ニート歴10年からの数学日記

2008年〜2009年の高一の冬休みから無職。最長で4ヶ月ほどの中断アリ。

プログラミングでジュニア算数オリンピック『1997年度トライアル問題1問目』

筆者:とりあえず毎日更新が目標です。そのためならば内容は二の次です。



問題文:
『ぼくのお兄さんは、西暦ABDC年の生れです。
1997年の今年、ぼくのお兄さんの年令は、A+B+C+Dになりました。
ぼくのお兄さんは何才になったのでしょうか。』



まず、数字をケタのリストに変換して、それぞれを足し合わせることができなければいけない。

def num2digit(num):
    divNum = 1
    digitList = []
    while num != 0:
        divNum *= 10
        mod = num % divNum
        num -= mod
        digitList.insert(0, mod*10//divNum)
    return digitList
digitList = num2digit(1997)
print(digitList)
sumDigitList = sum(digitList)
print(sumDigitList)
[1, 9, 9, 7]
26

 


これができるようになったので、まず簡単に、1997〜0まで総当りで、「1997年-ABCD年」と「A+B+C+D」が同じな年を探してみる。

for i in reversed(range(1998)):
    if 1997 - i == sum(num2digit(i)):
        print(i)
        print(sum(num2digit(i)))
1975
22

で1975年で、答えは「22才」、ということになる。



これでも良いのだけど、おそらくこれを解く小学生はこういう解き方はしない。もしかしたら1997年から一年ずつ計算していって1975年で見つけて当てずっぽうでこれで終わりかもしれないけども、少なくとも出題者が想定している理想の解き方では無いだろう。

おそらく想定される理想の小学生は、変化のルールに着目する。「1997年-ABCD年」と「A+B+C+D」のギャップがどういう風に縮まっていくかを理解しようとする。

gapList = []
for i in reversed(range(1998)):
    age1 = 1997 - i
    age2 = sum(num2digit(i))
    gapList.append(age1 - age2)

for year, gap in zip(reversed(range(1998)), gapList):
    print(year, gap)
1997 -26
1996 -24
1995 -22
1994 -20
1993 -18
1992 -16
1991 -14
1990 -12
1989 -19
1988 -17
1987 -15
1986 -13
1985 -11
1984 -9
1983 -7
1982 -5
1981 -3
1980 -1
1979 -8
1978 -6
1977 -4
1976 -2
1975 0
1974 2
1973 4
1972 6
1971 8
1970 10
1969 3
1968 5
1967 7
1966 9
1965 11
1964 13
1963 15
(以下略)
changedList = []
for i in range(len(gapList)):
    if i == 0:
        changedList.append(0)
        continue
    changedList.append(gapList[i] - gapList[i-1])

for year, gap, changed in zip(reversed(range(1998)), gapList, changedList):
    print(year, gap, changed)
1997 -26 0
1996 -24 2
1995 -22 2
1994 -20 2
1993 -18 2
1992 -16 2
1991 -14 2
1990 -12 2
1989 -19 -7
1988 -17 2
1987 -15 2
1986 -13 2
1985 -11 2
1984 -9 2
1983 -7 2
1982 -5 2
1981 -3 2
1980 -1 2
1979 -8 -7
1978 -6 2
1977 -4 2
1976 -2 2
1975 0 2
1974 2 2
1973 4 2
1972 6 2
(略)
1902 83 2
1901 85 2
1900 87 2
1899 71 -16
1898 73 2
1897 75 2
1896 77 2


疲れたので続きはまた明日。