こんにちは、ナナオです。

前回に引き続き競プロを実施していきたいと思います。

今回の問題は以下です。

座標系での移動・向き | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】

実装

前回の問題に方向が追加されました。

ということで条件を足しました。

package main
import "fmt"
func main(){
    var y, x int
    var D, d string
    fmt.Scan(&y, &x, &D)
    
    fmt.Scan(&d)
    
    // N, S, E, W のいずれかでそれぞれ 北・南・東・西 を意味する。
    switch D {
        case "N":
            if d == "R" {
                x++
            } else {
                x--
            }
        case "S":
            if d == "R" {
                x--
            } else {
                x++
            }
        case "E":
            if d == "R" {
                y++
            } else {
                y--
            }
        case "W":
            if d == "R" {
                y--
            } else {
                y++
            }
    }
    fmt.Println(y, x)
}

随分と長くなってしまいました。

一応これでも通るのですが、もっとスマートにしたいところです。

解説を見ると、スマートにできる方法が書いてありました。

  • あらかじめ、右に移動するときの座標の変化を考えておけば、左に移動するときは、-1*(右に移動するときの座標の変化) であることを用いて実装しています。
  • 移動方向がLだった場合には lr に -1 を、そうでない場合(R)は lr に1を入れることで移動量を決定しています。

なるほど…?

Goで実装してみます。

package main
import "fmt"
func main(){
    var y, x int
    var D, d string
    fmt.Scan(&y, &x, &D)
    
    lr := 1
    
    fmt.Scan(&d)
    
    if d == "L" {
        lr = -1
    }
    
    // N, S, E, W のいずれかでそれぞれ 北・南・東・西 を意味する。
    switch D {
        case "N":
            x += lr
        case "S":
            x -= lr
        case "E":
            y += lr
        case "W":
            y -= lr
    }
    fmt.Println(y, x)
}

なるほど、確かにこちらのほうがスマートですね。

めでたしめでたし。