【Paiza】「座標系での規則的な移動」解いてみた


問題

開始時点の x , y 座標と移動の歩数 N が与えられます。
以下の図のように時計回りに渦を巻くように移動を N 歩行った後の x , y 座標 を答えてください。
なお、マスの座標系は下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

引用: paiza.jp Aランクレベルアップセット STEP: 4 座標系での規則的な移動

着目点

東西南北は関係ありませんので完全に無視していました。(混乱させるための罠かな?)

着目点としては以下の通りです。

規則性

下記の画像からわかるように、
・深さ$d=3$において角$c$を4地点通過した時点で、次の深さ$d+2$へ入っていることがわかります。
また、同じく
・$ca$から$cb$の間で歩いた歩数$w$、つまり$w=d-1$の時において、角にいるということもわかります。
この2点の気付きだけで解くことができるとわかりましたので、残るはコードに落とし込む作業のみです。

コード化

上記の規則性を踏まえ、コード化します。

x,y,n=[int(x) for x in input().split()]

# 合計で歩いた回数
step=0
# 初回の深度は3で、深度移動のたびに+2となります
depth=3 # d+2
depth_walked=0
# デフォルトで移動させた際に1個目の角に到達するので予め1としておいてます
corner_reached=1
# 同じく、デフォルトで移動させた時点で次に進むべき方角は左です
direction='left'

# 初回の右、下という動きは共通なので、デフォルトで移動させておきます
x+=1
y+=1
step+=2

while not step>=n:
    # 角に到達
    if depth_walked is depth-1:
        # 現在の方角に従ってそれぞれの場合変換します
        if direction is 'down':
            direction='left'
        elif direction is 'left':
            direction='up'
        elif direction is 'up':
            direction='right'
        elif direction is 'right':
            direction='down'
        # 値のリセット
        depth_walked=0
        # 深度移動判定の為に角を通過した回数を記録しておきます
        corner_reached+=1

    # 次の深度に入ります
    if corner_reached is 4:
        # マニュアルで右へ移動します
        x+=1
        # 右へ移動したところで次からは下へ移動し始めます
        direction='down'
        # 次の深度です。d+2
        depth+=2
        # 変数をリセット
        corner_reached=0
        depth_walked=0
    else: # 次の深度に入った際は手動で右へ移動するので、elseです
        # それぞれの方角にしたがって座標を移動させます
        if direction is 'right':
            x+=1
        elif direction is 'left':
            x-=1
        elif direction is 'up':
            y-=1
        elif direction is 'down':
            y+=1

    step+=1
    depth_walked+=1

print(f'{x} {y}')

実行結果

実行速度も全く問題なく通ります。