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を得られます。