知恵袋で見つけた判断推理の幼稚園児の並び順の問題をPythonで解いてみました。(^_^;
東工大附属幼稚園の園児8 人が次の1~14 の条件を全て満たすように横一列に並んでこちらを向いています。
なお、下記文中のアルファベット大文字(A,B,C など)は、個人名を表し、同じ名前の園児はいないものとします。
条件以下、長いので省略(知恵袋を参照してください。)
難しいのは、たとえば、「A から見て左」(条件5)というのは、「横一列に並んでこちらを向いています」というとこで、「列に向かって」(条件8)見ると逆の右になります。これに気付くのに時間がかかてしまいました。(^_^;
ベストアンサーでは、園児から見て左右をとっていますが、プログラムでは、「列に向かって」見て左右をとりました。したがって、結果がベストアンサーとは逆になっています。(^_^;
それから、帽子とリボンの設定ですが、全員帽子をかぶっていて、3人だけ、リボン付きということにしました。(^_^;
また、リボンは、(橙、赤、桃)と全部わかっていますが、帽子の色は、黄色しか分かっていません。それで、条件3は、黄色だけチェックしてみましたが、コメントアウトしても結果が変わらないので省略しました。(^_^;
問(4)の条件を加えると、確定するようなので、プログラムに加えてみました。(^_^;
問題に出てくる要素、プログラムで用いた略号等の概要は次の通りです。
場所 PLACE 12345678 12345678 名前 NAME ABCDEFGH ABCDEFGH 性別 SEX 男男男男女女女女 mmmmffff 服の色 WEAR 黄黄緑緑桃白橙水 YYGGPWOC 帽子色 HAT 橙赤桃黄無無無無 ORPYxxxx リボン RIBBON 有有有無無無無無 rrrhhhhh 鞄の色 BAG 白赤黒黄緑水無無 WRBYGCxx 時計 WATCH 有有有有無無無無 ooooxxxx
● KinderGarten1.py
# coding: UTF-8 # KinderGarten1.py import itertools from time import time # 条件チェック: a[]の要素xからm個右側にb[]の要素yがあるか調べる def chkCond(m, a, x, b, y): n = a.index(x) if n==ValueError: return False if not 0<=m+n< len(a): return False return b[m+n]==y # 同じものを含むb[]の要素yに対応するa[]の要素をすべて求める def getXsOf(a, b, y): r = [] for n in range(len(a)): if b[n]==y: r.append(a[n]) return r def toStr(li): return '%s'%''.join(li) def main(): tm = time() # Timer Start # 要素を昇順にソートしたもの PLACE = "12345678" # 場所(列に向かって左右の並び順、園児から見て逆) NAME = "ABCDEFGH" # 園児の名前 SEX = "ffffmmmm" # 性別 (女女女女男男男男) WEAR = "CGGOPWYY" # 服の色 (水緑緑橙桃白黄黄) HAT = "OPRYxxxx" # 帽子の色 (橙桃赤黄無無無無) 無:分からない RIBBON = "hhhhhrrr" # リボン有無(無無無無無有有有) BAG = "BCGRWYxx" # 鞄の色 (黒水緑赤白黄無無) WATCH = "ooooxxxx" # 時計の有無(有有有有無無無無) place = tuple(PLACE) # 固定 Sexes = [] for sex in set(itertools.permutations(SEX)): s = toStr(sex) if 'mm' in s or 'ff' in s: continue # 条件01 if not s[-1]=='f': continue # 条件04,08 Sexes.append(sex) ## print(Sexes); exit() sex = Sexes[0] # 1通りしかないので Watches = [] for watch in set(itertools.permutations(WATCH)): s = toStr(watch) if 'oo' in s: continue # 条件10 Watches.append(watch) ## print(Watches); exit() Names = tuple(itertools.permutations(NAME)) Wears = tuple(set(itertools.permutations((WEAR)))) Hats = tuple(set(itertools.permutations((HAT)))) Ribbons = tuple(set(itertools.permutations((RIBBON)))) Bags = tuple(set(itertools.permutations((BAG)))) ## print(len(Sexes)) ## print(len(Watches)) ## print(len(Names)) ## print(len(Wears)) ## print(len(Hats)) ## print(len(Ribbons)) ## print(len(Bags)) cnt = 0 for watch in Watches: # watch loop for name in Names: # name loop if not chkCond( 0,name,'A',sex, 'm'): continue # 条件05 if not chkCond( 0,name,'E',sex, 'f'): continue # 条件06 if not chkCond(-2,name,'G',name, 'E'): continue # 条件06 if not chkCond( 0,name,'H',sex, 'f'): continue # 条件09 if not chkCond(-1,name,'B',watch,'o'): continue # 条件11 if not chkCond( 1,name,'B',watch,'o'): continue # 条件11 if not chkCond( 0,name,'A',watch,'o'): continue # 問(4)の条件 for ribbon in Ribbons: # ribbon loop if not chkCond( 0,name, 'F',ribbon,'r'): continue # 条件07 if not chkCond( 1,name, 'F',ribbon,'h'): continue # 条件07 if not chkCond( 0,place,'8',ribbon,'r'): continue # 条件08 if not chkCond(-1,name, 'B',ribbon,'r'): continue # 条件11 if not chkCond( 1,name, 'B',ribbon,'r'): continue # 条件11 if not chkCond(-1,name, 'C',ribbon,'r'): continue # 条件14 if not chkCond( 1,name, 'C',ribbon,'r'): continue # 条件14 for hat in Hats: # hat loop if not chkCond( 0,name, 'F',hat, 'O'): continue # 条件07 if not chkCond( 1,name, 'F',hat, 'Y'): continue # 条件07 if not chkCond( 0,place,'8',hat, 'R'): continue # 条件08 if not chkCond(-1,name, 'C',hat, 'O'): continue # 条件14 if not chkCond( 1,name, 'C',hat, 'P'): continue # 条件14 for bag in Bags: # bag loop if not chkCond( 3,name, 'A',bag,'W'): continue # 条件05 if not chkCond( 0,place,'1',bag,'R'): continue # 条件08 if not chkCond( 0,place,'8',bag,'G'): continue # 条件08 if not chkCond( 0,name, 'H',bag,'C'): continue # 条件09 if chkCond(-1,name, 'H',bag,'C'): continue # 条件09 if not chkCond( 1,name, 'H',bag,'x'): continue # 条件09 if not chkCond( 0,name, 'B',bag,'Y'): continue # 条件11 s = toStr(getXsOf(bag,watch,'o')) if 'x' in s: continue # 条件10 for wear in Wears: # wear loop s = toStr(wear) if 'yy' in s or 'gg' in s: continue # 条件01 ## n = hat.index('Y') ## if sex[n]=='m' and wear[n]=='Y': continue # 条件03 if not chkCond( 3,name,'A',wear,'Y'): continue # 条件05 if not chkCond( 0,name,'E',wear,'P'): continue # 条件06 if not chkCond(-1,name,'F',wear,'W'): continue # 条件07 if not chkCond( 0,name,'H',wear,'O'): continue # 条件09 if not chkCond(-1,name,'H',wear,'C'): continue # 条件09 if not chkCond( 1,name,'H',wear,'W'): continue # 条件09 if not chkCond( 0,name,'C',wear,'G'): continue # 条件14 if not chkCond( 3,name,'C',wear,'G'): continue # 条件14 s = toStr(getXsOf(wear,sex,'f')) if 'yy' in s or 'gg' in s: continue # 条件02 s = toStr(getXsOf(wear,sex,'m')) if 'yy' in s or 'gg' in s: continue # 条件02 pass # チェックを潜り抜けたものだけを表示 cnt+=1 print('[%d]'%cnt) print('#:'+toStr(place )) print('N:'+toStr(name )) print('S:'+toStr(sex )) print('W:'+toStr(wear )) print('H:'+toStr(hat )) print('R:'+toStr(ribbon)) print('B:'+toStr(bag )) print('W:'+toStr(watch )) print('') P = set(getXsOf(name,sex,'f')) Q = set(getXsOf(name,ribbon,'h')) print('(1) %s'%toStr(P&Q)) print('(2) %s'%name[bag.index('B')]) print('(3) %s'%wear[name.index('D')-1]) P = set(getXsOf(name,watch,'o')) n = name.index('B') Q = {'A',name[n-1],name[n+1]} print('(4) %s'%toStr(P-Q)) ## print(cnt) print("Runtime : %.3f [sec]"%(time()-tm)) # Timer Stop & Disp if __name__ == '__main__': main()
●実行結果
[1] #:12345678 N:AHDFCEBG S:mfmfmfmf W:COWYGPYG H:xxxOYPxR R:hhhrhrhr B:RCxWxBYG W:oxxoxoxo (1) H (2) E (3) O (4) F Runtime : 0.953 [sec]
※参考URL
●Zebra PuzzleをPythonで解いてみた。 - rscのブログ
●【Python入門】すぐわかる!set型(集合型)の基本まとめ | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト