6

数値を指定すると、関数が 1 からその数値 (2 次元配列) までのスパイラルを返す関数を作成したいと考えています。たとえば、関数に 25 という数値を指定すると、次のような値が返さ
ここに画像の説明を入力
れます。さまざまな方法を試しましたが、何もうまくいきませんでした。私はそれを理解することができません。
私が自分自身を適切に説明したことを願っています。

4

4 に答える 4

3

問題にはいくつかのステップがあります。まず、グリッドを設定します。グリッドのサイズは、次に大きい完全な正方形に等しくする必要があります。たとえば、23 と入力すると 5 × 5 (25) グリッドが必要になり、31 と入力すると 6 × 6 グリッド (36) が必要になります。次に、数列の次の値を「現在の位置」(つまり、中心) に格納します。各ステップで、方位を確認し、「現在の位置」を、東に偏って中心に最も近い、以前に入力されていない場所に移動します (最初のステップに対処するため、違いはありません)。北、南、東、西)。イテレータが終了するまで続行します。


編集:この質問は本当に楽しかったので、素敵な解決策を書きに行きました。私が Python を書いてから少し時間が経っているので、これは最も洗練されたものではないかもしれませんが、それでもなお.

from functools import partial
from math import ceil, sqrt

def gen_grid(n):
  grid_size = int(ceil(sqrt(n)))
  return [[None for _ in range(grid_size)] for _ in range(grid_size)]

def valid_coord(grid, coord):
  try:
    return grid[coord[0]][coord[1]] is None
  except:
    return False

def origin(size):
  adjustment = 1 if size % 2 == 0 else 0
  return (size / 2 - adjustment), (size / 2 - adjustment)

north = lambda y, x: (y - 1, x)
south = lambda y, x: (y + 1, x)
east = lambda y, x: (y, x + 1)
west = lambda y, x: (y, x - 1)

directions = lambda y, x: [east(y, x), south(y, x), west(y, x), north(y, x)]
distance = lambda c, nxt: sqrt((c[0] - nxt[0]) ** 2 + (c[1] - nxt[1]) ** 2)

def walk_grid(nums):
  grid = gen_grid(len(nums))
  center = origin(len(grid[0]))
  current_position = center
  center_distance = partial(distance, center)

  for n in nums:
    y, x = current_position
    grid[y][x] = n
    unseen_points = [c for c in directions(y, x) if valid_coord(grid, c)]
    if n != nums[-1]:
      current_position = sorted(unseen_points, key=center_distance)[0]

  return grid

def print_grid(highest):
  result = walk_grid(range(1, highest + 1))
  for row in result:
    for col in row:
      print "{:>4}".format(col if col is not None else ''),  
    print "\n"

出力例:

In [2]: grid.print_grid(25)
  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 
于 2014-05-17T01:36:55.100 に答える
0

したがって、配列のサイズと「1」の位置をすでに何らかの方法で決定できると思います。ここで、方向とカウンターを変更できる関数が必要です。

def get_new_direction(direction):
  switch direction:
     case E: return S
     case S: return W
     case W: return N
     case N: return E

i,j = initial_coordinates_of_the_one
direction = right
steps = 1
next_number = 1

while not done:
  place(next_number, i, j)
  i,j = get_coordinates_after_move(direction, steps)
  direction = get_new_direction(direction)
  next_number++
  if iteration is even:
    steps++

これは単なるスケッチです。まだ不足しているもの (ただし、簡単に把握できます):

  • 関数の実装方法
  • 一方向に沿って複数の数字を設定する方法
于 2014-05-17T01:40:23.140 に答える