知恵袋で見つけた判断推理の出勤簿の問題をPythonで解いてみた。(2) - rscの日記
# 同じものを含む順列 def perm(head, rest): if len(rest) == 0: return [head] else: res = [] # set(集合)型で重複を削除、ソート data = sorted(set(rest)) for i in data: # 配列の複製 restx = rest[:] # 指定データ削除 restx.remove(i) headx = head + [i] res += perm(headx, restx) return res # A 3日 # B 5日 # C 4日 # D 3日 # E 4日 # 3日出勤パターン作成 pattern3 = perm([], ['o', 'o', 'o', 'x', 'x', 'x', 'x']) # 4日出勤パターン作成 pattern4 = perm([], ['o', 'o', 'o', 'o', 'x', 'x', 'x']) # 5日出勤パターン作成 pattern5 = perm([], ['o', 'o', 'o', 'o', 'o', 'x', 'x']) ''' print(len(pattern3)) print(len(pattern4)) print(len(pattern5)) ''' # パターン絞り込み # Aは1日おきに働いた(2日連続で休んだことはない) a = [y for y in pattern3 if 'oxoxo' in ''.join(y)] # Bは条件なし b = pattern5 # Eは3日続けて休んだ e = [y for y in pattern4 if 'xxx' in ''.join(y)] # CとDは同じ日に働いたことはなかった # EとDは同じ日に働いたことはなかった # CとEは同じ日、DはCとEと違う日 ''' print(len(a)) print(len(b)) print(len(e)) ''' # 曜日ごとの出勤日数 days = [3, 4, 1, 3, 1, 4, 3] for xa in a: for xb in b: for xe in e: # CはEと同じ日 xc = xe # DはEと違う日 xd = ['x' if i == 'o' else 'o' for i in xe] for v in zip(days, xa, xb, xc, xd, xe): if v[0] != v[1:].count('o'): break else: print( ' 日月火水木金土') print('A', ' '.join(xa)) print('B', ' '.join(xb)) print('C', ' '.join(xc)) print('D', ' '.join(xd)) print('E', ' '.join(xe)) print('-' * 16)