お兄さんは何才になったのでしょうか?

※記法については『算数の問題文の記法のまとめ【随時更新】 - 算数の問題文の記法を考える』を読んでください。


【1997年度ジュニア算数オリンピックトライアル問題1問目】
ぼくのお兄さんは、西暦ABCD年の生れです。
1997年の今年、ぼくのお兄さんの年令は、A+B+C+Dになりました。ぼくのお兄さんは何才になったのでしょうか。


【記法化】

Aは0から9の整数である;
Bは0から9の整数である;
Cは0から9の整数である;
Dは0から9の整数である;
birth_year == 1000*A + 100*B + 10*C + D;
1997 - birth_year == age;
age == A + B + C + D;

実行;

print(age);


【工夫】

Aは0から9の整数である;
Bは0から9の整数である;
Cは0から9の整数である;
Dは0から9の整数である;
birth_year == 1000*A + 100*B + 10*C + D;
1997 - birth_year == age;
age == A + B + C + D;

A.最小 + B.最小 + C.最小 + D.最小 <= age <= A.最大 + B.最大 + C.最大 + D.最大;

age→birth_yearの順番で実行;

print(age);

どうだろう。「A.最小 + B.最小 + C.最小 + D.最小 <= age <= A.最大 + B.最大 + C.最大 + D.最大;」は、内部ですでに実行されているべきな気もする。10の4乗通りageが用意される所を、これならば37通りにまで削減できる。

また、実行に際しても、A、B、C、Dの順番で基準にしていったら10の4乗通り実行される所を、これならば37通りに削減できるのではないか。しかし例えば「age==1」と仮定した実行時に、定数を優先的に処理して「1000*A + 100*B + 10*C + D == 1997 - 1;」と実行される所までは良いとして、「A == 1; B == 9; C == 9; D == 6;」と自動的に仮定される所まで行くだろうか。人間からすれば「1996」は「1000*1 + 100*9 + 10*9 + 6」であり、ABCDが0から9である以上は、例えば「10*B」が1の位や100の位に入り込むことはないと分かるのだが。

また、そもそも「age→birth_yearの順番で実行;」の段階で、「A.最小 + B.最小 + C.最小 + D.最小 <= age <= A.最大 + B.最大 + C.最大 + D.最大;」という制約を基準に処理される必要があり、「age == A + B + C + D;」という制約が入り込んではいけない。これも問題だ。

解答を見る限りでは、これらの工夫により計算量を削減していた。