티스토리 뷰
📍 문제 탐색하기
로봇 문제는 정사각형 영역 SS에서 로봇이 주어진 명령어 열에 따라 이동한 뒤 최종 위치를 계산하는 문제다.
문제 조건
- 영역 S는 (0,0)에서 (M,M)까지의 정사각형이다.
- 로봇은 (0,0)에서 동쪽을 바라보고 시작한다.
- 명령어는 두 가지:
- TURN dir:
- TURN 0: 왼쪽 90도 회전
- TURN 1: 오른쪽 90도 회전
- MOVE d: 현재 방향으로 d만큼 이동.
- TURN dir:
- 명령어 수행 후 로봇이 S의 경계 또는 내부에 있어야 한다.
- 모든 명령어가 유효하면 최종 위치를 출력하고, 하나라도 유효하지 않다면 −1을 출력한다.
입력 범위
- 1≤M,n≤1,000
- 각 명령어의 d: 1≤d≤1,000
- 시간과 메모리 제약을 고려해야 한다.
가능한 시간복잡도
명령어 개에 대해 각 명령어를 상수 시간에 처리하므로 O(n)에 해결 가능하다.
알고리즘 선택
- 시뮬레이션:
- 로봇의 위치와 방향을 갱신하며 명령어를 차례로 실행한다.
- 경계를 벗어나거나 유효하지 않은 명령어가 있으면 즉시 종료한다.
📍 코드 설계하기
- 입력 받기:
- M: 정사각형 S의 크기.
- n: 명령어의 개수.
- 명령어 목록: TURN 또는 MOVE.
- 초기화:
- 로봇의 초기 위치: (0,0).
- 초기 방향: 동쪽.
- 명령어 수행:
- 각 명령어를 읽고 수행:
- MOVE:
- 이동 후 위치를 계산.
- 경계 검사.
- 경계 밖으로 나가면 −1 출력 후 종료.
- TURN:
- 방향 갱신.
- MOVE:
- 명령어가 유효하지 않으면 −1 출력 후 종료.
- 각 명령어를 읽고 수행:
- 결과 출력:
- 모든 명령어가 유효하다면 최종 위치 (x,y)를 출력.
📍 시도 회차 및 수정 사항
1차 시도 (중복 코드 문제) ✅
import sys
input = sys.stdin.readline
M, n = map(int, input().split())
robot = []
for _ in range(n):
command, num = input().split()
robot.append((command, int(num)))
x, y = 0, 0
idx = 0
directions = ['east', 'north', 'west', 'south']
for command, num in robot:
dir = directions[idx]
if command == 'MOVE':
if dir == 'east':
if 0 <= x + num < M:
x = x+num
else:
print(-1)
sys.exit(0)
elif dir == 'north':
if 0 <= y + num < M:
y = y+num
else:
print(-1)
sys.exit(0)
elif dir == 'west':
if 0 <= x - num < M:
x = x-num
else:
print(-1)
sys.exit(0)
else:
if 0 <= y - num < M:
y = y-num
else:
print(-1)
sys.exit(0)
elif command == 'TURN':
if num == 0:
idx = (idx + 1) % 4
else:
idx = (idx - 1 + 4) % 4
else:
print(-1)
sys.exit(0)
print(x, y)
문제점
답은 맞지만,
- MOVE 명령어에서 방향별로 같은 경계 검사 코드가 반복되는게 거슬렸다.
- 종료 처리 코드(print(-1) 및 sys.exit(0))도 중복되었다.
2차 시도 (중복 코드 제거) ✅
import sys
input = sys.stdin.readline
M, n = map(int, input().split())
robot = []
for _ in range(n):
command, num = input().split()
robot.append((command, int(num)))
# 초기화
x, y = 0, 0
idx = 0
directions = ['east', 'north', 'west', 'south']
def check_boundary(new_x, new_y):
if not (0 <= new_x < M and 0 <= new_y < M):
print(-1)
sys.exit(0)
for command, num in robot:
if command == 'MOVE':
if directions[idx] == 'east':
check_boundary(x + num, y)
x += num
elif directions[idx] == 'north':
check_boundary(x, y + num)
y += num
elif directions[idx] == 'west':
check_boundary(x - num, y)
x -= num
elif directions[idx] == 'south':
check_boundary(x, y - num)
y -= num
elif command == 'TURN':
if num == 0:
idx = (idx + 1) % 4 # 좌회전
elif num == 1:
idx = (idx - 1 + 4) % 4 # 우회전
else:
print(-1)
sys.exit(0)
else:
print(-1)
sys.exit(0)
print(x, y)
해결 방법
- check_boundary 함수로 경계 검사 코드를 추출해주었다:
- 함수화 시켜 중복된 경계 검사 코드가 제거되었다!
- 종료 처리 통합:
- 모든 비정상 상황을 공통 함수로 처리하여 간결화시켜주었당.
📍 느낀점
- 중복된 코드를 함수로 추출하는 것이 가독성과 유지보수성에 좋다는 것을 다시 한 번 느꼈다.
- 조건문이 많아질수록 코드를 깔끔하게 구성하기 위해 함수 추출 및 구조화를 고려해야 되겠다.
'알고리즘' 카테고리의 다른 글
[알고리즘] 백준 파이썬 2615 오목 (1) | 2025.01.16 |
---|---|
[알고리즘] 백준 파이썬 2503 숫자 야구 (0) | 2025.01.15 |
[알고리즘] 백준 파이썬 2096 내려가기 (1) | 2025.01.13 |
[알고리즘] 백준 파이썬 1149 RGB거리 (0) | 2025.01.12 |
[알고리즘] 백준 파이썬 14430 자원캐기 (1) | 2025.01.11 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 회원탈퇴
- 인텔리제이
- 웹MVC
- SQL 레벨업
- 백준 파이썬
- SQL
- 스프링부트
- 웹 MVC
- 스프링 커뮤니티
- 다이나믹 프로그래밍
- 로깅
- 로그아웃
- elasticsearch
- 스프링
- 자바
- SQLD
- 지연로딩
- 북마크
- 영속
- JPA
- 백준
- 프론트엔드
- 스프링 북마크
- EnumType.ORDINAL
- 자바 스프링
- 비영속
- 커뮤니티
- 준영속
- DP
- 파이썬
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
글 보관함