Project Euler 28
1から初めて右方向に進み時計回りに数字を増やしていき, 5×5の螺旋が以下のように生成される: 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 両対角線上の数字の合計は101であることが確かめられる. 1001×1001の螺旋を同じ方法で生成したとき, 対角線上の数字の合計はいくつだろうか?
Mathematica
A = Table[Table[0, {i, 1001}], {j, 1001}]; Pos = {501, 501}; A = ReplacePart[A, Pos -> 1]; Dir = "Right"; Num = 1; For[i = 1, i <= 1001^2, {}, Switch[Dir, "Right", For[j = 1, j <= Num, j++, A = ReplacePart[A, Pos + {0, j} -> i + j]]; Pos += {0, Num}; Dir = "Down"; i += Num, "Down", For[j = 1, j <= Num, j++, A = ReplacePart[A, Pos + {j, 0} -> i + j]]; Pos += {Num, 0}; Dir = "Left"; i += Num; Num++, "Left", For[j = 1, j <= Num, j++, A = ReplacePart[A, Pos - {0, j} -> i + j]]; Pos -= {0, Num}; Dir = "Up"; i += Num, "Up", For[j = 1, j <= Num, j++, A = ReplacePart[A, Pos - {j, 0} -> i + j]]; Pos -= {Num, 0}; Dir = "Right"; i += Num; Num++]; ] Total[ Table[A[[i, i]], {i, Length[A]}] ] + Total[ Table[A[[i, Length[A] - i + 1]], {i, Length[A]}] ] - 1
自分で書いておいてなんですが、参考にしてもいけないですし、実行もおすすめしません。
1000×1000の2次元配列を宣言している時点で敗北です・・・なにか数列を計算で出す必要があったように思うのですが、
力技で、上の説明にあるようならせんを実際に作って計算してしまいました・・・
直したいなーこれ・・・
C/C++
#include <iostream> using namespace std; int main(){ const int SIZE = 1001; int tmp = 1; int sum = 1; // iは中心を1として、どのぐらい離れているかどうか。 // i=2は 3, 5, 7, 9 が四隅にある枠。 // i=3は 13,17,21,25が四隅にある枠。 // 四隅のうちの右下にあたる数を tmp に入れる。 for(int i=1 ; i<(int)(SIZE/2)+1 ; i++){ tmp += 8*(i-1) + 2; for(int j=0 ; j<4 ; j++){ sum += tmp + 2*i*j; } cout << sum << endl; } int end; cin >> end; return 0; }
Mathematicaのひどいやつよりは改善できたと思います。1,3,13・・・がどういう数列になるかを考えれば楽。