sasaharayuugo.net

プログラミングでジュニア算数オリンピック『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


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