-
[프로그래머스] 1106 오늘의 문제 풀이Algorithm 2020. 11. 6. 15:43반응형
예전에 풀어봤던 문제들인데, 알고리즘 감을 되살리기 위해 다시 한 번 풀어보는 중.
사실 예전에 풀어봤다는 게 별 의미가 없는 것 같다.
너무 오래돼서, 내가 어떻게 풀었는지 기억이 하나도 안나기 때문에.
1. 실패율
function solution(N, stages) { let Nstages = new Array(N + 1).fill(0); const current = new Array(N + 1).fill(0); for(let i = 0; i < stages.length; i++) { for(let j = 0; j <= stages[i] - 1; j++) { Nstages[j]++; if(j === stages[i] - 1) current[j]++; } } Nstages = Nstages.slice(0, N); for(let i = 0; i < N; i++) { if(Nstages[i] === 0) { Nstages[i] = 0; } else { Nstages[i] = current[i] / Nstages[i]; } } const result = new Array(N); for(let i = 0; i < result.length; i++) { result[i] = i + 1; } return result.sort((a, b) => { if(Nstages[a - 1] === Nstages[b - 1]) { return a - b; } else { if(Nstages[a - 1] > Nstages[b - 1]) { return b - a; } else { return a - b; } } }); }
상당히 구구절절하지만 생각보다 속도가 빠르게 나와서 뿌듯.
2. 비밀지도
a. 혼자서 풀기
function solution(n, arr1, arr2) { const arr1_after = arr1.map(num => { let q = num, r, result = ''; while(q > 1) { r = q % 2; q = (q / 2) >> 0; result = r + result; } return (q + result).padStart(n, '0'); }); const arr2_after = arr2.map(num => { let q = num, r, result = ''; while(q > 1) { r = q % 2; q = (q / 2) >> 0; result = r + result; } return (q + result).padStart(n, '0'); }); return arr1_after.map((binary, idx) => { let str = ''; for(let i = 0; i < binary.length; i++) { if(binary[i] === '1' || arr2_after[idx][i] === '1') { str += '#'; } else { str += ' '; } } return str; }); }
b. 다른 사람의 풀이
function solution(n, arr1, arr2) { return arr1.map((bin, idx) => { return (bin | arr2[idx]).toString(2).padStart(n, '0').replace(/1|0/g, a => +a ? '#' : ' '); }); }
1. 십진수의 숫자를 논리연산 시키면 2진수로 변환해서 계산된다. 물론 결과는 십진수로 다시 변환되어 나온다.
2. Number.toString(n)을 해주면, Number가 n진수 숫자 형태의 문자열로 변환된다.
3. replace(/1|0/g, a =>+a ? '#' : ' ')
만약 a가 '1'이라면 +a는 숫자 1이므로 조건문에 들어갔을 때 true를 return한다.
반면, a가 '0'이라면 +a는 숫자 0이므로 조건문에 들어갔을 때 false를 return한다.
당연히 알고 있는 내용이었지만, 이렇게 똑똑하게 사용될 줄은 몰랐다.
3. 다트게임
a. 혼자서 풀기
function solution(dartResult) { let score = []; const strings = dartResult.match(/([0-9]{1,})([SDT])([*#]{0,1})/g); for(let i = 0; i < strings.length; i++) { let currentScore = 0; const digit = +strings[i].match(/[0-9]{1,}/g)[0]; const bonus = strings[i].match(/[SDT]/g)[0]; let option = strings[i].match(/[*#]/g); if(option) option = option[0]; if(bonus === 'S') currentScore += digit; else if(bonus === 'D') currentScore += Math.pow(digit, 2); else if(bonus === 'T') currentScore += Math.pow(digit, 3); if(option) { if(option === '*') { if(i - 1 >= 0) { score[i - 1] = score[i - 1] * 2; } currentScore = currentScore * 2; } else if(option === '#') { currentScore = currentScore * -1; } } score[i] = currentScore; } return score.reduce((prev, cur) => prev + cur, 0); }
이 문제는 사실 이전에 정규표현식으로 풀었던 게 기억이 나서 풀 수 있었다.
b. 다른 사람의 풀이
function solution(dartResult) { let answer = 0; let numArr = []; for (let i = 0; i < dartResult.length; i = i + 2){ let point; // 10인 경우와 아닌 경우로 분리 if(i + 1 < dartResult.length && dartResult[i + 1] === '0'){ point = 10; i++; } else { point = parseInt(dartResult[i]); } const bonus = dartResult[i+1]; // D면 제곱, T 면 세제곱 if(bonus === 'D'){ point *= point; } else if(bonus === 'T'){ point *= point * point; } // * 이면 현재 값과 이전값 2배, #이면 현재값 -1 if(i + 2 < dartResult.length && dartResult[i + 2] === '*'){ point *= 2; if(numArr.length !== 0){ numArr[numArr.length - 1] *= 2; } i++; } else if(i + 2 < dartResult.length && dartResult[i + 2] === '#'){ point *= -1; i++; } numArr.push(point); } for (let i = 0; i < numArr.length; i++){ answer += numArr[i]; } return answer; }
정규표현식을 사용하지 않은 풀이이다.
10점인 경우는 어떻게 처리해야되나 고민이 많았는데, 그냥 i를 1 더해주면 되는 거였네.
둘러봤던 코드들 중에 가장 보기가 편하고 이해가 잘되는 코드라서 가져와봤다.
너무 어렵게 생각해서 오히려 꼬여버린 문제.
출처
4. 예산
function solution(d, budget) { let answer = 0; const department = d.slice(); department.sort((a, b) => a - b).reduce((acc, cur, idx) => { if(acc + cur <= budget) { answer = idx + 1; return acc + cur; } else { return acc; } }, 0); return answer; }
5. 키패드 누르기
function solution(numbers, hand) { let answer = ''; let leftThumb = 10, rightThumb = 12; for(let i = 0; i < numbers.length; i++) { let curNum = numbers[i]; if(curNum === 1 || curNum === 4 || curNum === 7) { /* 왼쪽인 경우 */ answer += 'L'; leftThumb = curNum; } else if(curNum === 3 || curNum === 6 || curNum === 9) { /* 오른쪽인 경우 */ answer += 'R'; rightThumb = curNum; } else { /* 중간인 경우 */ if(curNum === 0) curNum = 11; let leftDistance = 100, rightDistance = 100; leftDistance = Math.abs(leftThumb - curNum); rightDistance = Math.abs(rightThumb - curNum); leftDistance = (leftDistance % 3) + Math.floor(leftDistance / 3); rightDistance = (rightDistance % 3) + Math.floor(rightDistance / 3); if(leftDistance === rightDistance) { if(hand === 'right') { answer += 'R'; rightThumb = curNum; } else { answer += 'L'; leftThumb = curNum; } } else if(leftDistance > rightDistance) { answer += 'R'; rightThumb = curNum; } else { answer += 'L'; leftThumb = curNum; } } } return answer; }
요거는 내가 카카오 인턴십 지원했을 때 직접 풀었던 문제다.
그때는 너무 긴장을 해서, 아무것도 생각이 안났는데
시간이 지나고 오늘 다시 풀어보기 규칙이 눈에 보였다.
항상 문제에서 규칙을 발견하는 게 제일 중요한듯.
한 줄에 3개씩 놓여 있으니까, 키패드 사이의 거리(절대값)를 3으로 나눴을 때몫이 세로로 움직이는 양이고, 나머지가 가로로 움직이는 양이었다.이렇게 간단한 규칙을 단순히 긴장때문에 못 찾았다니.
일단, 모든 알고리즘 문제들이
문제를 내기 위해 만들어진 문제이니만큼
틀림없이 규칙을 가지고 있다는 마인드로,
눈에 불을 밝히고 규칙을 찾을 수 있도록 해야겠다.
6. 두 개 뽑아서 더하기
a. 혼자서 풀기
function solution(numbers) { var answer = []; for(let i = 0; i < numbers.length - 1; i++) { for(let j = i + 1; j < numbers.length; j++) { const cur = numbers[i] + numbers[j]; if(answer.indexOf(cur) === -1) { answer.push(cur); } } } return answer.sort((a, b) => a - b); }
b. 다른 사람의 풀이
function solution(numbers) { const temp = []; for (let i = 0; i < numbers.length; i++) { for (let j = i + 1; j < numbers.length; j++) { temp.push(numbers[i] + numbers[j]); } } const answer = [...new Set(temp)]; return answer.sort((a, b) => a - b); }
사실, indexOf도 반복문이기 때문에 내 풀이는 3중 반복문이나 마찬가지이다.
이 사람은 반복문과 조건문을 사용하지 않고, set을 이용하여 현명하게 중복을 없앴다.
spread operator는 덤으로.
반응형'Algorithm' 카테고리의 다른 글
[백준] 0927 오늘의 문제 풀이📚 (0) 2020.09.27 [백준] 0926 오늘의 문제 풀이📚 (0) 2020.09.26 [백준] 0925 오늘의 문제 풀이📚 (0) 2020.09.26 [백준] 0924 오늘의 문제 풀이📚 (0) 2020.09.25 [백준] 0923 오늘의 문제 풀이📚 (0) 2020.09.25