728x90

https://school.programmers.co.kr/learn/courses/30/lessons/150368?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

function solution(users, emoticons) {
    let answer = [0, 0];

    function discountCombinations(discounts, numProducts) {
    
        function generateCombo(currentCombo, depth) {
            if (depth === numProducts) {
                let plus = 0, sell = 0; //플러스 가입자수, 총 판매금액 
                
                //reduce를 사용해 이모티콘 총 구매금액을 계산 
                for (let user of users) {
                    let total = emoticons.reduce((sum, price, c) => 
                        sum + (currentCombo[c] >= user[0] ? price * (1 - currentCombo                         [c] * 0.01) : 0), 0
                    );
                    //총 구매한 금액이 목표금액보다 비싼경우 구매를 취소하고 플러스 가입 
                    if (total >= user[1]) plus++;
                    else sell += total;
                }
                //그 경우의 수 마다 max값을 비교해서 최적의 결과를 answer에 넣어줌 
                if (plus > answer[0] || (plus === answer[0] && sell > answer[1])) {
                    answer = [plus, sell];
                }
                return;
            }
            //재귀
            for (let discount of discounts) {
                generateCombo([...currentCombo, discount], depth + 1);
            }
        }
        generateCombo([], 0);
        
    }

    discountCombinations([10, 20, 30, 40], emoticons.length);
    return answer;
}

 

재귀함수를 사용해서 각 이모티콘별로 할인되는 모든 경우의 수를 구하고, 그 경우의 수 중 max 값을 찾는 

무식한 방법을 사용했다 ㅎㅎ ... 

이모티콘의 갯수가 많지 않고 할인은 10 20 30 40 단 네가지의 경우의 수만 존재하기때문에 가능했던 풀이 

728x90

 

https://school.programmers.co.kr/learn/courses/30/lessons/132265

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

function solution(topping) {
    var answer = 0;
    let chul = new Map();
    topping.forEach((f)=>{
        if(chul.get(f)) chul.set(f,chul.get(f)+1);
        else chul.set(f,1);
    })
   
    let dong = new Set();
    for(let i =0; i<topping.length; i++){
        dong.add(topping[i]);
        if(chul.get(topping[i])){
            if(chul.get(topping[i])>1) chul.set(topping[i],chul.get(topping[i])-1);
            else chul.delete(topping[i])
        }
        if(chul.size ==dong.size){
            
           answer++;
            
        }
    }
    return answer;
}

 

처음에는 양쪽 다 set을 써서 풀려고 했는데

생각해보니 양쪽 다 동일한 토핑을 갖게되는 경우도 있어서 한쪽은 map을 써야한다는걸 알게되었다... 

set과 map을 써봤으면 간단히 풀 수 있는 문제군 

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/12909

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 
 

function solution(s){
    var answer = true;
    var stack = [];
    
    for(i of s){
        if(i==="(") stack.push(i);
        else{
            if(stack===0)return false;
            else stack.pop(); //stack에는 (만 들어가기때문
        }
    }
    

    return stack.length===0;
}

 
처음엔 스택의 LIFO 개념을 생각해서 push pop을 이용해 이렇게 작성했다. 
그러나 2,6번 케이스에서 오답이 나와서 반례를 찾아헤맸다.....
 
근데 완전 바보짓이었음 헤헷 
stack === 0 이라고 써놔서 오답이 뜬거였다.
 

function solution(s){
    var answer = true;
    var stack = [];
    
    for(i of s){
        if(i==="(") stack.push(i);
        else{
            if(stack.length===0)return false;
            else stack.pop(); //stack에는 (만 들어가기때문
        }
    }
    

    return stack.length===0;
}

 
이렇게 풀면 된다 ~.~ 요즘 스택에대해 공부중이어서 냅다 풀어본 문제 

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/12945#qna

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 
피보나치 수 % 1234567의 나머지를 구하면 되는 매우 간단한 문제라고 생각했다. 
 

function solution(n) {
    var answer = 0;
   const fibo = (x,y,cnt)=>{
         if(cnt<=n){
             y =y%1234567;
             return fibo(y,x+y,cnt+1);
         }
         else return y;
     }
    
 
    return fibo(0,1,2);
}

 
처음에는 피보나치라는 단어를 보자마자 아무생각없이 재귀함수를 작성했는데,
 
자연수 n은 n<=100,000이라는 조건으로 인해
 
n번째 피보나치 수가 int의 자료구조 범위를 벗어나는 정수 오버플로우(integer overflow)가 발생했다. 
재귀함수도 마찬가지로, 너무 잦은 재귀함수 호출로 인해 스택 오버플로우가 발생한 것 
 
2단계 문제 치고 너무 쉽다 했어 ~.~
 
 

function solution(n) {
    var answer = 0;
    let x = 0;
    let y = 1;

    
    for(let i=1; i<n; i++){
        let temp = x;
        x = y;
        y = (y+temp)%1234567;
        
    }
    return y;
}

최종 답은 이것 
 
중간중간 나머지 계산을 해주고, 재귀함수 대신 반복문을 사용하는 것으로 문제를 해결했다.

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/70129

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

function solution(s) {
    let cnt=0;
    let answer = s;
    let zero = 0;
    
    while(answer!=='1'){
        let findZero = answer.split('0').length - 1
        let editNum = answer.replaceAll("0",'');
        answer = editNum.length.toString(2);
     
        cnt++;
        zero+=findZero;
    }
    return [cnt,zero];
}

 

javascript의 여러 메서드들을 연습해볼 수 있는 문제군 ~.~

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/340213?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

처음에는 이렇게 풀었다. 

 

function solution(video_len, pos, op_start, op_end, commands) {
    var answer = '';
    const [min, sec] = pos.split(":").map(Number); 
    const [vmin,vsec]= video_len.split(":").map(Number); 
    const [smin,ssec]=op_start.split(":").map(Number); 
    const [emin,esec]=op_end.split(":").map(Number); 
    let [nmin,nsec] = [min,sec];
    const converter = (min,sec)=>min*60+sec;
    for(cmd of commands){        
        if(cmd==="next"){
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
                nsec += 10;
                if (nsec >= 60) {
                    nsec -= 60;
                    nmin += 1;
                }
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
        }else{
           if (nmin == 0 && nsec < 10) { 
                [nmin,nsec]=[0,0];
            } 
            else if(nsec<10){
                nsec = 60+nsec-10;
                nmin -=1;
            }else nsec = nsec-10;
        }
     
    }
    return nmin.toString().padStart(2, '0')+":"+nsec.toString().padStart(2, '0');
}

 

1,6,7,9,12  총 5개의 케이스에서 틀렸다고 나왔다. 

 

어떤 케이스가 고려되지 않았는지 모르겠어서 질문 게시판을 찾아보니

동영상 길이보다 길어지는 경우를 고려해야 한다고 나와있었다!!!

 

애초에 props로 동영상 길이를 왜 제공해주는지 생각했어야 했는데....ㅎㅎ 나의 실수 

 

그래서 중간에 

 if(converter(vmin,vsec)<=converter(nmin,nsec)) [nmin,nsec]=[vmin,vsec];

이 부분을 추가해 주었는데 어라라 아직도 1번케이스가 통과가 되지 않는 것이었다. 

 

다시 찾아보니 prev 명령어의 경우에도 오프닝 구간안에 있으면 오프닝 끝으로 이동해야한다는 것이었다.........헉 

function solution(video_len, pos, op_start, op_end, commands) {
    var answer = '';
    const [min, sec] = pos.split(":").map(Number); 
    const [vmin,vsec]= video_len.split(":").map(Number); 
    const [smin,ssec]=op_start.split(":").map(Number); 
    const [emin,esec]=op_end.split(":").map(Number); 
    let [nmin,nsec] = [min,sec];
    const converter = (min,sec)=>min*60+sec;
    for(cmd of commands){        
        if(cmd==="next"){
            if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)) 
               [nmin,nsec]=[emin,esec];
            
                nsec += 10;
                if (nsec >= 60) {
                    nsec -= 60;
                    nmin += 1;
                }
            if(converter(vmin,vsec)<=converter(nmin,nsec)) [nmin,nsec]=[vmin,vsec];
            else if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)){ 
               [nmin,nsec]=[emin,esec];
            }
        }else{
           if (nmin == 0 && nsec < 10) { 
                [nmin,nsec]=[0,0];
            } 
            else if(nsec<10){
                nsec = 60+nsec-10;
                nmin -=1;
            }else nsec = nsec-10;
            
             if(converter(nmin,nsec)>=converter(smin,ssec)&&converter(nmin,nsec)<=converter(emin,esec)) 
               [nmin,nsec]=[emin,esec]; //여기 이부분을 추가함 
        }
     
    }
    return nmin.toString().padStart(2, '0')+":"+nsec.toString().padStart(2, '0');
}

 

오프닝 구간인지 확인하는 조건문을 prev 에서도 넣어주니 

간단하게 해결이 되었다. ㅎㅎ 

난이도 1이라 시간제한이 빡센 문제는 아닌 듯 하다 

 

끝 ~.~

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/176962#qna

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

function solution(plans) {
  var answer = [];
  var notFinish = [];

  let plan = plans.sort((a, b) => {
    const [aHours, aMinutes] = a[1].split(':').map(Number);
    const [bHours, bMinutes] = b[1].split(':').map(Number);
    return aHours * 60 + aMinutes - (bHours * 60 + bMinutes);
  });

  for (let idx = 0; idx < plan.length; idx++) {
    const p = plan[idx];
    const [hours, minutes] = p[1].split(':').map(Number);
    const date = new Date();
    date.setHours(hours, minutes, 0, 0);

    const playTime = parseInt(p[2]) * 60 * 1000;
    date.setTime(date.getTime() + playTime);

    if (idx + 1 < plan.length) {
      const [nextHours, nextMinutes] = plan[idx + 1][1].split(':').map(Number);
      const nextDate = new Date();
      nextDate.setHours(nextHours, nextMinutes, 0, 0); 

      if (nextDate < date) {
      
        notFinish.push([p[0], (date - nextDate) / (60 * 1000)]); 
      } else {
        answer.push(p[0]);

      
        let remainingTime = (nextDate - date) / (60 * 1000); 
        while (notFinish.length > 0 && remainingTime > 0) {
          const [task, timeLeft] = notFinish.pop(); 
          if (remainingTime >= timeLeft) {
            answer.push(task);
            remainingTime -= timeLeft;
          } else {
            notFinish.push([task, timeLeft - remainingTime]);
            break;
          }
        }
      }
    } else {
      answer.push(p[0]); 

      while (notFinish.length > 0) {
        answer.push(notFinish.pop()[0]);
      }
    }
  }

  return answer;
}

조건문지옥....................... 

 

스택을 활용해서 풀면 된다 

물론 자바스크립트는 스택이나 큐를 제공하지 않기 때문에 shift push pop 을 적절히 사용해서 배열을 스택처럼 써야한다. 

 

 

오답노트 : 

 

다음 과제 시작 전에 미뤄둔 과제를 처리해줘야하는데

미뤄둔 과제 리스트중에 첫번째 과제가 40분이고 다음 과제까지 남은시간이 20분이다

그러면 20분이라도 했다고 처리해줘야 문제가 해결되는거였음

 

처음에 풀때

남은시간은 20분인데 40분짜리 과제? 절대못하죠.  이러고 넘어가버려서 절반이 오류케이스로 나왔었다 

테스트케이스에 이런경우도 같이 고려해서 넣어주면 좋겠음. 설명이 부족한 문제인듯 

728x90

https://school.programmers.co.kr/learn/courses/30/lessons/160586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

function solution(keymap, targets) {
    var answer = [];
    var map = new Map();
    keymap.forEach((keys) => {
    for (let idx = 0; idx < keys.length; idx++) {
      let k = keys[idx];
      if (!map.has(k)) {
        map.set(k, idx + 1);
      } else {
        if (map.get(k) > idx + 1) {
          map.set(k, idx + 1);
        }
      }
    }
  });
    
    targets.forEach((t) => {
    let ans = 0;

    for (let i = 0; i < t.length; i++) {
      if (!map.has(t[i])) {
        ans = -1;
        break;
      } else {
        ans += map.get(t[i]); 
      }
    }

    answer.push(ans); 
  });
    return answer;
}

 

keymap으로 넘어오는 값을 배열로 착각하고 forEach로 풀었더니 초반에 오류가 발생했는데

for 반복문으로 푸니까 바로 해결이 되었다 ㅎㅎ 간단한문제! 

728x90

+ Recent posts