문제 번호
알고리즘 분류
문제 풀이
구현 문제이다.
한 가지 어려웠던 점은 한개의 톱니바퀴가 돌아가면 다른 톱니바퀴에도 영향을 끼치게되는데 이 과정들이 동시에 일어난다는 것이다. 예를들어 1번 톱니바퀴를 돌리면 오른쪽 끝에있는 4번 톱니바퀴도 돌아갈 수 있는데, 1-2-3-4번 차례로 돌리는 것이 아니라 1-2-3-4번 톱니바퀴가 '동시에' 돌아가야 한다.
우선 돌리긴 돌려야하니 시계방향, 반 시계 방향으로 톱니를 돌리는 알고리즘을 작성했다.
function turnClock(gear) { // 반 시계 방향. <-
let temp = [...gear];
for (let i = 0; i < gear.length; i++) {
gear[i] = temp[(i + 1) % gear.length];
}
return gear;
}
function turnRclock(gear) { // 시계 방향. ->
let temp = [...gear];
for (let i = 0; i < gear.length; i++) {
gear[i] = temp[(i + gear.length - 1) % gear.length]
}
}
그러고 나서 생각을 해보니 '동시에' 돌려야 한다면 모든 톱니바퀴의 회전상태를 알고나서 한번에 돌리면 되겠거니 싶었다. 그럼 이제 돌리는 톱니바퀴와 방향이 주어졌을때 다른 톱니바퀴는 어느 방향으로 돌려야하는지 파악해보자.
각 톱니바퀴는 오른쪽, 왼쪽에 다른 톱니바퀴가 있을 수 있으므로 양쪽 다 확인해 준다. rotate배열에 각각의 톱니바퀴가 어느 방향으로 회전하는지 저장 할 것이다.
//각 톱니가 어디로 도는지 파악하고 모든 톱니를 한번에 돌린다.
let rotate = new Array(4).fill(0);
rotate[numOfGear] = way;
// 돌리는 톱니를 기준으로 오른쪽 확인.
for (let i = numOfGear; i < 3; i++) {
if (gear[i][2] !== gear[i + 1][6])
rotate[i + 1] = -1 * rotate[i];
else
break;
}
// 돌리는 톱니를 기준으로 왼쪽 확인.
for (let i = numOfGear; i > 0; i--) {
if (gear[i][6] !== gear[i - 1][2])
rotate[i - 1] = -1 * rotate[i];
else
break;
}
각각의 톱니바퀴가 어느방향으로 회전하는지 알았다면 위에서 구현해둔 회전 알고리즘을 사용해서 톱니바퀴를 돌려주면 된다.
// 톱니들의 회전방향을 모두 알았으니 돌린다.
for (let i = 0; i < rotate.length; i++) {
if (rotate[i] == 0)
continue;
else if (rotate[i] == -1) {
turnClock(gear[i]);
} else if (rotate[i] == 1) {
turnRclock(gear[i]);
}
}
마지막으로 각각의 톱니바퀴바다 위(12시 방향)에 있는 극에 따라서 점수를 합산해 주어야 한다.
for(let i=0; i<gear.length; i++) {
answer += gear[i][0] * Math.pow(2,i) ;
}
전체 코드
/**
* 1 2 3 4
* 극이 다르면 반대 방향.
*
* 극이 같으면 회전 안함.
* 1. 시계방향 회전 구현.
* 2. 반시계방향 회전 구현.
* 3. 각 톱니의 상태에 따라서 서로의 영향을 확인한다.
* 4. 각 톱니는 0-7 인덱스. 0은 12시방향, 2는 오른쪽, 6은 왼쪽 이다.
* 5. 1개의 톱니바퀴를 돌리때 다른 톱니의 회전방향까지 모두 구한다.
* 6. 모든 톱니바퀴의 회전방향을 구하고 모든 톱니바퀴의 회전을 한번에 적용한다.
*/
function main() {
let answer = 0;
const input = require('fs').readFileSync('dev/stdin').toString().trim().split('\n');
let gear = input.slice(0, 4).map(_ => _.trim().split('').map(Number));
// 회전 횟수
const K = +input[4].trim();
// 톱니, 방향 1:시계, -1: 반시계
const move = input.slice(5).map(_ => _.trim().split(' ').map(Number));
for (let i = 0; i < move.length; i++) {
let [numOfGear, way] = move[i];
sol(gear, numOfGear, way)
}
for(let i=0; i<gear.length; i++) {
answer += gear[i][0] * Math.pow(2,i) ;
}
console.log(answer)
}
function sol(gear, numOfGear, way) {
numOfGear--;
//각 톱니가 어디로 도는지 파악하고 모든 톱니를 한번에 돌린다.
let rotate = new Array(4).fill(0);
rotate[numOfGear] = way;
// 돌리는 톱니를 기준으로 오른쪽 확인.
for (let i = numOfGear; i < 3; i++) {
if (gear[i][2] !== gear[i + 1][6])
rotate[i + 1] = -1 * rotate[i];
else
break;
}
// 돌리는 톱니를 기준으로 왼쪽 확인.
for (let i = numOfGear; i > 0; i--) {
if (gear[i][6] !== gear[i - 1][2])
rotate[i - 1] = -1 * rotate[i];
else
break;
}
// 톱니들의 회전방향을 모두 알았으니 돌린다.
for (let i = 0; i < rotate.length; i++) {
if (rotate[i] == 0)
continue;
else if (rotate[i] == -1) {
turnClock(gear[i]);
} else if (rotate[i] == 1) {
turnRclock(gear[i]);
}
}
}
function turnClock(gear) { // 반 시계 방향. <-
let temp = [...gear];
for (let i = 0; i < gear.length; i++) {
gear[i] = temp[(i + 1) % gear.length];
}
return gear;
}
function turnRclock(gear) { // 시계 방향. ->
let temp = [...gear];
for (let i = 0; i < gear.length; i++) {
gear[i] = temp[(i + gear.length - 1) % gear.length]
}
}
main();
특이사항
'Algorithm' 카테고리의 다른 글
[JS][백준]10699_오늘 날짜 (2) | 2022.03.28 |
---|