📍문제 링크
https://www.acmicpc.net/problem/14891
14891번: 톱니바퀴
총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴
www.acmicpc.net
📍알고리즘 분류
- 구현
- 시뮬레이션
📍문제 풀이
- 톱니바퀴 동작 모델링하는 어려웠던 구현 문제
- 실제 톱니바퀴처럼 맞물려서 돌아가는 것이 아니라, 하나가 회전하면 맞닿은 톱니바퀴는 회전하지 않을 수도 있다
- 회전하는 톱니바퀴는 deque 으로 구현
📍코드 (JavaScript)
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const input = [];
// 점수 계산하는 함수
const getScore = (deques) => {
return (
deques[0][0] * 1 + deques[1][0] * 2 + deques[2][0] * 4 + deques[3][0] * 8
);
};
// 왼쪽 방향 탐색하며 rotateList 완성
const leftScan = (deques, leftNth, rotateList) => {
const newRotateList = rotateList;
if (leftNth < 0 || newRotateList[leftNth + 1] === 0) return;
if (deques[leftNth][2] !== deques[leftNth + 1][6]) {
newRotateList[leftNth] = -newRotateList[leftNth + 1];
} else {
newRotateList[leftNth] = 0;
}
return newRotateList;
};
// 오른쪽 방향 탐색하며 rotateList 완성
const rightScan = (deques, rightNth, rotateList) => {
const newRotateList = rotateList;
if (rightNth > 3 || newRotateList[rightNth - 1] === 0) return;
if (deques[rightNth][6] !== deques[rightNth - 1][2]) {
newRotateList[rightNth] = -newRotateList[rightNth - 1];
} else {
newRotateList[rightNth] = 0;
}
return newRotateList;
};
// 회전 함수
const rotate = (deques, rotateList) => {
const newDeques = deques;
rotateList.forEach((rotation, idx) => {
if (rotation === 1) {
newDeques[idx].unshift(newDeques[idx].pop());
}
if (rotation === -1) {
newDeques[idx].push(newDeques[idx].shift());
}
});
return newDeques;
};
rl.on("line", (line) => {
input.push(line);
}).on("close", () => {
const gears = input.slice(0, 4).map((el) => el.split(""));
const N = +input[4];
const data = input.slice(5).map((el) => el.split(" ").map(Number));
for (let el of data) {
const nth = el[0] - 1;
let leftIdx = nth;
let rightIdx = nth;
const rotateArr = [0, 0, 0, 0];
rotateArr[nth] = el[1]; // 회전 명령 받은 톱니 회전
while (--leftIdx > -1) {
leftScan(gears, leftIdx, rotateArr);
}
while (++rightIdx < 4) {
rightScan(gears, rightIdx, rotateArr);
}
// rotateArr 완성되면
rotate(gears, rotateArr);
}
console.log(getScore(gears));
});
📍리뷰
- leftScan 함수와 rightScan 함수를 결합할 수 있을까??
ChatGPT로 리팩토링 아이템을 물어봤는데, 결합하는게 낫다고 했다. 하지만, 양방향 반복문을 구현하기 힘드니 안 합치는게 나을 것 같다 (중복 코드라고생각되는 부분은 존재)
- 그런데 ChatGPT가 리팩토링만 해준 함수를 다듬어서 테스트했는데, 제대로 동작하지 않았다
아직 ChatGPT가 완벽하지 않은것 같아 다행이다