納得!朝三暮四

色々書きます

算数パズルをプログラムに解かせたい

次の□に+か-を入れて等号が成り立つようにしなさい。
0□1□2□3=4

こういうパズルを業務で作ってるわけなんですが、作為を考えつつ別解がでないようにしててもどこかで見落としをするので、プログラムに確認させたい、という気持ちがある。

入力は整数列(a1,a2, ... an)と右辺の整数値で、演算子加減乗除と「結合」(たとえば1□2が12、12□3が123となる、左が0の場合はなしにしたいけどプログラムで除外するほどのものではない)があるとする。

実際の問題では使える演算子は上述の問題のように限っているのだが、大した出力にもならないので、そこらへんは目でやることにする。色々やれば探索の枝刈りとかできそうな気はしたが、面倒くさいしどうせn<=7程度なので、全探索しても死なないので全探索することにした。こういう問題ならCとかで書いても良さそうな気はしたんだけども環境構築がだるかったので、他の業務にも使ってるHSPでやることにした。

nが入力を受け取るまで不定な以上、各□の多重ループで全探索は無理っぽいのは何となく分かる。それで最初は再帰関数を使ってやろうとしたが、配列を変数にわたすとかうんぬん考えてたら死にそうだったのでやめた。数列と答えを受け取って、実現できるかどうかを返すみたいな。あと、結合→乗除→加減の順で計算しなければいけないあたりでも死を招きそうだ。

全探索するので、とりあえず全通りの数を出せば良い。5^(n-1)である。あとはこの数を5進数表示にして演算子列に変換する。あとは結合→乗除→加減の順で順々に計算していく。ここらへんの作業用数列/演算子列と元の数列/演算子列の扱いだとか、どの演算子を見ているかあたりの扱いを適当にやって壮大に死んだが、なんとかした。コピペまみれの糞コードで250行ぐらいかかったけど間違ったことはしてなそうだし、よしとする。