[백준] 14891_톱니바퀴 (Javascript)

잭슨·2024년 4월 4일
0

알고리즘 문제 풀이

목록 보기
59/130
post-thumbnail

문제

BOJ14891_톱니바퀴

풀이

하나의 톱니바퀴가 굴러갈 때마다 해당 톱니바퀴의 왼쪽 톱니바퀴와, 오른쪽 톱니바퀴를 확인해야 한다.

이를 함수로 구현해보면 아래와 같다.

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); // 현재 톱니바퀴 회전
    }
}

profile
지속적인 성장

0개의 댓글