Skip to content

Commit 2138441

Browse files
committed
💡 프로그래머스 159993 - 미로 탈출
1 parent 41582b7 commit 2138441

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
⭐️ 문제 정보 ⭐️
3+
문제 : 159993 - 미로 탈출
4+
레벨 : Level 2
5+
링크 : https://school.programmers.co.kr/learn/courses/30/lessons/159993
6+
*/
7+
8+
/** NOTE
9+
* - BFS 2번이 관건
10+
* - 굳이 시작 지점부터의 거리를 계속 갖고 다닐 필요가 없다 => 이러면 BFS 2번 사이에 거리를 저장하고 있어야 해서 구조가 복잡해진다.
11+
* - 첫번째 BFS : 시작 지점에서 레버까지의 최단 거리 계산
12+
* - 두번째 BFS : 레버에서 출구까지의 최단 거리 계산
13+
* - 두 거리의 합이 답이 된다.
14+
* - 각 BFS 결과 도달할 수 없는 경우가 있다면 -1 반환
15+
* - 큐 구현을 Map으로 해봤다.
16+
*/
17+
18+
class Queue {
19+
queue = new Map();
20+
head = 0;
21+
tail = 0;
22+
23+
constructor() {}
24+
25+
get size() {
26+
return this.tail - this.head;
27+
}
28+
29+
enqueue(element) {
30+
this.queue.set(this.tail++, element);
31+
}
32+
33+
dequeue() {
34+
const ret = this.queue.get(this.head);
35+
if (!ret) {
36+
return undefined;
37+
}
38+
this.queue.delete(this.head++);
39+
return ret;
40+
}
41+
42+
isEmpty() {
43+
return this.head === this.tail;
44+
}
45+
}
46+
47+
function BFS(maps, start, goal) {
48+
const R = maps.length;
49+
const C = maps[0].length;
50+
const visited = Array.from({ length: R }, () =>
51+
Array.from({ length: C }, () => false)
52+
); // 숫자 값을 저장해서 거리 저장에 활용할수도 있음
53+
const dir = [
54+
[0, 1],
55+
[0, -1],
56+
[1, 0],
57+
[-1, 0],
58+
];
59+
const queue = new Queue();
60+
61+
queue.enqueue([start, 0]);
62+
visited[start.r][start.c] = true;
63+
64+
while (!queue.isEmpty()) {
65+
const [pos, dist] = queue.dequeue();
66+
67+
if (pos.r === goal.r && pos.c === goal.c) {
68+
return dist;
69+
}
70+
71+
// 상하좌우 이동, 이동 가능한 경우에만 큐에 넣는다.
72+
for (const [dirR, dirC] of dir) {
73+
const newR = pos.r + dirR;
74+
const newC = pos.c + dirC;
75+
76+
if (newR < 0 || newR >= R || newC < 0 || newC >= C) continue;
77+
if (maps[newR][newC] === "X") continue;
78+
if (visited[newR][newC]) continue;
79+
80+
visited[newR][newC] = true;
81+
queue.enqueue([{ r: newR, c: newC }, dist + 1]);
82+
}
83+
}
84+
85+
// goal에 도달할 수 없는 경우
86+
return -1;
87+
}
88+
89+
function solution(maps) {
90+
const R = maps.length;
91+
const C = maps[0].length;
92+
93+
// 지도 탐색
94+
let S, E, L;
95+
for (let r = 0; r < R; r++) {
96+
for (let c = 0; c < C; c++) {
97+
if (maps[r][c] === "S") S = { r, c };
98+
else if (maps[r][c] === "E") E = { r, c };
99+
else if (maps[r][c] === "L") L = { r, c };
100+
}
101+
}
102+
103+
// S-L 최단 거리 구하기
104+
const distToLever = BFS(maps, S, L);
105+
if (distToLever === -1) return -1;
106+
107+
// L-E 최단 거리 구하기
108+
const distToExit = BFS(maps, L, E);
109+
if (distToExit === -1) return -1;
110+
111+
return distToLever + distToExit;
112+
}

Programmers/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
| 121683 | 외톨이 알파벳 | [121683_외톨이_알파벳.js](Unrated/121683_외톨이_알파벳.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/121683) |
6969
| 131127 | 할인 행사 | [131127_할인_행사.js](Level2/131127_할인_행사.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/131127) |
7070
| 150370 | 개인정보 수집 유효기간 | [150370_개인정보_수집_유효기간.js](Level1/150370_개인정보_수집_유효기간.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/150370) |
71+
| 159993 | 미로 탈출 | [159993_미로_탈출.js](Level2/159993_미로_탈출.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/159993) |
7172
| 159994 | 카드 뭉치 | [159994_카드_뭉치.js](Level1/159994_카드_뭉치.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/159994) |
7273
| 258711 | 도넛과 막대 그래프 | [258711_도넛과_막대_그래프.js](Level2/258711_도넛과_막대_그래프.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/258711) |
7374
| 340212 | [PCCP 기출문제] 2번 퍼즐 게임 챌린지 | [340212_[PCCP_기출문제]_2번_퍼즐_게임_챌린지.js](Level2/340212_[PCCP_기출문제]_2번_퍼즐_게임_챌린지.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/340212) |

0 commit comments

Comments
 (0)