sungyup's.

Web_Miscellaneous / Algorithm(JS) / 4.10 프로그래머스 Lv.0 #101~124

4.10프로그래머스 Lv.0 #101~124

프로그래머스 Lv.0 101~124번

개요

기초 트레이닝 문제(Lv.0) 101 ~ 124번 문제 풀이 중 배울 점이 있는 풀이들에서 배운 개념들을 내 것으로 만들고자 정리해본다.

102. 전국 대회 선발 고사

전국 대회 선발 고사

javascript
function solution(rank, attendance) { const rankedMap = rank.map((v, i) => { return attendance[i] ? v : 0 }).filter(v => v).sort((a, b) => a - b) const a = rank.indexOf(rankedMap[0]); const b = rank.indexOf(rankedMap[1]); const c = rank.indexOf(rankedMap[2]); return 10000 * a + 100 * b + c; }

102-1.

javascript
function solution(rank, attendance) { const [a, b, c] = rank .map((r, i) => [r, i]) .filter(([_, i]) => attendance[i]) .sort(([a], [b]) => a - b); return 10000 * a[1] + 100 * b[1] + c[1]; }
javascript
function solution(rank, att) { return Object.entries(rank) .filter((_, i) => att[i]) .sort(([,a], [,b]) => a-b) .slice(0, 3) .reduce((a, [b], j)=> a + b*(100**(2-j)), 0) }

117. 그림 확대

그림 확대는 문제를 읽고 바로 2중 for문이 생각났고, 이렇게 풀었다:

javascript
function solution(picture, k) { for(let i = 0; i < picture.length; i++){ picture[i] = [...picture[i]].map(l => l.repeat(k)).join("") } const answer = []; for(let i = 0; i < picture.length; i++){ for(let j = 0; j < k; j++){ answer.push(picture[i]) } } return answer; }

117-1. flatMap을 활용해 한 번에 풀기

Array(k).fill(...)로 세로 복제, ch.repeat(k)로 한 문자를 가로로 확장하는 방법이 있다. 그리고 이렇게 복제된 k줄을 flatten하는 flatMap으로 감싼다.

javascript
function solution(picture, k) { return picture.flatMap(line => Array(k).fill([...line].map(ch => ch.repeat(k)).join("")) ); }

이렇게도 푼 풀이가 있다. reduce를 통해 오히려 개별 픽셀 길이를 늘리는(!) 것이다.

javascript
function solution(picture, k) { const expandPixels = (pixels, k) => [...pixels].reduce((prev, curr) => prev + curr.repeat(k), ''); return picture.flatMap((pixels) => { const expandedPixels = expandPixels(pixels, k); return new Array(k).fill(expandedPixels); }); }

121. 정수를 나선형으로 배치하기

이 문제는 프로그래머스 lv.0에서 가장 정답률이 낮은 문제다. 실제로 풀면서도 가장 어렵다고 느꼈다.

방향 전환이 늘 오른쪽 -> 아래 -> 왼쪽 -> 위인 것을 감안해서, 행과 열이 일정 값을 넘어가거나 기존 입력값 쪽으로 가면 방향을 틀라는 식으로 코드를 작성했다.

javascript
function solution(n) { const answer = Array.from({length: n}, () => Array(n).fill(0)) const dx = [0, 1, 0, -1]; // 오른쪽, 아래, 왼쪽, 위 const dy = [1, 0, -1, 0]; let x = 0, y = 0, dir = 0; for(let i = 1; i <= n ** 2; i++){ answer[x][y] = i; let nx = x + dx[dir]; let ny = y + dy[dir]; if(nx < 0 || ny < 0 || nx >= n || ny >= n || answer[nx][ny] !== 0){ dir = (dir + 1) % 4; nx = x + dx[dir]; ny = y + dy[dir]; } x = nx; y = ny; } return answer; }

121-1. 각 방향마다 다른 행동 부여하기

각 방향마다 다른 행동을 부여하고, 행 또는 열이 종점에 다다르면 다음 방향을 지시하는 풀이가 멋지다고 생각했다.

javascript
function solution(n) { let ans = Array.from({length:n},()=>[]); let rowMin = 1, rowMax = n-1; let colMin = 0, colMax = n-1; let row = col = 0; let dir = 'r'; for (let i = 1; i <= n*n; i++) { ans[row][col]=i; if (dir === 'r') if (col === colMax) colMax--,row++,dir = 'b'; else col++; else if (dir === 'l') if (col === colMin) colMin++,row--,dir = 't'; else col--; else if (dir === 'b') if (row === rowMax) rowMax--, col--, dir = 'l'; else row++; else if (dir === 't') if (row === rowMin) rowMin++, col++, dir = 'r'; else row--; } return ans; }

121-2. 배열 안에 정확히 어디로 움직여야 하는지 두고 지시

내 풀이와 크게 다를 것은 없지만 좀 더 가독성이 좋다고 느꼈다.

javascript
function solution(n) { const move = [[0, 1], [1, 0], [0, -1], [-1, 0]]; const answer = Array.from(new Array(n), () => new Array(n).fill(0)) let x = 0, y = 0, dir = 0, num = 1; while(num <= n * n) { answer[x][y] = num; let nextX = x + move[dir][0]; let nextY = y + move[dir][1]; if (nextX >= n || nextX < 0 || nextY >= n || nextY < 0 || answer[nextX][nextY] !== 0) { dir = (dir + 1) % 4; nextX = x + move[dir][0]; nextY = y + move[dir][1]; } x = nextX; y = nextY; num ++; } return answer; }

124. 이차원 배열 대각선 순회하기

이 문제는 나는 2중 for문으로 풀었으나 한번의 루프로 푼 답이 있어 기억하고자 남긴다. 나는 이렇게 풀었다:

javascript
function solution(board, k) { const answer = []; for(let i = 0; i < board.length; i++){ for(let j = 0; j < board[0].length; j++){ if(i + j <= k){ answer.push(board[i][j]) } } } return answer.reduce((acc, cur) => acc += +cur, 0) }

124-1. 이중 reduce

2중 reduce도 있다.

javascript
function solution(board, k) { return board.reduce( (total, row, i) => total + row.reduce((prev, num, j) => (i + j <= k ? prev + num : prev), 0), 0, ); }

이렇게 lv.0 문제(정확히는, 코딩 기초 트레이닝 문제)를 모두 풀었다. 문자열과 배열 등의 메소드들을 연습해볼 수 있는 좋은 기회였고, 상위 레벨 알고리즘을 푸는데 도움이 될 경험이었다.