2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Project Euler 28 非効率的回答案 「螺旋状に並んだ数」を作成する

Last updated at Posted at 2015-03-02

問題

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の螺旋を同じ方法で生成したとき, 対角線上の数字の和はいくつか?

回答

久しぶりに燃えた問題。
n2 + an + b
的な公式に当てはめた回答もできるけど、ここは効率悪く「螺旋状に並んだ数」を作成してみることとした。

螺旋状に並んだ数は、次のルールで作られる。
・前回が上方向への移動であった場合‥右があいていれば右、右があいていなければ上
・前回が下方向への移動であった場合‥左があいていれば左、左があいていなければ下
・前回が右方向への移動であった場合‥下があいていれば下、下があいていなければ右
・前回が左方向への移動であった場合‥上があいていれば上、上があいていなければ左

あとは、このルールをコードに落とし込めばらせん状に並んだ数を再現することが出来る。
度の処理を関数化するなどが残といったところだろうか。

UPPER = 'upper'
UNDER = 'under'
RIGHT = 'right'
LEFT  = 'left'

def nextupper(domain,i,j):
  return (UPPER,i-1,j)
  
def nextunder(domain,i,j):
  return (UNDER,i+1,j)

def nextright(domain,i,j):
  return (RIGHT,i,j+1)
  
def nextleft(domain,i,j):
  return (LEFT,i,j-1)
  
def nowupper(domain,i,j):
  if domain[i][j+1]:
    return nextupper(domain,i,j)
  else:
    return nextright(domain,i,j)

def nowunder(domain,i,j):
  if domain[i][j-1]:
    return nextunder(domain,i,j)
  else:
    return nextleft(domain,i,j)

def nowright(domain,i,j):
  if domain[i+1][j]:
    return nextright(domain,i,j)
  else:
    return nextunder(domain,i,j)

def nowleft(domain,i,j):
  if domain[i-1][j]:
    return nextleft(domain,i,j)
  else:
    return nextupper(domain,i,j)

def next(domain,drct, i, j):
  if drct == UPPER:
    return nowupper(domain,i,j)
  elif drct == UNDER:
    return nowunder(domain,i,j)
  elif drct == RIGHT:
    return nowright(domain,i,j)
  else:
    return nowleft(domain,i,j)
  
def cof():
  #MAX = 5
  MAX = 1001
  START = MAX//2
  seq = range(MAX)
  
  domain = [[0 for i in seq] for j in seq]
  v = 1
  (drct, i, j) = (UPPER,START,START)
  while i < MAX and j < MAX:
    domain[i][j] = v
    (drct, i, j) = next(domain, drct, i, j)
    v += 1
    
  #for i in seq: print domain[i]
  
  ans = 0
  for m in seq:
    ans += domain[m][m]
  for m in seq:
    ans += domain[m][MAX-m-1]
  ans -= domain[START][START]
  print ans
  
cof()
2
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?