{ }codelper
열거형switchP0077

거북이가 보는 방향

거북이 한 마리가 (0, 0)에서 북쪽을 보고 서 있다.
북쪽으로 한 걸음이면 y가 1 늘고, 동쪽이면 x가 1 늘고, 남쪽이면 y가 1 줄고, 서쪽이면 x가 1 준다.
한 줄에 명령 글자들이 빈칸 없이 주어진다.
F는 보는 방향으로 한 걸음, R은 오른쪽으로 90도 돌기, L은 왼쪽으로 90도 돌기, B는 제자리에서 뒤로 돌기(180도)다.
명령을 모두 마친 뒤 거북이의 x, y와 보는 방향의 첫 글자(N·E·S·W 중 하나)를 빈칸 하나씩 띄워 출력하라.
방향은 북·동·남·서 네 값을 시계 방향 차례로 가진 열거형(enum)으로 만들어 풀어 보자.

입력
명령의 길이는 1 이상 100,000 이하, 글자는 F·R·L·B 중 하나
출력
한 줄: x y 방향
예시 1 · stdin
FFRFFLFBFF
stdout
2 1 S
예시 2 · stdin
LF
stdout
-1 0 W
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 6개 언어 풀이

이 문제는 열거형으로 풀 수 있는 Python·TypeScript·Java·C#·C·C++만 받아요.
Python은 표준 모듈 enum의 class Dir(Enum)으로 만들어요.
JavaScript에는 열거형 문법이 없어서(Object.freeze({...})로 흉내만 내요) 빠지고, 크레이콘에도 열거형이 없어요.
TypeScript의 enum Dir { North, East, South, West }는 값이 0~3인 숫자 열거형이라 (d + 1) % 4처럼 수로 계산한 뒤 as Dir로 되돌리고, 역방향 표 Dir[d]가 이름 "North"를 줘요.
enum은 타입만 있는 문법이 아니라 실행할 때 쓰는 객체를 만들어 내요.
언어마다 열거형의 속이 달라요.
C의 enum Dir { NORTH, EAST, SOUTH, WEST }는 이름 붙은 int 상수 0~3일 뿐이라 실행 중에 이름을 모르고, "NESW"[d]처럼 이름표를 직접 둬요.
C++ enum class는 Dir::North로 쓰고 int로 저절로 바뀌지 않아 static_cast<int>(d)가 필요해요.
Java enum은 클래스라서 values(), ordinal(), name()을 가지고, C#은 (Dir)(((int)d + 1) % 4)처럼 오가고 d.ToString()이 이름을 줘요.
Python은 Dir(값), d.value, d.name이에요.
함정 셋: ① 왼쪽 돌기를 (d - 1) % 4로 쓰면 북쪽(0)에서 C·C++·Java·C#·TypeScript는 -1이 나와요(나머지가 나누어지는 수의 부호를 따라가요).
C#은 (Dir)(-1)도 오류 없이 만들어 "-1"을 찍고, TypeScript도 -1 as Dir를 막지 않아 Dir[-1]이 undefined가 돼요.
(d + 3) % 4로 써요(Python은 -1 % 4 == 3이라 괜찮아요).
② C·C++(그리고 Java의 옛 case: switch)에서 break를 빠뜨리면 다음 case로 흘러내려 한 걸음에 여러 번 움직여요.
C#은 이걸 컴파일 오류로 막고, Java의 case NORTH -> y++; 화살표 switch는 흘러내리지 않아요.
③ Python의 Enum 멤버는 수와 같지 않아서 d == 0은 늘 False예요(IntEnum이면 True).
d == Dir.NORTH나 d.value로 비교해요.

Pythonmain.py · 23 줄
from enum import Enum  class Dir(Enum):  # 시계 방향 차례    NORTH = 0    EAST = 1    SOUTH = 2    WEST = 3  STEP = {Dir.NORTH: (0, 1), Dir.EAST: (1, 0), Dir.SOUTH: (0, -1), Dir.WEST: (-1, 0)}TURN = {"R": 1, "B": 2, "L": 3}  # 왼쪽 = 오른쪽으로 세 번 x = y = 0d = Dir.NORTHfor c in input().strip():    if c == "F":        dx, dy = STEP[d]        x += dx        y += dy    else:        d = Dir((d.value + TURN[c]) % 4)  # 수로 바꿔 계산하고 다시 열거형으로print(x, y, d.name[0])
TypeScriptmain.ts · 34 줄
import { readFileSync } from "node:fs"; enum Dir { // 시계 방향 차례: North = 0, East = 1, South = 2, West = 3  North,  East,  South,  West,} // 숫자 enum은 수로 계산할 수 있다. 결과를 다시 Dir로 돌려놓는다function turn(d: Dir, k: number): Dir {  return ((d + k) % 4) as Dir; // 왼쪽은 -1 대신 +3} const s = readFileSync(0, "utf8").trim();let x = 0;let y = 0;let d = Dir.North;for (const c of s) {  switch (c) {    case "R": d = turn(d, 1); break;    case "B": d = turn(d, 2); break;    case "L": d = turn(d, 3); break;    default:      switch (d) {        case Dir.North: y++; break;        case Dir.East: x++; break;        case Dir.South: y--; break;        case Dir.West: x--; break;      }  }}// 역방향 표 Dir[d]가 이름("South")을 준다console.log(`${x} ${y} ${Dir[d].charAt(0)}`);
JavaMain.java · 33 줄
import java.io.BufferedReader;import java.io.InputStreamReader; public class Main {    enum Dir { NORTH, EAST, SOUTH, WEST } // 시계 방향 차례     static Dir turn(Dir d, int k) {        Dir[] all = Dir.values();        return all[(d.ordinal() + k) % 4];    }     public static void main(String[] args) throws Exception {        String s = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();        int x = 0, y = 0;        Dir d = Dir.NORTH;        for (char c : s.toCharArray()) {            switch (c) {                case 'R' -> d = turn(d, 1);                case 'B' -> d = turn(d, 2);                case 'L' -> d = turn(d, 3);                default -> {                    switch (d) { // 화살표 switch는 아래로 흘러내리지 않는다                        case NORTH -> y++;                        case EAST -> x++;                        case SOUTH -> y--;                        case WEST -> x--;                    }                }            }        }        System.out.println(x + " " + y + " " + d.name().charAt(0));    }}
C#Main.cs · 34 줄
using System; enum Dir { North, East, South, West } // 시계 방향 차례 class Program{    static Dir Turn(Dir d, int k) => (Dir)(((int)d + k) % 4); // 열거형 ↔ int는 명시적으로 바꾼다     static void Main()    {        string s = Console.ReadLine().Trim();        int x = 0, y = 0;        Dir d = Dir.North;        foreach (char c in s)        {            switch (c)            {                case 'R': d = Turn(d, 1); break;                case 'B': d = Turn(d, 2); break;                case 'L': d = Turn(d, 3); break;                default:                    switch (d)                    {                        case Dir.North: y++; break;                        case Dir.East: x++; break;                        case Dir.South: y--; break;                        case Dir.West: x--; break;                    }                    break;            }        }        Console.WriteLine($"{x} {y} {d.ToString()[0]}");    }}
C++main.cpp · 34 줄
#include <iostream>#include <string> enum class Dir { North, East, South, West };  // 범위 있는 열거형: Dir::North로 쓰고 int로 저절로 바뀌지 않는다 Dir turn(Dir d, int k) {    return static_cast<Dir>((static_cast<int>(d) + k) % 4);} char name(Dir d) {    return "NESW"[static_cast<int>(d)];  // C++도 열거형의 이름을 실행 중에 모른다} int main() {    std::string s;    std::cin >> s;    int x = 0, y = 0;    Dir d = Dir::North;    for (char c : s) {        switch (c) {        case 'R': d = turn(d, 1); break;        case 'B': d = turn(d, 2); break;        case 'L': d = turn(d, 3); break;        default:            switch (d) {            case Dir::North: y++; break;            case Dir::East:  x++; break;            case Dir::South: y--; break;            case Dir::West:  x--; break;            }        }    }    std::cout << x << " " << y << " " << name(d) << "\n";}
Cmain.c · 32 줄
#include <stdio.h> enum Dir { NORTH, EAST, SOUTH, WEST };  /* 이름 붙은 int 상수 0, 1, 2, 3 */ static const char NAME[] = "NESW";      /* C 열거형은 실행 중에 이름을 모른다: 직접 둔다 */ enum Dir turn(enum Dir d, int k) {    return (enum Dir)((d + k) % 4);} int main(void) {    static char s[100002];    scanf("%100001s", s);    int x = 0, y = 0;    enum Dir d = NORTH;    for (int i = 0; s[i]; i++) {        switch (s[i]) {        case 'R': d = turn(d, 1); break;        case 'B': d = turn(d, 2); break;        case 'L': d = turn(d, 3); break;        default:            switch (d) {            case NORTH: y++; break;  /* break가 없으면 다음 case로 흘러내린다 */            case EAST:  x++; break;            case SOUTH: y--; break;            case WEST:  x--; break;            }        }    }    printf("%d %d %c\n", x, y, NAME[d]);    return 0;}