## 🌟 문제
[코딩테스트 연습 - 방문 길이 \| 프로그래머스 스쿨](https://school.programmers.co.kr/learn/courses/30/lessons/49994)
캐릭터의 이동방향 명령어가 주어졌을 때, 좌표명면 위에서 캐릭터가 처음 걸어본 길의 길이를 구하기
## 🌟 풀이
알고리즘 문제를 풀 때에는 함수를 잘 쪼개지 않는 편인데 (재사용 할 일이 거의 없기 때문 + 가독성이 오히려 좋지 않음) 구현 문제의 경우에는 재사용 할 일도 많고 코드가 너무 길어서 오히려 기능별로 코드 분리를 하지 않으면 가독성이 너무 좋지 않은 것 같다... 그래서 분리해줬다.
```javascript
// 주어진 위치가 좌표 평면을 벗어나는지를 확인하는 함수
function isValidPos(pos) {
const { x, y } = pos;
return (x >= -5 && x <= 5) && (y >= -5 && y <= 5);
}
// 명령어에 따라 업데이트 된 위치를 반환하는 함수
function move(dir, pos) {
const { x, y } = pos;
let npos;
switch(dir) {
case "U":
nPos = {x, y: y - 1};
if (isValidPos(nPos)) return nPos;
return null;
case "D":
nPos = {x, y: y + 1};
if (isValidPos(nPos)) return nPos;
return null;
case "R":
nPos = {x: x + 1, y};
if (isValidPos(nPos)) return nPos;
return null;
case "L":
nPos = {x: x - 1, y};
if (isValidPos(nPos)) return nPos;
return null;
default:
return null;
}
}
```
이번에 새로 배운 것은 방문 경로를 문자열로 저장해두는 것이었다. 방문한 "칸"이 아니라 "경로"를 저장해야 하는 상황이라 고민을 많이 했는데, 양방향 경로를 문자열로 만들어 Set에 저장해두면 양방항 경로 모두의 방문 여부를 체크해 둘 수 있었다.
```javascript
const path = `${pos.x},${pos.y}-${newPos.x},${newPos.y}`;
const oppositePath = `${newPos.x},${newPos.y}-${pos.x},${pos.y}`;
if (!visited.has(path)) {
visited.add(path);
visited.add(oppositePath);
answer++;
}
```
전체 코드
```javascript
function isValidPos(pos) {
const { x, y } = pos;
return (x >= -5 && x <= 5) && (y >= -5 && y <= 5);
}
// 명령어에 따라 업데이트 된 위치를 반환하는 함수
function move(dir, pos) {
const { x, y } = pos;
let npos;
switch(dir) {
case "U":
nPos = {x, y: y - 1};
if (isValidPos(nPos)) return nPos;
return null;
case "D":
nPos = {x, y: y + 1};
if (isValidPos(nPos)) return nPos;
return null;
case "R":
nPos = {x: x + 1, y};
if (isValidPos(nPos)) return nPos;
return null;
case "L":
nPos = {x: x - 1, y};
if (isValidPos(nPos)) return nPos;
return null;
default:
return null;
}
}
function solution(dirs) {
let answer = 0;
const visited = new Set(); // 방문한 from-to 경로를 저장하는 set
let pos = {x: 0, y: 0};
for (const dir of dirs) {
const newPos = move(dir, pos);
if (!newPos) continue;
const path = `${pos.x},${pos.y}-${newPos.x},${newPos.y}`;
const oppositePath = `${newPos.x},${newPos.y}-${pos.x},${pos.y}`;
if (!visited.has(path)) {
visited.add(path);
visited.add(oppositePath);
answer++;
}
pos = newPos;
}
return answer;
}
```