へたっぴpythonista

ド素人pythonistaとして、日々の学習成果や気づいたことについて書きます。

ProjectEuler28をpythonで解く

 寝る前に解いたら1時間近くかかってしまいました(笑)

 

Problem28

Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows:

 21 22 23 24 25
 20  7    8    9 10 
 19  6    1    2 11
 18  5    4    3 12
 17 16 15 14 13

It can be verified that the sum of the numbers on the diagonals is 101.

What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?

 

1を中心にして、時計回りにぐるぐると数字を並べた時に、対角線上の数字(青い数字)の和はいくつか?という問題です。四角形の右上の数が1、9、25、・・・(2n+1)^2となっている点と、対角線上の数字同士の間隔が2、4、6、・・・2nと4つ毎に増加する点に注目して解いてみました。

解答

#-----------------------------------------------------------------------

def diagonals(width):
       ans=1
       max_add=(width-1)
       current=1
       add=2
       while add<=max_add:
            if width%2==0:            #widthは奇数でなくてはならない。  
                 break
            for i in range(1,5):

                 ans += current+(add*i)
                 current =current+(add*4)
                 add +=2
       print(ans)

diagonals(1001)

#-----------------------------------------------------------------------

関数diagonalsは変数を四角形の幅(一行に含まれる数字の数)とします。

3行目のmax_addは先述の数字同士の間隔(2n)と四角形の幅(2n+1)の関係から出した、間隔の最高値です。

6行目からのwhileループでは、間隔が4回置きに増加することを利用して、ansに値を足します。その後currentを更新し、間隔を2つ広げるコードを実行させます。

以上を実行すれば、答え669171001を得られます。