본문 바로가기

알고리즘 문제풀이

[프로그래머스] 2020카카오 인턴십 - 키패드 누르기/ 수식 최대화

오늘 푼 문제

 

1. 키패드 누르기/ Lv.1 / 시간: 59분(타임오버)

programmers.co.kr/learn/courses/30/lessons/67256

 

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

[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

function solution(numbers, hand) {
    let l = 10;
    let r = 12;
    let answer = numbers.reduce((acc,cur)=>{
        cur = cur==="*"?10:cur;
        cur = cur==="#"?12:cur;
        cur = cur===0?11:cur;
        if(cur%3===1){
            acc+='L';
            l = cur;
        }    
        else if(cur%3===0){
            acc+='R';
            r = cur
        }    
        else{
            let lpos = [Math.floor((l-1)/3),(l-1)%3];
            let rpos = [Math.floor((r-1)/3),(r-1)%3];
            let pos = [Math.floor((cur-1)/3),(cur-1)%3];
            
            let lDistance = Math.abs(lpos[0]-pos[0]) + Math.abs(lpos[1]-pos[1]); 
            let rDistance = Math.abs(rpos[0]-pos[0]) + Math.abs(rpos[1]-pos[1]); 
            
            if(lDistance>rDistance){
                acc+='R'
                r = cur;
            }else if(lDistance<rDistance){
                acc+='L';
                l =cur;
            }else{
                if(hand==='right'){
                    acc+='R'
                    r = cur;
                }else{
                    acc+='L';
                    l =cur;
                }
            }
        }
        return acc;
    },'')
    
    return answer;
}

 

상하좌우만 이동 가능하고 대각선 이동은 불가능해서 맨하탄 거리를 써야 한다.

문제도 제대로 안 읽고 등신같이 풀었음.

(numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다... 즉 *이나 #은 첫 시작점을 제외하고는 눌릴 일이 없다;)

 

 

2. 다시 품. 맨하탄 거리를 쓸 것이기 때문에 각각의 위치를 좌표로 그냥 미리 만들었음.

function solution(numbers, hand) {
    var answer = '';
    let pos = [[0,1],[3,0],[3,1],[3,2],[2,0],[2,1],[2,2],[1,0],[1,1],[1,2]];
    let left = [0,0];
    let right = [0,2];
    answer = numbers.reduce((acc,cur)=>{
        if(cur%3===1){ //1,4,7
            left = pos[cur];
            acc+='L';
        }else if(cur && !(cur%3)){ //3,6,9
            right = pos[cur];
            acc+='R';
        }else{ //2,5,8,0
            let [target_x,target_y] = pos[cur];
            let [left_x,left_y] = left;
            let [right_x,right_y] = right;
            let lDis = Math.abs(left_x-target_x) + Math.abs(left_y-target_y); 
            let rDis = Math.abs(right_x-target_x) + Math.abs(right_y-target_y);
            if((lDis>rDis) || ((lDis===rDis)&&hand==='right') ){
                right = pos[cur];
                acc+='R'
            }else if((lDis<rDis) || ((lDis===rDis)&&hand==='left')){
                left = pos[cur];
                acc+='L';
            }
        }
        return acc;        
    },'')
    return answer;
}

 

 

2. 수식 최대화/ Lv.2 / 시간: 67분(타임오버)

programmers.co.kr/learn/courses/30/lessons/67257

 

코딩테스트 연습 - 수식 최대화

IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과

programmers.co.kr

function solution(expression) {
    var answer = 0;
    let priorities =  [['*', '+', '-'], ['*', '-', '+'], ['+', '*', '-'],
                       ['+', '-', '*'], ['-', '+', '*'], ['-', '*', '+']];
    priorities.forEach(priority=>{
        let result = calc(priority,expression);
        if(answer<result) answer = result;
    })
    return answer;
}


function calc(priority,expression){
    let regx = /[*+-]/g;
    let numbers = expression.split(regx);
    let opers = expression.match(regx);
    
    for(let i=0;i<3;i++){
        let [temp,temp2] = [[],[]];
        let key = priority[i];
        while(numbers.length){
            let n = numbers.shift();
            let o = opers.shift();
            if(o===key){
                let n2 = numbers.shift();
                let newN = eval(n+o+n2);
                numbers.unshift(newN);
            }else{
                temp.push(n);
                if(o)temp2.push(o)
            }
        }
        [numbers,opers] = [temp,temp2];
        
    }
    return Math.abs(numbers)
}

 

연산 우선순위를 정하는 방식도 원래는 동적으로 생성했으나 정적인 변수로 박아넣어도 경우의 수가 최대 6가지 밖에 안 나오고, 실행 결과도 속도 면에서 유의미한 차이가 없어서 코드의 가독성을 고려해 정적인 변수로 변경했다. 연산자의 종류가 더 다양할 경우 사용하면 될 듯.

기존의 코드

function solution(expression) {
    var answer = 0;

    let [first,sec,last] = [null,null,null];
    let arr = ['+','-','*'];
    for(let i=0;i<3;i++){
        first = arr[i];
        let temp = [...arr]
        temp.splice(i,1);
        for(let j=0;j<2;j++){
            sec = temp[j];
            last = temp[1-j];
            let result = calc([first,sec,last],expression);
            if(answer<result) answer = result;
        }
    }
    return answer;
}

//이하 calc 함수는 동일