計算能力テスト
フランスのテレビ番組の「Des chiffres et des lettres(数字と文字)」およびその英国版である「Countdown(カウントダウン)」は参加者の計算能力をテストする.このゲームの簡単なものを作り,新関数のGroupingsで問題を解く.
計算を行うために使用する算術演算を指定する.
In[1]:=

ops = {Plus, Subtract, Times, Divide};
指定された数の集合からランダムに選択した4つの数のリストを生成する.
In[2]:=

numbers = RandomChoice[{1, 2, 3, 5, 7, 10}, 4]
Out[2]=

これらの数の演算から導く結果もランダムに生成する.
In[3]:=

total = RandomInteger[100]
Out[3]=

各数を1回ずつ使う可能なすべての方法を構築する.算術操作の中には順序が重要なものもあるので注意のこと.
In[4]:=

orderings = Flatten[Permutations /@ Subsets[numbers, {4}], 1]
Out[4]=

各順序と,最初に指定した二項演算の可能なすべての組合せを生成する.
In[5]:=

candidates = Groupings[orderings, ops -> 2, HoldForm];
候補の中には0の割り算のためにComplexInfinityメッセージが出るものもある.メッセージはQuietで消去することができる.
In[6]:=

results = Quiet@ReleaseHold[candidates];
要求された結果を出す組合せの数は次の通りである.
In[7]:=

combinations = Thread[Equal[candidates, results]];
Count[Thread[Equal[candidates, results]], _ == total]
Out[7]=

以下は可能な組合せの一つである.
In[8]:=

FirstCase[combinations, _ == total]
Out[8]=

場合によってはぴったり合う結果が得られないものもある.
In[9]:=

total2 = 76;
Count[combinations, _ == total2]
Out[9]=

そのような場合でも,Nearestを使って結果の中から最も近いものを探すことはできる.
In[10]:=

total2 = 76;
Count[combinations, _ == total2];
DeleteCases[results, ComplexInfinity];
DeleteDuplicates@Nearest[%, total2]
Out[10]=
