문제
프로그래머스 문제
내 풀이
function solution(board, moves) {
let box = [];
let answer = 0;
for(var i=0; i<moves.length; i++){
let m = moves[i]-1;
for(var j=0; j<board.length; j++){
if(board[j][m] > 0){
box.push(board[j][m]);
board[j][m] = 0;
if(box[box.length-1] === box[box.length-2]){
answer++;
box.pop();
box.pop();
}
break;
}
}
}
return answer * 2;
}
개선점
- 나는 윗줄부터 아래줄까지의 상태를 제시한 board를 변형시키지 않았기 때문에 빈공간(0)이 아닌 부분까지 파고들기 위해서 중첩 루프를 썼다면, 아래의 풀이는 애초에 빈공간을 버리고 행과 열을 바꿔서 중첩할 필요없이 pop()하면 원하는 인형을 뽑을 수 있게끔 푼 풀이다. 이렇게 풀면 격자가 커지고 빈공간이 많아져도 내 풀이보다 속도가 덜 늘어날 것이다.
- [[0, 0, 0, 0, 0], [0, 0, 1, 0, 3], [0, 2, 5, 0, 1], [4, 2, 4, 4, 2], [3, 5, 1, 3, 1]], [1, 5, 3, 5, 1, 2, 1, 4]
-> [ [ 3, 4 ], [ 5, 2, 2 ], [ 1, 4, 5, 1 ], [ 3, 4 ], [ 1, 2, 1, 3 ] ]
이렇게 빈공간은 버리고 그냥 각 줄에 무슨 인형이 있는지만 정리한 것이다.
- spread 연산자가 빈배열을 받으면 그건 무시해버린다고 한다. 따라서 [...(result[i] || []), row[i]]에서 result[i]가 null이면 [...(null || []), row[i]] -> [...[], row[i]] -> [row[i]]가 된다.
const transpose = matrix =>
matrix.reduce(
(result, row) => row.map((_, i) => [...(result[i] || []), row[i]]),
[]
);
const solution = (board, moves) => {
const stacks = transpose(board).map(row =>
row.reverse().filter(el => el !== 0)
);
const basket = [];
let result = 0;
for (const move of moves) {
const pop = stacks[move - 1].pop();
if (!pop) continue;
if (pop === basket[basket.length - 1]) {
basket.pop();
result += 2;
continue;
}
basket.push(pop);
}
return result;
};