受験算数の「約数の個数」の問題をPythonで解いてみた。(2)

 受験算数の「約数の個数」の問題Pythonで解いてみました。(^_^;
 1993年度の灘中の問題らしいです。(^_^;

 表には1から50までの整数をかき,裏には何もかいていないカードがつぎのように並べられている。
  [1][2][3][4][5][6][7][8]・・・・・・[47][48][49][50]
 まず,左から2番目ごとにカードを裏返し,さらに左 から3番目ごとにカードを裏返すとつぎのようになる。
  [1]□□□[5][6][7]□‥‥‥[47][48][49]□
[6]や[48]などのカードは2回裏返されたので表となっている。 同じように,さらに4番目ごと,5番目ごと,・・・・・・,25 番目ごとに裏返してこの操作を終わる。つぎの問いに答えよ。
(1)4番目ごとにカードを裏返し終わったときには,表向きのカードは何枚になっているか。
(2)すべての操作が終わったとき,つぎの問いに答えよ。
(ア) [16]のカードは何回裏返されたか。
(イ) (ア)と同じ回数だけ裏返されたカードにかいてある 整数で16以外のものをすべてかけ。

 プログラムでは、カードを裏返した回数のリストlCardsから、カードの表裏の状態を問題文中のように、それぞれ、[数字]と□で表して並べた文字列を返す関数toStrCards(lCards)を作りました。
 ちなみに、(1)で、「50-sCards.count(u'□')」は、「sCards.count('[')」や「sCards.count(']')」でもいいです。(^_^;

● NumberOfDivisors2.py

# coding: UTF-8
# NumberOfDivisors2.py

from time import time

# リストlCardsの要素が偶数なら表、奇数なら裏になる
# 表なら[1]〜[50]、裏なら□を並べた文字列を返す
def toStrCards(lCards):
    s = ''
    for i in range(1,len(lCards)):
        if lCards[i]%2==0: s+='['+str(i)+']'
        else:              s+=u'□'
    return s

def main():
    tm = time()  # Timer Start
    N = 50
    # カードをcard[1]〜[N]まで用意。card[0]はダミー
    card = [0]*(N+1)
##    print('%2d: %s'%(0,toStrCards(card)))
    for i in range(2,25+1):
        for j in range(1,N+1):
            if j%i==0: card[j]+=1
##        print('%2d: %s'%(i,toStrCards(card)))
        if i==4:
            sCards = toStrCards(card)
##    print(toStrCards(card))
    hit = []
    for i in range(1,N+1):
        if card[i]==card[16] and i!=16:
            hit.append(i)
##    print(sCards)
    print( '(1) %d'%(50-sCards.count(u'□')))
    print(u'(2)(ア) %d'%(card[16]))
    print(u'(2)(イ) %s'%(hit))
    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

(1) 29
(2)(ア) 4
(2)(イ) [28, 32, 44, 45, 50]
Runtime : 0.001 [sec]

※参考URL
今年の「2題!?」 | 前田昌宏の中学受験が楽しくなる算数塾
質問の箱と球の問題をPythonで解いてみた。 - rscの日記
受験算数の「約数の個数」の問題をPythonで解いてみた。