Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

kohigowild

221007 :: [프로그래머스] 시저 암호 | 최소직사각형 | 구명보트 본문

Algorithm

221007 :: [프로그래머스] 시저 암호 | 최소직사각형 | 구명보트

kohi ☕ 2022. 10. 7. 19:49

 

시저 암호

👾 문제 설명

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

 

👾 제한 조건

  • 공백은 아무리 밀어도 공백입니다.
  • s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
  • s의 길이는 8000이하입니다.
  • n은 1 이상, 25이하인 자연수입니다.

 

👾 나의 답안

function solution(s, n) {
    let result = "";

    for (let i = 0; i < s.length; i++) {
        let sCode = s.charCodeAt(i);

        if (65 <= sCode <= 90 || 97 <= sCode <= 122) {
            sCode += n;
            if (sCode > 90 || sCode > 122) {
                sCode -= 26;
            }
        }
        str = String.fromCharCode(sCode);
        result += str;
    }
    return result;
}

 

  • s를 아스키 코드 값으로 변환하고 for loop를 통해 문자열을 걸러내서 (65부터 90까지 대문자, 97부터 122까지 소문자) n값을 더한다.
  • if 안에 if를 사용해서 n을 더한 값이 91(Z) 이상 or 122(z) 이상이면 26을 빼서 z  + 1이 a가 되는 것을 처리하고, 다시 아스키 코드를 문자열로 치환해서 결과를 반환한다.
  • 공백 처리가 되지 않은 문제가 있었고, if 조건식을 쓸 때 65 <= sCode <= 90 이런 식으로 쓰면 안 된다는 걸 배웠다!

 

function solution(s, n) {
    let result = "";

    for (let i = 0; i < s.length; i++) {
        let sCode = s.charCodeAt(i);

        if (sCode === 32) {
            result += "";
        }

        if (65 <= sCode && sCode <= 90) {
            sCode += n;
            if (sCode > 90) {
                sCode -= 26;
            }
        }

        if (97 <= sCode && sCode <= 122) {
            sCode += n;
            if (sCode > 122) {
                sCode -= 26;
            }
        }

        str = String.fromCharCode(sCode);
        result += str;
    }
    return result;
}

 

  • 최종 답안
  • 공백 처리를 추가하고 if 문에서 문제였던 부분을 수정하였다.

 

👾 다른 사람의 풀이

function solution(s, n) {
    var chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY                          "
    return s.split('').map(e => chars[chars.indexOf(e)+n]).join('');
}

 

  • 아스키 코드 생각해낸 내가 기특하다고 생각했는데 풀고 보니까 아스키 코드 안 쓴 사람들이 진짜 천재 같다.
  • 창의적인 답변인 것 같아서 가져왔다. n은 1 이상 25 이하이기 때문에 알파벳을 두 번 연달아서 변수 선언하면 됨.

 

function solution(s, n) {
    var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var lower = "abcdefghijklmnopqrstuvwxyz";
    var answer= '';

    for(var i =0; i <s.length; i++){
        var text = s[i];
        if(text == ' ') {
            answer += ' '; 
            continue;
        }
        var textArr = upper.includes(text) ? upper : lower;
        var index = textArr.indexOf(text)+n;
        if(index >= textArr.length) index -= textArr.length;
        answer += textArr[index];
    }
    return answer;
}

 

  • 제일 정석 같은 코드라서 가져왔다.
  • 삼항연산자를 쓰면 왠지 코드가 멋있어 보인다. 나도 많이 써 봐야겠다고 생각하는데 생각이 잘 안 남...

 


최소직사각형
👾 문제 설명

명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.

아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.

명함 번호 가로 길이 세로 길이
1 60 50
2 30 70
3 60 30
4 80 40
가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.

모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.

👾 제한사항
  • sizes의 길이는 1 이상 10,000 이하입니다.
    • sizes의 원소는 [w, h] 형식입니다.
    • w는 명함의 가로 길이를 나타냅니다.
    • h는 명함의 세로 길이를 나타냅니다.
    • w와 h는 1 이상 1,000 이하인 자연수입니다.

 

👾 나의 답안

function solution(sizes) {
    for (let i = 0; i < sizes.length; i++) {
        if (sizes[i][0] < sizes[i][1]) {
            return sizes.reverse();
        } else return sizes;
    }

    let x = 0;
    let y = 0;
    for (let i = 0; i < sizes.length; i++) {
        if (sizes[i][0] > x) x = size[i][0];
        if (sizes[i][1] > y) y = size[i][1];
    }
    return x * y;
}

 

  • 처음 제출한 답안 (오답)
  • 코딩 테스트 때마다 2차원 배열 문제가 너무 어렵게 느껴져서 도전해 보았다.
  • 명함은 회전이 가능하기 때문에 큰 값을 앞으로, 작은 값을 뒤로 정렬한다. -- 여기서 문제가 있었던 것 같다.
  • 변수 x와 y를 선언하고 for loop를 돌면서 [i][0] 중 가장 큰 값을 x에, [i][1] 중 가장 큰 값을 y에 넣고 x * y 값을 리턴한다.

 

function solution(sizes) {
    let arr = sizes.map((size) => (size[0] > size[1] ? [size[0], size[1]] : [size[1], size[0]]));

    let x = 0;
    let y = 0;
    for (let i = 0; i < arr.length; i++) {
        if (arr[i][0] > x) x = arr[i][0];
        if (arr[i][1] > y) y = arr[i][1];
    }

    return x * y;
}

 

  • map() 메서드를 사용해서 명함 회전 조건 부분을 수정하였다.
  • 제대로 출력된다.

 


구명보트
👾 문제 설명

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다.

예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 50kg]이고 구명보트의 무게 제한이 100kg이라면 2번째 사람과 4번째 사람은 같이 탈 수 있지만 1번째 사람과 3번째 사람의 무게의 합은 150kg이므로 구명보트의 무게 제한을 초과하여 같이 탈 수 없습니다.

구명보트를 최대한 적게 사용하여 모든 사람을 구출하려고 합니다.

사람들의 몸무게를 담은 배열 people과 구명보트의 무게 제한 limit가 매개변수로 주어질 때, 모든 사람을 구출하기 위해 필요한 구명보트 개수의 최솟값을 return 하도록 solution 함수를 작성해주세요.

👾 제한사항
  • 무인도에 갇힌 사람은 1명 이상 50,000명 이하입니다.
  • 각 사람의 몸무게는 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 40kg 이상 240kg 이하입니다.
  • 구명보트의 무게 제한은 항상 사람들의 몸무게 중 최댓값보다 크게 주어지므로 사람들을 구출할 수 없는 경우는 없습니다.

 

👾 나의 답안

function solution(people, limit) {
    let answer = 0;
    people.sort(function (a, b) {
        return a - b;
    });

    for (let i = 0, j = people.length - 1; i <= j; j--) {
        if (people[i] + people[j] <= limit) {
            answer++;
            i++;
        } else {
            answer++;
        }
    }
    return answer++;
}

 

  • 이번 주에 봤던 코딩 테스트 문제 중에 있었던 유형이라 복기할 겸 가져왔다.
  • 사람들을 무게 내림차 순으로 정렬한다.
  • i는 배열 시작점, j는 배열의 끝부터 시작해서 가장 가벼운 사람과 가장 무거운 사람이 함께 탈 수 있는지 체크한다. (보트를 최대한 적게 사용하기 위함.) 만약 그렇지 않다면 가장 무거운 사람 먼저 보트에 탑승한다. -- for문 안에 변수를 여러 개 쓸 수 있다!
  • 카운트한 answer 반환

 

👾 다른 사람의 풀이

function solution(people, limit) {
    people.sort(function(a, b){return a-b});
    for(var i=0, j=people.length-1; i < j; j--) {
        if( people[i] + people[j] <= limit ) i++;
    }    
    return people.length-i;
}

 

  • 거의 비슷한 풀이인데 따로 보트 수를 카운트하는 변수를 따로 선언하지 않고 배열의 길이에서 i값을 차감하는 방식
  • var를 사용해서 i를 선언했기 때문에 for문 밖에서도 i를 참조할 수 있다.