728x90
반응형

2021.09.17

문제명 : 2020 KAKAO BLIND RECRUITMENT 괄호 변환

사용언어 : Javascript

개발 시간 : 120분

 

📋 문제 설명

  • 균형잡힌 괄호 문자열 = '(' 의 개수와 ')' 의 개수가 같은 경우     
  •   올바른  괄호 문자열 = '('와 ')'의 괄호의 짝도 모두 맞을 경우  

예 : (()))(  →  균형잡힌 괄호 문자열

예 : (())()  →  균형잡힌 괄호 문자열, 올바른 괄호 문자열

 

 

📢 입출력 예

새로운 예로 ' )()()()( ' 를 들어보겠습니다

 

주어진 단계를 순차적으로 따라가면 빨간색으로 표시한 부분을 모두 연결한 ' (((()))) ' 이 됩니다

 

 

 

 

🔑 문제 풀이

function solution(p) {
    var answer = '';
    
    answer = revision(p);
    
    return answer;
}

function revision(str){
    var res = '';
    var u = '';
    var v = '';
    var left = 0;
    var right = 0;
    var check = '';
    
    // 1.
    if(str == ""){
        return "";
    }else{
        // 2.
        for(var i=0; i<str.length; i++){
            if(str[i] == '('){
                left++;
            }else if(str[i] == ')'){
                right++;
            }
        
            if(left == right){
                u = str.substring(0,i+1);
                v = str.substring(i+1);
                break;
            }
        }
        
        // 3.
        check = right_check(u);
  
        if(check == 'T'){
            // 3-1.
            u += revision(v);
            
            return u;
        }else if(check == 'F'){  // 4.
            // 4-1.
            res += '(';
            // 4-2.
            res += revision(v);
            // 4-3.
            res += ')';
            // 4-4.
            u = u.substring(1,u.length-1);
            
            var r = '';
            for(var i=0;i<u.length;i++){
                if(u[i] == '('){
                    r += ')';
                }else{
                    r += '(';
                }
            }
            res += r;
            
            return res;
        }
    }
}


// 올바른 괄호 문자열인지 확인
function right_check(s){

    for(var j=0; j<s.length; j++){

        if(s == '()'){
            return 'T';
        }else{
        
            if(s[0] == ')'){
                return 'F';
            }else{
                if(s[j] == ')'){
                    s = s.substring(0,j-1) + s.substring(j+1);

                    if(s.length == 2){

                        if(s == ')('){    // 올바르지 않음
                            return 'F';
                        }else if(s == '()'){   // 올바름
                            return "T";
                        }
                    }else{
                        return right_check(s);
                    }
                }
            }
        }
    }
  
}

 

 

🔔 새로 알게 된 점

끝없는 재귀 함수의 연속이었다..

이미 1~4단계까지 주어진 로직이 있어서 따라가기만 하면 됐다

다음번엔 시간을 단축시켜서 풀 수 있도록 해야겠다

728x90
반응형
728x90
반응형

2021.08.20

문제명 : 연습문제 - 서울에서 김서방 찾기

사용언어 : Kotiln

개발 시간 : 10분

 

 

코딩테스트 연습 - 서울에서 김서방 찾기

String형 배열 seoul의 element중 "Kim"의 위치 x를 찾아, "김서방은 x에 있다"는 String을 반환하는 함수, solution을 완성하세요. seoul에 "Kim"은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니

programmers.co.kr

 

📋 문제 설명

'Kim'이 들어있는 인덱스 구하는 문제입니다

 

🔑 문제 풀이

class Solution {
    fun solution(seoul: Array<String>): String {
        var answer = ""
        
        // 1.
        seoul.forEachIndexed{ index, value ->
            if(value == "Kim"){
                answer = "김서방은 ${index}에 있다"
            }
        }
        
        // 2.
        for(i in seoul.indices) {
            if(seoul[i].equals("Kim")) answer = "김서방은 ${i}에 있다"
        }        
        
        return answer
    }
}

 

🔔 새로 알게 된 점

// 값

for(i in seoul){

  println(i)     

}

Jane
Kim

 

// 인덱스

for(i in seoul.indices){

  println(i)     

}

0
1

 

728x90
반응형
728x90
반응형

 

2021.08.17

문제명 : 2021 KAKAO BLIND RECRUITMENT 순위 검색

사용언어 : Javascript

개발 시간 : 120분 + 다른 사람 풀이 60분

 

 

코딩테스트 연습 - 순위 검색

["java backend junior pizza 150","python frontend senior chicken 210","python frontend senior chicken 150","cpp backend senior pizza 260","java backend junior chicken 80","python backend senior chicken 50"] ["java and backend and junior and pizza 100","pyt

programmers.co.kr

 

📋 문제 설명

이 문제의 핵심은 조합이분탐색입니다.

주어진 info 배열이 가질 수 있는 조합을 모두 구하고

이분탐색을 이용해 query 배열의 조건에 맞는 갯수를 구하는 것입니다.

 


이분 탐색의 간단한 예시를 먼저 보고 갑시다.

 

1 2 3 4 5 6라는 값에서 6을 찾고자 한다면

 

배열의 중간에 위치한 3이라는 값과 6을 비교합니다.

 

6은 3보다 크므로, 이제 3의 왼쪽에 위치하는 값들은 탐색할 필요가 없으므로

(어차피 3 왼쪽에 있는 수들은 3보다 작기 때문입니다)

 

3의 오른쪽에 있는 값들을 대상으로 탐색을 다시 시도합니다.

 

이제 4 5 6이 남았으므로, 다시 중간값인 5와 찾고자 하는 대상인 6를 비교합니다.

 

6은 5보다 크므로, 5의 오른쪽에 있는 값들을 대상으로만 탐색을 다시 시도합니다.

 

이제 6만이 남았는데 6과 6을 비교하면, 값이 일치하므로 탐색을 종료합니다.


출처: https://satisfactoryplace.tistory.com/39

 


 

우선 조합을 통해서 - 를 다 넣어줍니다.

 

예를 들어, 

java backend junior pizza 150 이 입력으로 들어왔다고 칩시다. 

 

- backend junior pizza 150

java   -  junior pizza 150

java backend - pizza 150

java backend junior - 150

.

.

.

- - - - 150 

이런식으로 -를 넣을 수 있는 곳을 조합으로 찾아 모두다 150을 넣어줍니다.

 

출처 : https://dkwjdi.tistory.com/224


 

📢 입출력 예

 

🔑 문제 풀이

// 정확성 테스트 success
// 효율성 테스트 success
function solution(info, query) {
    var answer = [];
    let map = {};
    
    function combination(infos, score, map, start){
        let key = infos.join("");  // 키 값으로 쓸거 합쳐주기
        let value = map[key];      // 값 있는지 없는지 확인해주기
    
        if(value){ // 값이 있으면 push
            map[key].push(score);
        }else{ // 값이 없으면 프로퍼티 만들어주기
            map[key] = [score];
        }
        
        // -를 이용해 조합 만들기
        for(let i=start; i<infos.length; i++){
            let combiArr = [...infos]; // 전개연산자 ...
            combiArr[i] = '-';
            
            combination(combiArr, score, map, i+1);
        }
    }
    
    
    // 이분탐색
    function binarySearch(map2, key2, score2){
        let scoreArr = map2[key2];
       
        if(scoreArr){
       
            var start = 0;
            var end = scoreArr.length;
            
            while(start < end){
                var mid = Math.floor((start+end)/2);
                
                if(scoreArr[mid] >= score2){ // 현재 가르키는 값보다 내가 찾는 값이
                    end = mid;
                }else if(scoreArr[mid] < score2){
                    start = mid + 1;
                }
            }
            
            return scoreArr.length - start;
        }
        else return 0
        
    }
    
    
    
    // 1. -로 가능한 모든 조합 만들기
    for(let i=0; i<info.length; i++){
        let infos = info[i].split(" ");
        let score = infos.pop();
        
        combination(infos, score, map, 0);
    }
    
    // 2. 이분탐색을 위해 정렬
    for(let key in map){
        map[key].sort((o1, o2) => o1 - o2);
    }
    
    // 3. 이분탐색 실행
    for(let i=0; i<query.length; i++){
        let querys = query[i].replace(/ and /g, "").split(" ");
        let score = Number(querys.pop());
      
        answer.push(binarySearch(map, querys.join(""), score));
    }
    
    return answer;
}

 

// 정확성 테스트 success
// 효율성 테스트 fail
function solution(info, query) {
    var answer = [];
    var arr1 = [];
    var arr2 = [];
    
    for(var i=0; i<info.length; i++){
        arr1.push(info[i].split(' '));
    }
    for(var i=0; i<query.length; i++){
        arr2.push(query[i].replace(/and /gi,'').split(' '));
    }
    
    
    for(var i=0; i<arr2.length; i++){
        var cnt = 0;
        for(var j=0; j<arr1.length; j++){
            for(var k=0; k<4; k++){   
                if(arr2[i][k] == arr1[j][k] || arr2[i][k] == '-'){
                    if(k==3 && arr2[i][4]*1 <= arr1[j][4]*1){
                        cnt++;
                    }
                }else{
                    break;
                }
            }
        }
        answer.push(cnt);
    }
    return answer;
}

 

🔔 새로 알게 된 점

2단계가 맞나 싶을 정도로 난이도가 높게 느껴졌다.

첫 시도때는 점수를 제외한 조건들만 차례대로 비교하면서 충족할 경우에만 점수를 비교하였다.

이렇게 풀면 정답이긴 하나, 효율성 테스트에서 fail이 뜬다.

for문이 중첩되면서 타임아웃 에러가 나는 듯 하다.

 

다른 사람의 풀이를 참조하니 이분탐색을 이용하지 않으면 통과할 수 없는 문제같다.

조합, 이분탐색, 프로퍼티 등을 공부하고 알고리즘을 이해하는 것이 중요할 듯 하다.

 

프로퍼티 관련 : https://opentutorials.org/module/3989/26100

 

 

 

728x90
반응형
728x90
반응형

2021.07.29

문제명 : 2021 카카오 채용연계형 인턴십 - 숫자 문자열과 영단어

사용언어 : Javascript

개발 시간 : 90분 + 5분....

 

 

코딩테스트 연습 - 숫자 문자열과 영단어

네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다. 다음은 숫자의 일부 자

programmers.co.kr

 

📋 문제 설명

이번 문제는 단순한 문제였으나 왜 이렇게 복잡하게 생각을 한건지 시간을 너무 많이 뺏겼었습니다ㅠㅠ...

결국 다음날 다시 풀어보니 5분만에 해결,,, 바보 기매연...ㅠㅠ

주어진 s 문자열 안에서 영단어와 대응되는 부분을 대응하는 숫자로 변경하면 되는 문제입니다

 

📢 입출력 예

 

🔑 문제 풀이

function solution(s) {
    var answer = "";
    var tmp = "";
    var arr = ['zero','one','two','three','four','five','six','seven','eight','nine'];
    
    for(var i=0; i<s.length; i++){
        if(isNaN(s[i]) == false){  // 숫자
            answer += s[i];
        }else{                     // 문자
            tmp += s[i];		   // 임시 보관함 tmp에 문자열 누적
            for(var j=0; j<arr.length; j++){ 
                if(tmp == arr[j]){ // 대응하는 영단어 있을 경우
                    answer += j;
                    tmp = "";
                }
            }
        }
    }
        
    return answer*1;
}

 

🔔 새로 알게 된 점

다른 사람 풀이를 보니 단순히 replace만 반복하여 푼 방법도 있었습니다.

참고하면 좋을 것 같습니다.

그리고 문제가 너무 안풀릴때는 잠시 쉬어가는걸로,,,,

728x90
반응형
728x90
반응형

2021.07.17

문제명 : 2021 KAKAO BLIND RECRUITMENT - 신규 아이디 추천

사용언어 : Javascript

개발 시간 : 50분

 

 

코딩테스트 연습 - 신규 아이디 추천

카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로

programmers.co.kr

 

📋 문제 설명

복잡해보이지만 주어진 규칙을 순서대로 적용해주면 되는 문제입니다.

 

📢 입출력 예

 

🔑 문제 풀이

function solution(new_id) {
    var answer = '';
    
    new_id = new_id.toLowerCase();  // 1. 소문자로 치환
    new_id = new_id.replace(/[^a-z0-9-._]/gi, ''); // 2. 특정문자 외 제거

    // 3단계 : 연속된 . 하나로 치환
    var str = '';
    for(var i=0; i<new_id.length; i++){
        if(new_id[i] == '.' && new_id[i-1] == '.'){
            str += '';
        }else{
            str += new_id[i];
        }    
    }
    new_id = str;
   
    // 4단계 : . 처음 또는 끝일 경우 제거
    new_id = four(new_id);
    
    // 5단계
    if(new_id == '') new_id = 'a';
   
    // 6단계
    if(new_id.length>15) new_id = new_id.substring(0,15);
    new_id = four(new_id);
        
    // 7단계
    new_id = seven(new_id);

    answer = new_id;
    return answer;
}

function four(new_id){
    if(new_id.substring(0,1) == '.') new_id = new_id.slice(1);
    if(new_id.substring(new_id.length-1) == '.') new_id = new_id.substring(0,new_id.length-1);
    
    return new_id;
}

function seven(new_id){
    if(new_id.length < 3){
        new_id = new_id + new_id.substring(new_id.length-1);
        return seven(new_id);
    }else{
        return new_id;
    }
}

 

🔔 새로 알게 된 점

문제가 어렵지는 않았으나 정규식 부분에서 시간이 많이 잡힌 것 같습니다.

/[^a-z0-9-._]/gi 에서

^~ : ~를 제외하고

a-z : a부터 z까지

0-9 : 0부터 9까지

-._ 등등 : 해당 문자열

728x90
반응형
728x90
반응형

2021.06.26

문제명 : 2021 Dev-Matching: 웹 백엔드 개발자(상반기) - 로또의 최고 순위와 최저 순위

사용언어 : Javascript

개발 시간 : 10분

 

 

코딩테스트 연습 - 로또의 최고 순위와 최저 순위

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1 순위 당첨 내용 1 6개 번호가 모두 일치 2 5개 번호

programmers.co.kr

 

📋 문제 설명

초등학교때 수학시간에 자주 등장했던 물을 엎질러 종이가 일부 찢어졌을때 값을 유추하는 문제입니다.

최저 순위 = 보여지는 숫자 안에서 맞은 갯수

최고 순위 = 보여지는 순자 안에서 맞은 갯수 + 안보이는 숫자(0)이 모두 당첨번호라는 가정

 

📢 입출력 예

 

🔑 문제 풀이

function solution(lottos, win_nums) {
    var answer = [];
    var cnt = 0; // 0갯수
    var win = 0; // 맞은 로또 갯수
    
    
    for(var i=0; i<lottos.length; i++){
        if(lottos[i] == 0){
            cnt++;
        }else{
            for(var j=0; j<win_nums.length; j++){
                if(win_nums[j] == lottos[i]){
                    win++;
                }
            }
        }
    }
    
    var min = rank(win);
    var max = rank(win+cnt);
    
    answer = [max,min];
    
    return answer;
}


function rank(win){
    var rank = 0;
    
    if(win == 6) rank = 1;
    else if(win == 5) rank = 2;
    else if(win == 4) rank = 3;
    else if(win == 3) rank = 4;
    else if(win == 2) rank = 5;
    else rank = 6;
    
    return rank;
}
728x90
반응형
728x90
반응형

2021.06.26

문제명 : 2020 카카오 인턴십 - 키패드 누르기

사용언어 : Javascript

개발 시간 : 70분

 

 

코딩테스트 연습 - 키패드 누르기

[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"

programmers.co.kr

 

📋 문제 설명

왼손 시작은 *, 오른손 시작은 #입니다. 

1,4,7은 왼손 3,6,9는 오른손 그 외는 가까운 손이 누릅니다.

만약 거리가 같다면 왼손잡이는 왼손이, 오른손잡이는 오른손이 누릅니다.

 

📢 입출력 예

차근히 따라 하시면 입출력 예는 이해가 될 것입니다.

 

🔑 문제 풀이

키패드의 최하단에  *  0  # → 10  11  12 라고 바꿔서 생각해보았습니다.

그럼 1부터 12까지의 키패드가 됩니다.

(1,4,7)과 (3,6,9)는 각각 왼손, 오른손이 누르기로 정해져 있으므로 가운데 숫자를 누를 때만 생각해봤습니다.

 

⁕ 왼손 시작일 경우

예를 들어, 만약 왼손이 1에 위치하고, 다음 눌러야 할 숫자가 5일 경우를 생각해봅시다.

무조건 오른쪽으로 한 칸은 이동해야 합니다.

그리고, 줄마다의 차이는 3씩이므로 3씩 몇 번 이동해야 하는지를 확인합니다.

1(현재 위치) + 1 + (3 * n번) = 5(도착 위치)

1+n 만큼 이동하는 횟수가 필요합니다. n은 1이므로 총 거리 2만큼 이동합니다.

 

⁕ 오른손 시작일 경우

예를 들어, 만약 오른손이 6에 위치하고, 다음 눌러야 할 숫자가 2일 경우를 생각해봅시다.

무조건 왼쪽으로 한 칸은 이동해야 합니다.

그리고, 줄마다의 차이는 3씩이므로 3씩 몇 번 이동해야 하는지를 확인합니다.

6(현재 위치) - 1 + (3 * n번) = 2(도착 위치)

1+n 만큼 이동하는 횟수가 필요합니다. 

여기서 n은 -1입니다.

6에서 2로 이동하기까지는 2칸이 걸리는 것을 고려해보았을 때, n은 절댓값 처리가 필요할 것으로 예상됩니다.

따라서 1+(|-1|) = 2만큼 이동합니다.

 

 

왼손, 오른손 모두

만약 손가락이 가운데 위치해 있을 때 가운데 숫자를 눌러야 한다면 처음 +1 또는 -1 과정은 생략될 것입니다.

이미 가운데로 이동되어있기 때문입니다.

 

 

이를 코드로 옮겨보면,

function solution(numbers, hand) {
    var answer = '';
    var left = 10;	// *
    var right = 12;	// #
    
    for(var i=0; i<numbers.length; i++){
        if(numbers[i] == 0){ // 0
            numbers[i] = 11;
        }
         
        // 무조건 왼손
        if(numbers[i] == 1 || numbers[i] == 4 || numbers[i] == 7){
            answer += 'L';
            left = numbers[i];
        }
        // 무조건 오른손
        else if(numbers[i] == 3 || numbers[i] == 6 || numbers[i] == 9){
            answer += 'R';
            right = numbers[i];
        }
        // 가까운 손가락, 같다면 잡이를 확인
        else {
            var L = 0; // 현재 왼손이 위치한 숫자 키패드
            var R = 0; // 현재 오른손이 위치한 숫자 키패드
            
            // 왼손이 좌측에 위치해있다면
            if(left == 1 || left == 4 || left == 7 || left == 10){
                L = Math.abs((numbers[i] - (left + 1)) / 3) + 1;
            }
            // 왼손이 가운데 위치해있다면
            else{ // 2 5 8 0(11)
                L = Math.abs((numbers[i] - left) / 3);
            }
            
            // 오른이 좌측에 위치해있다면
            if(right == 3 || right == 6 || right == 9 || right == 12){
                R = Math.abs((numbers[i] - (right - 1)) / 3) + 1;
            }
            // 오른손이 가운데 위치해있다면
            else{ // 2 5 8 0(11)
                R = Math.abs((numbers[i] - right) / 3);
            }
        
        
        	// 거리가 같다면
            if(L == R){
                if(hand == "right"){
                    answer += 'R';
                    right = numbers[i];
                }else if(hand == "left"){
                    answer += 'L';
                    left = numbers[i];
                }
            }else if(L < R){	// 왼손이 가깝다면
                answer += 'L';
                left = numbers[i];
            }else if(L > R){	// 오른손이 가깝다면
                answer += 'R';
                right = numbers[i];
            }
    }
    }
    
    return answer;
}

 

🔔 새로 알게 된 점

정답을 제출 후 다른 사람 풀이를 확인하니, 키패드의 숫자들은 배열에 담고 관리하는 소스들이 많았습니다.

그중 인상적이었던 것은 키패드 숫자들을 행렬처럼 관리하는 것입니다.

const grid = [

                [0,-2], [-1,1], [0,1],

                [1,1], [-1,0], [0,0],

                [1,0], [-1,-1], [0,-1],

                [1,-1], [-1,-2], [1,-2]

];

이렇게 관리하면 행끼리의 거리 + 열끼리의 거리만큼 이동거리가 구해진다는 것을 이용했다면 더 간단하게 소스를 짤 수 있었을 것 같습니다.

728x90
반응형
728x90
반응형

2021.06.12

문제명 : 찾아라 프로그래밍 마에스터 - 폰켓몬

사용언어 : Javascript

개발 시간 : 10분

 

 

코딩테스트 연습 - 폰켓몬

당신은 폰켓몬을 잡기 위한 오랜 여행 끝에, 홍 박사님의 연구실에 도착했습니다. 홍 박사님은 당신에게 자신의 연구실에 있는 총 N 마리의 폰켓몬 중에서 N/2마리를 가져가도 좋다고 했습니다.

programmers.co.kr

 

📋 문제 설명

주어진 폰켓몬중 N/2마리를 고를 때 선택할 수 있는 폰켓몬 종류의 최댓값을 구하는 문제입니다

주어지는 폰켓몬은 항상 짝수 개수이므로 N/2는 딱 떨어지는 수입니다

 

📢 입출력 예

nums 배열 안에 값은 각각의 폰켓몬을 의미합니다. '1'이라는 폰켓몬, '2'라는 폰켓몬 등..

예제 2를 보면, [3,3,3,2,2,4] 이므로 가져갈 수 있는 폰켓몬의 개수(N/2)는 3마리(6/2)입니다

3마리를 가져갈 수 있는 방법 중 가장 다양하게 가져가는 방법은 2,3,4라는 폰켓몬을 한 마리씩 가져가는 것입니다

따라서 3이 답입니다

 

즉,

  1. nums배열 안에 중복되는 폰켓몬들을 제거한 후
  2. 중복 제거한 배열의 개수 >= N/2 라면 답은 N/2
  3. 중복 제거한 배열의 개수  <  N/2 라면 답은 중복 제거한 배열의 개수가 되는 것입니다

 

🔑 문제 풀이

function solution(nums) {
    var answer = 0;
    var cnt = nums.length / 2;
    
    // 중복 제거
    var arr = nums.filter((element, index) => {
        return nums.indexOf(element) === index;
    });
    
    if(arr.length >= cnt){
        answer = cnt;
    }else{
        answer = arr.length;
    }
    
    return answer;
}

 

728x90
반응형
728x90
반응형

2021.05.29

문제명 : 2019 KAKAO BLIND RECRUITMENT - 실패율

사용언어 : Javascript

개발 시간 : 90분

 

 

 

코딩테스트 연습 - 실패율

실패율 슈퍼 게임 개발자 오렐리는 큰 고민에 빠졌다. 그녀가 만든 프랜즈 오천성이 대성공을 거뒀지만, 요즘 신규 사용자의 수가 급감한 것이다. 원인은 신규 사용자와 기존 사용자 사이에 스

programmers.co.kr

 

📋 문제 설명

실패율 = 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수

 

📢 입출력 예

예시 1을 보면, 최종단계(N)는 5단계이고, stages배열 [2, 1, 2, 6, 2, 4, 3, 3]입니다.

stages배열의 각각은 개개인이 현재 위치해있는 단계를 의미합니다.

 

따라서 stages 배열의 크기만큼 인원(8명)이 있고,

  • 1단계에 머무르고 있는 사람은 [2, 1, 2, 6, 2, 4, 3, 3] 한 명이므로 1단계 실패율 : 1/8 (=0.125)
  • 2단계에 머무르고 있는 사람은 2단계 이상 올라온 사람 중 [22, 6, 2, 4, 3, 3] 세명이므로 2단계 실패율 : 3/7 (=0.42)
  • 3단계에 머무르고 있는 사람은 3단계 이상 올라온 사람 중 [6, 4, 33] 세명이므로 3단계 실패율 : 2/4 (=0.5)

이런식으로 반복되면 실패율이 높은(큰) 단계는 3단계(0.5)→4단계(0.5)→2단계(0.42)→1단계(0.125)→5단계(0) 순입니다.

 

따라서 정답은 [3,4,2,1,5]입니다.

 

 

🔑 문제 풀이

function solution(N, stages) {
    var answer = [];
    var fail_arr = [];
    var total = stages.length;

    for(var i=1; i<=N; i++){
        
        var cnt = 0;
        for(var j=0; j<stages.length; j++){
            if(i == stages[j]){
                cnt++;                
            }
        }        
        
        // 실패율(per)순으로 정렬시키기 위해 json형태로 push
        fail_arr.push({per:cnt/total, idx:i});
        total -= cnt;
    }
    
    fail_arr.sort(function(a, b) { return b["per"] - a["per"]; });
    
    for(var i=0; i<fail_arr.length; i++){
        answer.push(fail_arr[i].idx);
    }
    
    return answer;
}

 

 

🔔 새로 알게 된 점

16번 라인 : fail_arr.push({per:cnt/total, idx:i}); 

딕셔너리로 관리할 수 있다.

 

728x90
반응형
728x90
반응형

2021.05.29

문제명 : 2019 카카오 개발자 겨울 인턴십 - 크레인 인형뽑기 게임

사용언어 : Javascript

개발 시간 : 90분

 

 

코딩테스트 연습 - 크레인 인형뽑기 게임

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

programmers.co.kr

 

 

📋 문제 설명

NxN행렬에서 인형을 뽑아 쌓을 때 중복되어 없어지는 인형의 갯수를 구하는 문제입니다

 

 

📢 입출력 예

 

 

🔑 문제 풀이

예시의 board 배열을 테이블 형식으로 표현하면 다음과 같습니다.

각각의 숫자를 '1'이라는 인형, '2'라는 인형이라고 생각하면 이해가 빠를 것입니다.

단 '0'은 비어있는 공간이라고 생각하는 것입니다.

 

0 0 0 0 0
0 0 1 0 3
0 2 5 0 1
4 2 4 4 2
3 5 1 3 1

 

 

 

moves [1,5,3,5,1,2,1,4]는 위 테이블 하단에 해당하는 숫자로,

⁕ 첫 번째 1의 경우

0은 비어있는 공간이라고 생각하기로 했기 때문에 크레인이 지나치므로 '4'라는 인형이 뽑힙니다.

'4'라는 인형이 뽑혔으므로 그 자리는 공백이 됩니다  

 

 

 

⁕ 두번째 5의 경우

마찬가지로 0이라는 빈 공간 지나치면 크레인은 '3'이라는 인형을 뽑고 그 자리는 공백으로 바뀝니다.

 

 

이런 식으로 뽑으면 순서대로 4 → 3 →  113 → 2 → '없음' → 4라는 인형이 뽑힙니다.

중복이 되는 경우 인형은 터진다고 했으므로, 4 → 3 →  1 → 1 에서 '1'이라는 인형 두 개는 터지고,

4 → 3 → 3 에서 '3'이라는 인형 두 개가 터집니다.

그 후에는 더이상 중복이 발생하지 않으므로 종료됩니다.

따라서 4개의 인형이 터지게 됩니다.

 

 

이를 코드로 변경하면,

function solution(board, moves) {
    var answer = 0;
    var res_arr = new Array();
    var chk = "N";

    var y = 0;
    for(var i=0; i<moves.length; i++){
        if(chk == "N"){
            y = i;    
        }
        
        var x = moves[i] - 1; 
        
        for(var j=0; j<board.length; j++){
        	// 빈 공간이 아니라면
            if(board[j][x] != 0){ 
                
                // 해당 인형을 넣기
                res_arr.push(board[j][x]); 
                
                // 뽑힌 인형 자리는 빈 공간(0)으로 변경
                board[j][x] = 0;	
                
                // 중복 발생시
                if((res_arr[y] == res_arr[y-1])){ 
                    
                    // 터지는 인형은 기존것과 새로 뽑힌것 : 총2개
                    answer = answer + 2;	
                    
                    // 기존것 제거(터지기)
                    res_arr.pop();	
                    // 새로뽑힌 것 제거(터지기)
                    res_arr.pop();  
                    
                    y--;
                    chk = "Y";
                }else{
                     y++;
                }
                
                break;
            }
        }        
    }
    
    return answer;
}

 

728x90
반응형

+ Recent posts