質問: 11 print(solve(integer_list, target_sum)) # => True ``` のようになったのですが、 この ``` if (solve(integer_list, target_sum, i + 1, sum)): return True if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])): return True ``` の中のif文の条件が何をしているのかわかりません。 ``` if (solve(integer_list, target_sum, i + 1, sum)): ``` ``` if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])): ``` は何の機能なのでしょうか?
回答: 再帰処理ですね。 `solve`の引数は、次のように解釈するといいかと思います。 * `integer_list` 文字通り、整数のリスト。途中変更されることはない。([1,3,5,12,7]) * `target_sum` 文字通り、対象となる和。途中変更されることはない。(11) * `i` どこまでリストを見たか記憶している変数。 * `sum` これまでの和。 さらに、それぞれのif文は、次を意味します。 * `if i = len(integer_list):` **終了条件** リストの全てをチェックした場合、現段階の合計がtarget_sumと等しければTrueを返す。 異なる場合はFalseを返す。 * `if (solve(integer_list, target_sum, i + 1, sum)):` 今着目している数値(integer_list[i])を**足さず**に、次の数値に着目する。 * `if (solve(integer_list, target_sum, i + 1, sum + integer_list[i])):` 今着目している数値(integer_list[i])を**足して**、次の数値に着目する。 これらを把握したうえで、プログラムの処理を追ってみましょう。 `solve([1,3,5,12,7], 11, 0, 0)`が呼ばれると、次の二パターンに分割して問題を解決します。 1. 0番目の数値をsumに足す場合 次のようにsolveを呼び出し、判断を次のsolveに委託します。`solve([1,3,5,12,7], 11, 1, 1)` 2. 0番目の数値をsumに足さない場合 次のようにsolveを呼び出し、判断を次のsolveに委託します。`solve([1,3,5,12,7], 11, 1, 0)` ... どんどん二分割されていきます ... これをある程度続けていくと、いつかリストの最後まで見ることになります。 その時の条件が、`i == len(integer_list)`です。 例えば`solve([1,3,5,12,7], 11, 5, 11)`が呼ばれると、終了条件に達します。 リスト長がこの場合5ですから、2の5乗で32パターンに分割されますが、 それぞれが必ず終了条件に達し、結論がTrue/Falseで返されます。 私も初めて再帰処理を見たとき、狐に化かされたような気がしました。 面倒でも、ひとつひとつ紙に書いてみると、感覚がつかめるかもしれません。