※記法については『算数の問題文の記法のまとめ【随時更新】 - 算数の問題文の記法を考える』を読んでください。
【1999年度ジュニア算数オリンピックトライアル問題10問目】
下のように9つの重さのちがうダンボール箱がA、B、Cの3つの家にあります。これをAの家には15kg、Bの家には30kg、Cの家には45kgになるようにトラックを使って移したいと思います。ただしトラックは一度に2こまでのダンボール箱しか運べませんし、たった1まわりしかできません。Aの家からスタートするとして、○の中に移すダンボール箱の重さを書き入れなさい。
【記法化】
house_A := [8, 9, 13]; house_B := [3, 5, 7, 15]; house_C := [12, 18]; 実行; list_A := 被りなしで2個まで移動 := house_A.every; 実行; 記録1; house_B := 被りなしで全て移動 := list_A.every; 実行; list_B := 被りなしで2個まで移動 := house_B.every; 実行; 記録2; house_C := 被りなしで全て移動 := list_B.every; 実行; list_C := 被りなしで2個まで移動 := house_C.every; 実行; 記録3; house_A := 被りなしで全て移動 := list_C.every; 実行; sum(house_A) == 15; sum(house_B) == 30; sum(house_C) == 45; 記録1 { print(listA); } 記録2 { print(listB); } 記録3 { print(listC); }
「house_B.every := 被りなしで2個まで移動(listAとして保存) := house_A.every;」みたいに書ければ随分楽になるんだが、そのような機能を追加するかは保留だ。
【工夫】
人間であれば、この条件下で最終的なAの15kgになりうるのは8㎏と7㎏の対だけだと考えて、まず9㎏と13㎏を移動して、次に7㎏と合計30㎏に合致するように15㎏を移動して、最後に7㎏だけ移動させる。この工夫をどう記述すれば良いのかが分からない。
house_Aの1個以上と残りのhouse_Bとhouse_Cを合わせたもので15kgを作ろうとすると8㎏と7㎏の組み合わせになる。だから最初の組は9㎏と13㎏が入るし、残りの組の片方にはそれぞれ7㎏が入る、残りは手なりではじき出す。という感じなんだろうか。
制約が大きいのは15㎏のhouse_Aなのは間違いない。だからそこに着目して優先的に処理して、制約をはじき出してしまおうというアプローチだ。こういう問題がいくつも積み重なってきたら、それらの問題にも共通するような書き方でいつか工夫を正式に記述したい。