実家に帰省した際にツクダオリジナルの算数塾と呼ばれる5角形のパズルがありました。
30分くらい挑戦して回答が出せず、回答を導出するプログラムを作成したので備忘録として残しておきます。(最初に言っておきますが、答えが出ればいいという考えのクソコードです。)
そもそもツクダオリジナルの算数塾とは
下記のように五角形の各面に数字と記号が書かれており、5面の数式をすべて成立させるパズルです。商品の箱には下記のような説明が記載されていました。
謎の5角形のドラムには各々1~5、+ー×÷がランダムに配列されています。各ドラムをスライドさせて5面の計算を全て政界にしてください。3125通りの組み合わせで正解はひとつです。※カラーは5色、色によって正解は異なります。
ツクダオリジナルの商品まとめによるとこちらの商品は1980年代に1000円程度で発売されていた商品みたいです。(この商品を調べている過程でツクダオリジナルの会社が別の会社になっていることを知りました。。。どうりで最近CM見ないと思いました。。。)
調べていても全然情報が無かったのですが、メルカリを見ていると白字以外にも赤字と黄色字のものがあるみたいです。残り2色が何色かは不明です。
回答を求めるコード
ここでは回答を求めるコードを紹介します。最初にも記載しましたが、コードは全パターン網羅するクソコードです。商品紹介には$5^5=3125$通りとしてますが、答えの部分もループさせているため、$5^6=15625$パターン試してます。
column1 = ["1","2","5","3","4"]#各面の値を記載
column2 = ["-","-","*","+","*"]
column3 = ["2","5","4","3","1"]
column4 = ["*","+","-","-","/"]
column5 = ["4","5","2","3","1"]
answer = ["4","2","3","1","5"]
ans_count = 0
def judge_add(i,j,k,l,m,n):#[0,1,2,3,4]となっているため5を超えた場合0に戻す処理
if i > 4:
return_i = i-5
else:
return_i = i
if j > 4:
return_j = j-5
else:
return_j = j
if k > 4:
return_k = k-5
else:
return_k = k
if l > 4:
return_l = l-5
else:
return_l = l
if m > 4:
return_m = m-5
else:
return_m = m
if n > 4:
return_n = n-5
else:
return_n = n
return return_i,return_j,return_k,return_l,return_m,return_n
def add_one(i,j,k,l,m,n):#他の面が妥当か検証するためにiなどの値に1追加する関数
i+=1
j+=1
k+=1
l+=1
m+=1
n+=1
return i,j,k,l,m,n
for i in range(5):
for j in range(5):
for k in range(5):
for l in range(5):
for m in range(5):
for n in range(5):
join_column1 = column1[i]+column2[j]+column3[k]+column4[l]+column5[m]
if int(eval(join_column1)) == int(answer[n]):#まず1列が正しいか判定し、正しければ他の列の評価する
add_i,add_j,add_k,add_l,add_m,add_n = i,j,k,l,m,n#一旦別の変数で現在のiなどの値を保持
for o in range(5):#他の5面の検証
add_i,add_j,add_k,add_l,add_m,add_n = add_one(add_i,add_j,add_k,add_l,add_m,add_n)
judge_i,judge_j,judge_k,judge_l,judge_m,judge_n = judge_add(add_i,add_j,add_k,add_l,add_m,add_n)
join_column = column1[judge_i]+column2[judge_j]+column3[judge_k]+column4[judge_l]+column5[judge_m]
if int(eval(join_column)) == int(answer[judge_n]):
ans_count += 1#検証した結果問題妥当と判断されたらカウンタをインクり
if ans_count >= 4:#4面が妥当と判断されたら回答を返答
print("YES")
print(join_column1+"="+answer[n])
ans_count = 0
else:
ans_count = 0
コードにコメントを記載しているため、特に追加で説明することはないですが今回eval関数を初めて使いました。簡単にいうとこの関数は文字列をpythonの式として評価し、結果をリターンしてくれるものです。
今回は+などの記号を文字列として使用している中で組み合わせを求めているため、このeval関数を使って数式に変換し結果を求めています。
eval関数の注意点として外部からの入力を実行する際にインジェクション攻撃などのリスクが高まるため、実践のコードで使う際は注意が必要となります。
(詳細はこちらの記事参照お願いします。)
前置きが長くなりましたが、こちらのコードの実行結果は下記のようになりました。
5個回答が出ていますが、本来1面だけ回答を出せばいいところを5面すべての回答を出しているからです。効率的に解を求めるのならコードを少し変えますが、今回はそんなに計算時間がかからない内容かつ時間制約もないため、このままでいきます。
YES
1*5-1=4
YES
2+4-4=2
YES
5*3/5=3
YES
3-1*2=1
YES
4-2+3=5
上記記載の通りにパズルを動かしたら式が成立することが確認できたので、白字のパズルについてはこれが解で問題なさそうです。
まとめ
今回はツクダオリジナルの算数塾の回答を導出するプログラムを作成し、パズルを解きました。
このパズルについて全然情報が無かったため、もし何か情報をお持ちの方がいたらコメント記載していただけると幸いです。(あとこのパズルを自力で解く場合のコツなどもあれば教えてほしいです。。。)
0 件のコメント:
コメントを投稿