年賀状にするための2011をおりこんだパズルの問題を考えているところ。
数式的なやつを考えていて試しにプログラムを走らそうと思って、いったんC#で書き始めたが・・・。
思い直してprologでやってみた。なんかちろっとやるならprologが便利なことはある。「ちろっと」はどの程度かはご都合主義笑。
ソースはこれ。
(2011-01-17:割り算のコメントを外した場合はバグありなのが判明、注意!!!)
wake(A,B,C) :- A > 10, B is A div 10, C is A mod 10.
wake(A,B,C) :- A > 100, B is A div 100, C is A mod 100.
wake(A,B,C) :- A > 1000, B is A div 1000, C is A mod 1000.
wake(A,B,C) :- A > 10000, B is A div 10000, C is A mod 10000.
wake(A,B,C) :- A > 100000, B is A div 100000, C is A mod 100000.
wake(A,B,C) :- A > 1000000, B is A div 1000000, C is A mod 1000000.
wake(A,B,C) :- A > 10000000, B is A div 10000000, C is A mod 10000000.
wake(A,B,C) :- A > 100000000, B is A div 100000000, C is A mod 100000000.
wake(A,B,C) :- A > 1000000000, B is A div 1000000000, C is A mod 1000000000.
wake(A,B,C) :- A > 10000000000, B is A div 10000000000, C is A mod 10000000000.
wake(A,B,C) :- A > 100000000000, B is A div 100000000000, C is A mod 100000000000.
atai(N,N,N).
% atai(N,V,V) :- V is -(N).
atai(N,V,F):- wake(N,N1,N2),a
% atai(N,V,F):- wake(N,N1,N2),a
atai(N,V,F):- wake(N,N1,N2),a
% atai(N,V,F):- wake(N,N1,N2),a
%はコメントアウトでマイナス、引き算、割り算は候補からはずしてある。
走らせると
1 ?- atai(12345678,2
X = 1+ (2+3*4* (5+6))* (7+8) ;
X = 1+ (2+3* (4* (5+6)))* (7+8) ;
false.
えーっと問題としては、
1 2 3 4 5 6 7 8
と書いてある紙に+(足し算)、×(掛け算)、カッコを書き足して2011になる式にしろ。
ということ。唯一解。
問題としては成立しているけど、おもしろみには欠けるなぁ。
問題作りは続行中。
ソースに関してコメント。
・wakeについては再帰的に書けるよねぇ。
・ataiってシンボルはあってなくねぇ?って話。
だが、いいわけすると、atai(A,B,C)としてAに元の数字を入れてやると記号加えて計算した結果のいろんな値がBに出る。当初C引数はなかったので。
思い出したのでコメント。プログラムとしては一貫して10進数なところが特長。文字列処理がでてこない。プロログでなくても使える。