def solution(park, routes):
dir_dict = {'N': (-1, 0), 'S': (1, 0), 'W': (0, -1), 'E': (0, 1)}
# 출발 지점 탐색
r = c = 0
for y in range(len(park)):
for x in range(len(park[y])):
if park[y][x] == 'S':
r, c = y, x
break
for route in routes: # 각 명령문별 방향 및 이동거리 추출
dr, dc = dir_dict[route[0]]
moves = int(route[2])
# park의 범위를 벗어나지 않는지 검사
if 0 <= r + dr*moves < len(park) and 0 <= c + dc*moves < len(park[0]):
# 벗어나지 않는다면, 명령문별 도착지 좌표 설정
nr = r + dr*moves
nc = c + dc*moves
# 도착지로 이동 중 장애물을 만나지 않는지 검사
if all(park[r+i*dr][c+i*dc] != 'X' for i in range(1, moves+1)):
r, c = nr, nc
answer = [r, c]
return answer
TIL & 코드 개선사항
# 개선 전
if 0 <= r + dr*moves < len(park) and 0 <= c + dc*moves < len(park[0]):
(nr, nc) = (r, c)
for _ in range(moves):
nr += dr
nc += dc
if park[nr][nc] == 'X':
break
else:
(r, c) = (nr, nc)
# 개선 후
if 0 <= r + dr*moves < len(park) and 0 <= c + dc*moves < len(park[0]):
nr = r + dr*moves
nc = c + dc*moves
if all(park[r+i*dr][c+i*dc] != 'X' for i in range(1, moves+1)):
r, c = nr, nc
개선 전
- 두 변수의 값을 갱신할 때 쓸데없이(...) 튜플로 묶어주었다.
- 이동 범위 내에 'X'를 만나지 않아서 반복문이 break되는 일이 없다면 else문을 통해 r, c값을 갱신하였는데, all 메서드를 활용하여 코드를 단축시켰다.
개선 후 & TIL [all 메서드 활용하기]
- all은 iterable한 객체를 인수로 받아, 객체의 요소의 참/거짓을 판별해 하나라도 거짓이 있을 시 'false'를, 모두 다 참인 경우엔 'true'를 반환한다. 따라서 경로 이동 중 하나라도 조건과 맞지 않는다면 갱신이 되지 않는 등의 로직에 사용하기 좋다.
- 여태껏 습관적으로 for-else (조건이 다 들어맞아서 반복문을 다 돌았을 때에만 else문 안에서 새로 특정 변수를 갱신해주기) 구조를 활용했는데, if-all-for(comprehension)문을 활용하니 코드가 훨씬 깔끔해졌다. 게다가 all은 거짓 값을 만나면 즉시 false를 반환하고 반복을 중단하기 때문에 break을 따로 적어줄 필요가 없다.
'Algorithm' 카테고리의 다른 글
[백준] 계단 오르기 | 자바스크립트 JS | 다이나믹 프로그래밍 DP | S3 (1) | 2024.01.28 |
---|---|
[백준] 파도반 수열 | 자바스크립트 JS | 다이나믹 프로그래밍 DP | S3 (0) | 2024.01.26 |
[백준] DSLR | 자바스크립트 JS | BFS | G4 (1) | 2024.01.25 |
[백준] 테트로미노 | 자바스크립트 JS | 브루트포스, 구현 | G4 (1) | 2024.01.24 |
[백준] 뱀과 사다리 게임 | 자바스크립트 JS | BFS | G5 (0) | 2024.01.23 |