본문 바로가기
👋국비 후기 모음👋 (이력도 확인 가능!)
개발/코테 준비

[JS] 프로그래머스 - 기능개발

by 킴뎁 2022. 2. 20.
728x90
반응형

내 풀이

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 등의 함수를 사용하는 데에 도움이 되는 문제였다.

 

https://programmers.co.kr/learn/courses/30/lessons/42586

 

코딩테스트 연습 - 기능개발

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는

programmers.co.kr

반응형
👋국비 후기 모음👋 (이력도 확인 가능!)

댓글