二次元配列をらせん状に移動する方法の一例を、二つのパターンで、以下に紹介します。
二次元配列の[0][0]の地点から、時計回りに通し番号を振っていく
H = 3 #行数
W = 3 #列数
#探索する二次元配列 myMap を -1 で初期化
myMap = [[-1] * W for h in range(H)]
#debug
for m in myMap:
print(m) #--> [-1, -1, -1]
# [-1, -1, -1]
# [-1, -1, -1]
num = H * W #マスの総数
h, w = 0, 0 #初期位置
dh, dw = 0, 1 #移動するために加算する変数。詳細は後述。
cnt = 0 #マスに書き込む数 および 探索数管理用
while cnt < num:
myMap[h][w] = cnt
cnt += 1
# 右端の列を超えた or 左端の列を超えた or 下端の行を超えた or 上端の行を超えた or すでに訪れたことのあるマスに到達した
if w + dw >= W or w + dw < 0 or h + dh >= H or h + dh < 0 or myMap[h+dh][w+dw] != -1:
#移動のために加算する値を変更する
#1)はじめは dh, dw = 0, 1 を加算して 右に移動
#2)次は dh, dw = 1, 0 で下に移動
#3)さらに dh, dw = 0, -1 で左に移動
#4)最後に dh, dw = -1, 0 で上にに移動
#次は dh, dw = 0, 1 で 1)に戻る
# 以上を表現するのが下の式
dh, dw = dw, -dh
h += dh
w += dw
for m in myMap:
print(m) #--> [0, 1, 2]
# [7, 8, 3]
# [6, 5, 4]
二次元配列の[0][0]の地点から時計回りに巡回し、対象とする配列の値を1次元配列に格納する
#らせん状に移動したい配列
matrix = [ [1, 2, 3],
[4, 5, 6],
[6, 8, 9] ]
H = len(matrix) #行の数
W = len(matrix[0]) #列の数
limit_counter = H*W #要素の数
mypath = [] #経路を格納する配列
while len(mypath) < limit_counter:
if matrix != []:
#1)最初の行はそのまま追加
mypath += matrix[0]
del matrix[0] #最初の行を消す
if len(mypath) >= limit_counter: #すべての要素が追加されていれば終了
break
#2)最終列は上から追加
for i in range(0,len(matrix)):
mypath.append(matrix[i][-1])
del matrix[i][-1] #追加された要素を消す
if len(mypath) >= limit_counter: #すべての要素が追加されていれば終了
break
#3)最終行は逆順に追加
mypath += matrix[-1][::-1]
del matrix[-1] #最終行を消す
if len(mypath) >= limit_counter: #すべての要素が追加されていれば終了
break
#4)最初の列も逆順に追加 ※最初の列の1番上は、ここでは追加せずに 1)に戻った時点で追加
for i in range(1,len(matrix)):
mypath.append(matrix[-i][0])
del matrix[-i][0] #追加された要素を消す
if len(mypath) >= limit_counter: #すべての要素が追加されていれば終了
break
else:
break
#print(mypath, matrix)
print(mypath)