PaizaAランクLvアップ問題と解説(Ruby)その5

※スキルチェック問題ではありません。
規約により公式の解答コードそのままはよろしくないので、
オリジナルのコードにしています。

詳しくはコチラ

なるべくわかりやすい解説を付けました

その5  座標系での向きの変わる移動 (paizaランク B 相当)

開始時点の x , y 座標、移動の回数 N が与えられます。
続くN行で移動の向き d1 … dN が与えられるので、与えられた順に移動をしたときの各移動後の x , y 座標 を答えてください。
移動者ははじめ北を向いています。

なお、マスの座標系は下方向が y 座標の正の向き、右方向が x 座標の正の向きとします。

・ 移動をするごとに向く方角が変わること
・ 移動前に向いている方角によって同じ移動の向きでも座標の変化が違うこと
の 2 点に気をつけてください。
例えば、上の図の状態から右に移動を行った場合、下の図のような状態になります。


入力される値
X Y N       
d1      
...     
dN

・ 1 行目には、開始時点の x , y 座標を表す X , Y, 移動の回数 N が与えられます。
・ 続く N 行 (1 ≦ i ≦ N) には、盤面の i 回目の移動の向きを表す文字 d_i が与えられます。入力値最終行の末尾に改行が1つ入ります。

期待する出力
N 行での出力

・ 各移動後の x , y 座標を出力してください。

x_1 y_1
...
x_N y_N
条件
すべてのテストケースにおいて、以下の条件をみたします。
・ -100 ≦ X, Y ≦ 100
・ 1 ≦ N ≦ 100
・ d は、L, R のいずれかでそれぞれ 左・右 に 1 マス進むことを表す。
入力例1

3 5 1
L
出力例1

2 5
入力例2

-18 45 6
L
L
R
R
L
R
出力例2

-19 45
-19 46
-20 46
-20 45
-21 45
-21 44

解答と解説

x, y, n = gets.split.map(&:to_i)

#初期位置が北なので以下のように配置[北, 東, 南, 西]
operate = [[-1, 0], [0, 1], [1, 0], [0, -1]]

#LとRで移動したときの状態を表す
current = 0
n.times do
  d = gets.chomp

#LかRかで状態を変える
  d == 'L' ? current -= 1 : current += 1

#状態によって移動を変更する
  y += operate[current % 4][0]
  x += operate[current % 4][1]
  puts x.to_s + ' ' + y.to_s
end

※ポイント

初期状態が北向きなのでRだったら東で[0, 1]に進み
Lだったら西なので[0, -1]に進む
-1 % 4 は 3
-3 % 4 は 1
1 % 4 は 1
3 % 4 は 3
となるので
d == ‘L’ ? now -= 1 : now += 1
でnowの値を変えるだけで移動操作が表現できる。

その6に続きます

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です