以前、Javaで解いた判断推理の出勤簿の問題をPythonで解いてみました。と、いうより翻訳してみました。(^_^;
どうも、同じものを含む順列set(itertools.permutations())を使うと遅いようなので、前回と同様、itertools.product()でループを回してみました。(^_^;
それから、結果の表示をJava版に合わせて全角にしてみました。(^_^;
ちなみに、ループをeから逆に始めると、倍速近く速くなります。o(^-^)o
● AttendanceBook2.py
# coding: UTF-8 # AttendanceBook2.py import itertools from time import time # 曜日ごとの出勤者数のチェック def chechAttendance(la, ls): for i in range(len(ls)): t = 0 for j in range(len(la)): t+=1 if la[j][i]=='o' else 0 if t!=ls[i]: return False return True # aの出勤表laからc曜日に働いたか調べる # 'UMTWRFS': '日月火水木金土' def hasWorked(la, c): WD = 'UMTWRFS' return la[WD.index(c)]=='o' # 一緒に出勤した日数を調べる def numOfDaysTog(la,lb): c = 0 for i in range(len(la)): if la[i]=='o' and lb[i]=='o': c+=1 return c # 結果を表示 def PrintResult(lst): n = len(lst) NAME = u'ABCDE' print(u' 日月火水木金土') for i in range(n): s = NAME[i]+''.join(lst[i]) print(s.replace('o',u'○').replace('x',u'×')) print('') def main(): tm=time() # Timer Start S = [3,4,1,3,1,4,3] # 曜日ごとの働いた人数 T = [3,5,4,3,4] # 5人の働いた日数 ch = [True]*5 cnt = 0 for a in itertools.product('ox',repeat=7): sa = ''.join(a) # Aの出勤表1行を文字列で得る if sa.count('o')!=T[0]: continue if 'xx' in sa: continue # 条件ア for b in itertools.product('ox',repeat=7): sb = ''.join(b) # Bの出勤表1行を文字列で得る if sb.count('o')!=T[1]: continue for c in itertools.product('ox',repeat=7): sc = ''.join(c) # Cの出勤表1行を文字列で得る if sc.count('o')!=T[2]: continue for d in itertools.product('ox',repeat=7): sd = ''.join(d) # Dの出勤表1行を文字列で得る if sd.count('o')!=T[3]: continue if numOfDaysTog(c,d)!=0: continue # 条件イ for e in itertools.product('ox',repeat=7): se = ''.join(e) # Eの出勤表1行を文字列で得る if se.count('o')!=T[4]: continue if numOfDaysTog(d,e)!=0: continue # 条件ウ if 'xxx' not in se: continue # 条件エ li = [a,b,c,d,e] if not chechAttendance(li,S): continue # チェックを潜り抜けたものだけを表示 cnt+=1 print("[%d]"%cnt) PrintResult(li) # 選択肢のチェック ch[0] &= not hasWorked(c,'U') ch[1] &= not hasWorked(a,'M') ch[2] &= hasWorked(d,'T') ch[3] &= not hasWorked(b,'W') ch[4] &= hasWorked(e,'R') if cnt==0: ch = [False]*5 s = "" for c in ch: if c : s+=" %s"%(ch.index(c)+1) print(u"∴%s"%s) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
[1] 日月火水木金土 A×○×○×○× B○○×○×○○ C○○×××○○ D××○○○×× E○○×××○○ ∴ 3 Runtime : 0.357 [sec]
※参考URL
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1124852786
●UMTWRFS
●判断推理の出勤簿の問題をJavaで解いてみた。
●知恵袋で見つけた判断推理の出勤簿の問題をPythonで解いてみた。