하나의 톱니바퀴가 굴러갈 때마다 해당 톱니바퀴의 왼쪽 톱니바퀴와, 오른쪽 톱니바퀴를 확인해야 한다.
이를 함수로 구현해보면 아래와 같다.
function left(num, direction) {
if (num < 0) return;
// 극이 다른 경우
if (gear[num][2] !== gear[num + 1][6]) {
left(num - 1, -direction); // 왼쪽 톱니바퀴 탐색
rotate(gear[num], direction); // 현재 톱니바퀴 회전
}
}
function right(num, direction) {
if (num > 3) return;
// 극이 다른 경우
if (gear[num][6] !== gear[num - 1][2]) {
right(num + 1, -direction); // 오른쪽 톱니바퀴 탐색
rotate(gear[num], direction); // 현재 톱니바퀴 회전
}
}
서로 극이 맞닿는 부분 끼리 비교하여 만약 서로 극이 다를 경우 다음 톱니바퀴도 확인해준다.
그리고 첫 번째 톱니바퀴나 마지막 톱니바퀴까지 탐색을 마쳤거나, 극이 같아서 더 이상 탐색할 필요가 없을 경우 함수가 종료되며 톱니바퀴를 회전시킨다.
여기서 주의할 점은 톱니바퀴를 탐색을 하기 전에 톱니바퀴를 먼저 회전시키면 안된다는 점이다.
// 올바른 결과 출력
if (gear[num][6] !== gear[num - 1][2]) {
right(num + 1, -direction); // 오른쪽 톱니바퀴 탐색
rotate(gear[num], direction); // 현재 톱니바퀴 회전
}
// 잘못된 결과 출력
if (gear[num][6] !== gear[num - 1][2]) {
rotate(gear[num], direction); // 현재 톱니바퀴 회전
right(num + 1, -direction); // 오른쪽 톱니바퀴 탐색
}
톱니바퀴를 회전시키고 다음 톱니바퀴로 넘어갈 경우 현재 톱니바퀴가 회전되어, 다음 톱니바퀴와 맞닿은 극이 달라질 수 있기 때문이다.
전체 코드를 보자면 아래와 같다.
const filePath = process.platform === 'linux' ? '/dev/stdin' : './Javascript/input.txt';
const input = require('fs').readFileSync(filePath).toString().trim().split('\n');
const gear = input.slice(0, 4).map((e) => e.trimEnd().split('').map(Number));
const k = +input[4];
const actions = input.slice(5).map((e) => e.split(' ').map(Number));
let answer = 0;
actions.forEach(([num, direction]) => {
num -= 1;
left(num - 1, -direction);
right(num + 1, -direction);
rotate(gear[num], direction);
});
// 점수 계산
for (let i = 0; i < 4; i++) {
if (gear[i][0] === 0) {
answer += 0;
} else {
answer += i === 0 ? 1 : 1 << i;
}
}
console.log(answer);
function clockWise(arr) {
const rear = arr.pop();
arr.unshift(rear);
}
function antiClockWise(arr) {
const front = arr.shift();
arr.push(front);
}
function rotate(arr, direction) {
// 시계 방향
if (direction === 1) {
clockWise(arr);
}
// 반시계 방향
else {
antiClockWise(arr);
}
}
function left(num, direction) {
if (num < 0) return;
// 극이 다른 경우
if (gear[num][2] !== gear[num + 1][6]) {
left(num - 1, -direction); // 왼쪽 톱니바퀴 탐색
rotate(gear[num], direction); // 현재 톱니바퀴 회전
}
}
function right(num, direction) {
if (num > 3) return;
// 극이 다른 경우
if (gear[num][6] !== gear[num - 1][2]) {
right(num + 1, -direction); // 오른쪽 톱니바퀴 탐색
rotate(gear[num], direction); // 현재 톱니바퀴 회전
}
}
