내 풀이
function solution(pro, speeds) {
let answer = [];
let day = [];
for (let i = 0; i < pro.length; i++) {
day.push(Math.ceil((100 - pro[i]) / speeds[i]));
}
while (day.length > 0) {
let cnt = 1;
for (let i = 1; i <= day.length; i++) {
if (day[0] >= day[i]) {
cnt++;
continue;
}
answer.push(cnt);
day.splice(0, cnt);
break;
}
}
return answer;
}
해설
처음에 문제 자체를 이해하기가 어려웠다. 아니 일단 문제를 읽기가 너무 귀찮아서 눈에 잘 안 들어왔다. 뭔가 기존에 프로그래머스 2단계를 풀 땐 거의 접근방식을 블로그에서 찾아보고 그걸 코드로 짜는 방식으로 문제를 풀어왔다. 즉, 내 스스로 풀었던 적이 거의 없다. 근데 최근에 푼 프린터와 지금 이 기능개발 문제는 스스로 풀어내서 정말 뿌듯했다. 더 신기한 점은 내 접근방식이 다른 사람 풀이에도 그대로 있었다는 점이다. 항상 '저와 같은 방식으로 풀었네요!' 라는 댓글을 볼 수 있었는데 그게 조금 부러웠는데 막상 경험해보니 신기한 듯..?
뭐 아무튼 해설 시작.
function solution(pro, speeds) { // pro = [ 93, 30, 55 ], speeds = [ 1, 30, 5 ]
let answer = [];
let day = [];
for (let i = 0; i < pro.length; i++) {
day.push(Math.ceil((100 - pro[i]) / speeds[i]));
}
console.log(day); // [ 7, 3, 9 ]
...
return answer;
}
우선 각 작업마다 얼마나 걸리는지를 알아야한다.
첫 번째 예로 설명하자면 93%까지 작업이 완료되어 있고 하루에 1%씩 가능하므로 100%가 되기까지 7일이 걸린다.
여기서 이 7일을 구하는 공식을 적어본다.
남은 작업량 / 작업의 개발 속도 의 올림처리를 하면 구해진다.
Math.ceil((100-progress) / speed) -> Math.ceil() 올림 함수.
-> ex) 작업이 30% 진행되었고 속도가 30일 경우
-> (100 - 30) / 30 = 2.333333
-> Math.ceil(2.333333) = 3
->. 3일째에 배포가능.
line5에 언제부터 배포가 가능한 지를 day배열에 담아준다.
function solution(pro, speeds) {
...
console.log(day); // [ 7, 3, 9 ]
while (day.length > 0) {
let cnt = 1;
for (let i = 1; i <= day.length; i++) {
if (day[0] >= day[i]) {
cnt++;
continue;
}
answer.push(cnt);
day.splice(0, cnt);
break;
}
}
return answer;
}
day의 다른 요소들과 첫 번째 요소를 비교해야한다.
비교는 앞에서 부터 차근차근 해가면서 첫번째 요소보다 큰 요소가 나오기 전까지는 한 번에 배포하면 된다.
day = [ 7, 3, 9 ] 이므로 7, 3을 한 번에 배포한 후 9를 배포하면 된다.
- line 7 - day가 0이 될 때까지 반복.
- line 8 - 몇 개를 동시에 배포할 지의 대한 변수. 기본으로 한 개는 배포하므로 초기화는 1
- line 9 - i = 1로 초기화. 첫번째 요소와 비교대상은 나머지 요소이므로 자기 자신은 제외.
- line 10~13 - 첫번째 요소가 비교 요소보다 같거나 크면 한 번에 배포할 것이므로 cnt++후 continue;
- line 14 - 비교 요소가 첫번째 요소보다 클 경우 cnt를 answer에 push.
- line 15 - day.splice(0, cnt) -> day의 0번째 요소부터 cnt만큼 삭제한다. (배포 완료)
- line 16 - day의 요소들이 삭제되었으므로 break를 해서 다시 while로 돌아간다.
- 위와 동일한 메커니즘 반복 후 return answer;
다른 사람의 풀이
function solution(progresses, speeds) {
let answer = [0];
let days = progresses.map((progress, index) => Math.ceil((100 - progress) / speeds[index]));
let maxDay = days[0];
for(let i = 0, j = 0; i< days.length; i++){
if(days[i] <= maxDay) {
answer[j] += 1;
} else {
maxDay = days[i];
answer[++j] = 1;
}
}
return answer;
}
이 사람도 결국 day를 구하고 비교하는 방식으로 풀어갔다. 나는 day를 만들 때 for문으로 돌렸는데 이 코드는 map을 사용해서 코드를 간결하게 했다. 분명히 map을 공부했고 사용 방법도 알아서 코드를 이해하는 데에는 어려움이 없었지만 아쉬운 점은 내가 코드를 짤 때 map을 활용할 생각을 하지 못했다는 점이다. 사용 방법을 아는 것은 공부로 할 수 있지만 그걸 언제 사용할까에 대한 센스는 앞으로 더 많은 문제를 접하면서 연습을 해야할 것이다.
설명이 잘 되었을지는 모르겠다. 프린터나 기능개발이나 둘 다 스택/큐 관련 문제라 푸는 방식이 비슷했다. 일단 규칙을 찾으면 그의 맞게 코드를 작성하면 되는 문제였다. 배열의 앞이나 뒤의 요소를 잘 추가하거나 빼면 된다. push, pop, shift, splice 등의 함수를 사용하는 데에 도움이 되는 문제였다.
'개발 > 코테 준비' 카테고리의 다른 글
[JS] 프로그래머스 - 프린터 (2) | 2022.02.17 |
---|---|
[JS] 프로그래머스 - 위장 (0) | 2022.02.13 |
[java] 프로그래머스 - 문자열 내 마음대로 정렬하기 (0) | 2021.12.10 |
자바 백준 1929 - 소수 구하기 (에라토스테네스의 체) (0) | 2021.10.31 |
자바 백준 1193 - 분수찾기 (설명 포함) (0) | 2021.10.26 |
댓글