Lsiron

코딩테스트 11(Math.max, Math.min, 아스키코드, s.charCodeAt, string.fromCharCode) 본문

코딩테스트/Java Script

코딩테스트 11(Math.max, Math.min, 아스키코드, s.charCodeAt, string.fromCharCode)

Lsiron 2024. 7. 2. 12:09

문제 1. 최소 직사각형
 

명함 지갑을 만드는 회사에서 지갑의 크기를 정하려고 합니다. 다양한 모양과 크기의 명함들을 모두 수납할 수 있으면서, 작아서 들고 다니기 편한 지갑을 만들어야 합니다. 이러한 요건을 만족하는 지갑을 만들기 위해 디자인팀은 모든 명함의 가로 길이와 세로 길이를 조사했습니다.
아래 표는 4가지 명함의 가로 길이와 세로 길이를 나타냅니다.
명함 번호 : 가로 길이 / 세로 길이
1 : 60 / 50 , 2 : 30 / 70  , 3 : 60 / 30  , 4 : 80 / 40
 [ [ 60, 50 ] , [ 30, 70 ] , [ 60, 30 ] , [ 80 , 40 ] ]
가장 긴 가로 길이와 세로 길이가 각각 80, 70이기 때문에 80(가로) x 70(세로) 크기의 지갑을 만들면 모든 명함들을 수납할 수 있습니다. 하지만 2번 명함을 가로로 눕혀 수납한다면 80(가로) x 50(세로) 크기의 지갑으로 모든 명함들을 수납할 수 있습니다. 이때의 지갑 크기는 4000(=80 x 50)입니다.
모든 명함의 가로 길이와 세로 길이를 나타내는 2차원 배열 sizes가 매개변수로 주어집니다. 모든 명함을 수납할 수 있는 가장 작은 지갑을 만들 때, 지갑의 크기를 return 하도록 solution 함수를 완성해주세요.

 
풀이=해답.

function solution(sizes) {
    let maxArr = [];
    let minArr = [];
    
    for(let i = 0; i < sizes.length; i += 1) {
        maxArr.push(Math.max(sizes[i][0], sizes[i][1]));
        minArr.push(Math.min(sizes[i][0], sizes[i][1]));
    }
    
    let max = Math.max(...maxArr);
    let min = Math.max(...minArr);
    
    return max * min;
}

 
=> 배열 속 배열의 최댓값과 최솟값 들을 구하기 위해 반복문을 써 주었고, 골라낸 최댓값 들 중 최댓값과 최솟값 들 중 최댓값을 구해서 곱한 값을 반환하도록 하였다. 

 

// 크기가 가지각색인 명함들을 모두 수용할 수 있으려면 가로 세로 길이 중 가장 큰 값 들 중에 가장 큰 값 하나와, 가장 작은 값 들 중에 가장 큰 값을 구해야겠다고 생각했다. 가장 길이가 긴 값을 하나 쓰면 나머지 길이를 포용할 수 있는 값 하나가 필요할테니 당연히 가장 큰 값과 작은 값들 중, 가장 큰 값이 필요하다고 생각했다.

 

문제 2. 시저암호
 

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "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 = '';

    // 입력 문자열 s의 각 문자에 대해 반복
    for (let i = 0; i < s.length; i++) {
        let char = s[i];
        
        // 문자가 공백인 경우 그대로 결과에 추가
        if (char === ' ') {
            result += ' ';
            continue;
        }

        // 문자가 대문자인지 소문자인지에 따라 다른 ASCII 범위 사용
        let charCode = s.charCodeAt(i);
        let base = (char >= 'a' && char <= 'z') ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0);
        
        // 밀어서 새로운 문자 계산
        let newChar = String.fromCharCode(((charCode - base + n) % 26) + base);
        result += newChar;
    }

    return result;
}

 
=> 먼저 입력 문자열 s의 각 문자를 순회한다. 공백 문자는 변환하지 않고 그대로 결과 문자열에 추가한다.

각 문자의 ASCII 값을 얻고, 대문자와 소문자에 대해 각각의 기본 ASCII 값을 기준으로 이동한 새로운 문자를 계산한다.

계산된 새로운 문자를 결과 문자열에 추가한다.

 

 

s.charCodeAt은 JavaScript의 문자열 메서드로, 문자열에서 특정 인덱스에 있는 문자의 유니코드(UTF-16) 값을 반환한다. 이 메서드는 문자열 내의 문자를 숫자 코드로 변환할 때 사용된다. (영어 알파벳 범위에서는 유니코드와 아스키코드 값이 같다.)

console.log('a'.charCodeAt(0)); // 97 ('a'의 유니코드 값)
console.log('A'.charCodeAt(0)); // 65 ('A'의 유니코드 값)

 

String.fromCharCode는 JavaScript의 내장 함수로, 주어진 유니코드 값에 해당하는 문자를 반환한다. 이 함수는 숫자로 표현된 유니코드 값을 받아서 그에 해당하는 문자로 변환하는 역할을 한다. (영어 알파벳 범위에서는 유니코드와 아스키코드 값이 같다.)

console.log(String.fromCharCode(65)); // "A"
console.log(String.fromCharCode(97)); // "a"
console.log(String.fromCharCode(122)); // "z"

 

ASCII 코드 (American Standard Code for Information Interchange)

ASCII 코드는 컴퓨터가 문자(알파벳, 숫자, 특수 문자 등)를 숫자로 표현하는 표준이다. 각 문자에는 고유한 숫자 값이 할당되어 있다.

예를 들어:

  • A의 ASCII 값은 65
  • B의 ASCII 값은 66
  • a의 ASCII 값은 97
  • b의 ASCII 값은 98

시저 암호에서 % 26 연산은 알파벳이 순환하도록 하기 위해 사용된다. 알파벳은 26개의 문자로 이루어져 있으므로, 26으로 나눈 나머지를 구하는 연산을 통해 알파벳의 끝에서 다시 처음으로 돌아가게 할 수 있다. 이를 이해하기 위해 좀 더 자세하게 알아보자.

알파벳의 순환

알파벳은 26개의 문자로 구성되어 있다:

  • A부터 Z까지 26개 (대문자)
  • a부터 z까지 26개 (소문자)

예를 들어, z에서 1만큼 이동하면 a가 되어야 한다. 이를 위해 % 26 연산이 필요하다. 이 연산을 통해 알파벳의 끝에서 다시 처음으로 돌아가게 할 수 있다.

수학적 배경

  1. 대문자 예시:
    • Z는 ASCII 코드 90입니다.
    • 1만큼 이동하면 ASCII 코드 91이 되어야 하는데, 이는 알파벳 범위를 벗어난다.
    • (90 - 65 + 1) % 26 + 65 계산을 통해:
      • 90 - 65 + 1 = 26
      • 26 % 26 = 0
      • 0 + 65 = 65
      • 65는 A의 ASCII 코드이다.
  2. 소문자 예시:
    • z는 ASCII 코드 122이다.
    • 1만큼 이동하면 ASCII 코드 123이 되어야 하는데, 이는 알파벳 범위를 벗어난다.
    • (122 - 97 + 1) % 26 + 97 계산을 통해:
      • 122 - 97 + 1 = 26
      • 26 % 26 = 0
      • 0 + 97 = 97
      • 97은 a의 ASCII 코드이다.

 

// 손도 못 댔다. 아스키 코드란게 있다는 것을 처음 알았다. 문자 관련된 코테가 있지 않을까 했는데 드디어 나왔다. 덕분에 아스키 코드를 처음으로 배우게 됐는데, 아스키코드를 보기 전 까지는 아무리 고민해도 알파벳을 배열로 전부 나열한 다음에 푸는 방법밖에 생각나지 않았다. 한 시간정도 고민하다가 AI 도움을 받기로 했다.