paizaの練習問題を解く 移動が可能かの判定・幅のある移動 Go編
こんにちは、ナナオです。 前回に引き続き競プロを実施していきたいと思います。 今回の問題は以下です。 移動が可能かの判定・幅のある移動 | レベルアップ問題集 | プログラミング学習サイト【paizaラーニング】 実装 コアとなるロジックはあまり変わらないのですが、途中で壁があったり壁を超えたりする場合はそれを超える手前の座標を出力したうえでStopと出力しなければいけないようです。 ちょっと大変でしたが実装しました。 package main import "fmt" func main(){ var h, w, sy, sx, n int fmt.Scan(&h, &w, &sy, &sx, &n) s := make([]string, h) for i := 0; i < h; i++ { fmt.Scan(&s[i]) } dir := []string{"N", "E", "S", "W"} c := 120 // 現在の向き for i := 0; i < n; i++ { var d string var l int fmt.Scan(&d, &l) lr := 1 if d == "L" { lr = -1 } move := l * lr // 移動量 // X軸上に壁があるかどうか判定 checkWallX := func(y, fromX, toX, lr int) bool { i := fromX for { i += lr if i == toX { fmt.Println(y, toX) return true } if i >= w || i < 0 || s[sy][i] == '#' { fmt.Println(y, i - lr) fmt.Println("Stop") return false } } } // Y軸上に壁があるかどうか判定 checkWallY := func(x, fromY, toY, lr int) bool { i := fromY for { i += lr if i == toY { fmt.Println(toY, x) return true } if i >= h || i < 0 || s[i][sx] == '#' { fmt.Println(i - lr, x) fmt.Println("Stop") return false } } } // チェック結果を格納 result := true switch dir[c%4] { case "N": result = checkWallX(sy, sx, sx + move, lr) sx += move case "S": result = checkWallX(sy, sx, sx - move, -lr) sx -= move case "E": result = checkWallY(sx, sy, sy + move, lr) sy += move case "W": result = checkWallY(sx, sy, sy - move, -lr) sy -= move } c += lr if !result { return } } } ポイントはcheckWall関数です。 ...