HaHaHa! - 覆面算汎用ソルバ より、覆面算クイズを解くコードを Squeak の Smalltalk で。速度的にはまったく使い物にならないのですが、Haskell 版の汎用性(SEND + MORE = MONEY 専用ではない…)と、Shiro さんの Gauche 版 における文字列を介することにより得られる簡潔さ…の双方を意識してざっと書き下ろしてみました(肝心のソルバとしてのヒネリはまったくないです(^_^;))。
使い方
'SEND + MORE = MONEY' solve
'KYOTO + OSAKA = TOKYO' solve
定義
String >> solve | letters shouldntZeros | letters := self onlyLetters asSet asArray. shouldntZeros := self subStrings collect: [:str | str first] thenSelect: [:chr | chr isLetter]. ($0 to: $9) reversed combinations: letters size atATimeDo: [:comb | comb permutationsDo: [:digits | (shouldntZeros noneSatisfy: [:shoudntZero | (digits at: (letters indexOf: shoudntZero)) = $0]) ifTrue: [ | expression | expression := self copy. letters with: digits do: [:letter :digit | expression replaceAll: letter with: digit]. (Compiler evaluate: expression) ifTrue: [^ expression]]]]. ^ false
答えが出るのに 1.2GHz PenM なノートで 10 分弱かかります(^_^;)。当然ですが、'SEND + MORE = MONEY' onlyLetters asSet size の大きさに依存します。 そーとー待たされましたが、とりあえず 'APPLE + GRAPE = CHERRY' を探してきてくれるところまでは確認しました。