배꼽파지 않도록 잘 개발해요

[프로그래머스] 입문 Day 8 배열, 구현, 수학 (Javascript) 본문

코딩테스트/프로그래머스

[프로그래머스] 입문 Day 8 배열, 구현, 수학 (Javascript)

꼽파 2023. 12. 19. 13:41


배열 자르기

문제 설명

  • 정수 배열 numbers와 정수 num1, num2가 매개변수로 주어질 때, numbers의 num1번 째 인덱스부터 num2번째 인덱스까지 자른 정수 배열을 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 2 ≤ numbers의 길이 ≤ 30
  • 0 ≤ numbers의 원소 ≤ 1,000
  • 0 ≤num1 < num2 < numbers의 길이

입출력 예

numbers num1 num2 result
[1, 2, 3, 4, 5] 1 3 [2, 3, 4]
[1, 3, 5] 1 2 [3, 5]

 

풀이 1

주어진 범위에 해당하는 원소들을 for 반복문으로 추출해서 새로운 배열에 추가

function solution(numbers, num1, num2) {
    var answer = [];
    // 배열 원소 자르기
    for (i = num1; i <= num2; i++) {
        answer.push(numbers[i])
    }
    
    return answer;
}

 

풀이 2

slice 메소드 이용

function solution(numbers, num1, num2) {
	// num1부터 num2까지 (num2 + 1 미만)
    return numbers.slice(num1, num2 + 1)
}

 

풀이 3

splice 메소드 이용

function solution(numbers, num1, num2) {
    // 시작 인덱스, 추출할 요소 개수, (추가할 값)
    // num1부터 num2까지 개수 = num2 - num1 + 1
    return numbers.splice(num1, num2 - num1 + 1)
    }

 

주의할 점

  • 배열 자르기는 기본적으로 slice와 splice를 활용할 수 있음.

외계행성의 나이

문제 설명

  • 우주여행을 하던 머쓱이는 엔진 고장으로 PROGRAMMERS-962 행성에 불시착하게 됐습니다. 입국심사에서 나이를 말해야 하는데, PROGRAMMERS-962 행성에서는 나이를 알파벳으로 말하고 있습니다. a는 0, b는 1, c는 2, ..., j는 9입니다. 예를 들어 23살은 cd, 51살은 fb로 표현합니다. 나이 age가 매개변수로 주어질 때 PROGRAMMER-962식 나이를 return하도록 solution 함수를 완성해주세요.

제한사항

  • age는 자연수입니다.
  • age ≤ 1,000
  • PROGRAMMERS-962 행성은 알파벳 소문자만 사용합니다.

입출력 예

age result
23 "cd"
51 "fb"
100 "baa"

 

풀이 1

숫자의 각 자릿수를 map으로 인덱싱

function solution(age) {
    
    var answer = '';
    
    // map에 알파벳의 기호와 인덱스 쌍을 넣기
    const alpha = "abcdefghijklmnopqrstuvwxyz";
    const m = new Map();
    for (i = 0; i < alpha.length; i++) {
        m.set(i, alpha[i])   
    }

    // age를 10으로 나눈 나머지를 저장
    // 해당 나머지 값이 key(인덱스) 중 있으면 해당 value(알파벳) 반환
    // value 값은 str에 넣기
    
    while (age >= 1) {
        const remainder = age % 10
        if (m.has(remainder)) {
            answer = m.get(remainder) + answer;
        } 
        age = Math.floor(age / 10);
    }

    return answer;
}
function solution(age) {
    
    var answer = '';
    
    // map에 알파벳의 기호와 인덱스 쌍을 넣기
    const alpha = "abcdefghij";
    const m = new Map();
    for (i = 0; i < alpha.length; i++) {
        m.set(i, alpha[i])   
    }

    // 각 숫자를 알파벳으로 매핑하여 answer에 추가
    String(age).split("").forEach(digit => {
        // 각 자리의 숫자를 정수로 변환하여 인덱스로 활용
        const index = Number(digit);
        // 매핑된 알파벳을 answer에 추가
        answer += m.get(index);
    });
    return answer;
}

 

풀이 2

map과 join을 활용

function solution(age) {
    // 각 숫자가 0부터 9까지 숫자에 해당되게끔 
    // a는 = "abcdefghij"라는 문자열에서 a의 인덱스값
      return age
        .toString()  // "23"
        .split("")  // ["2", "3"]
        .map((v) => "abcdefghij"[v])  // "2"는 "abcdefghij"[2] = c
        .join("");  // "23" (문자열)
}

 

풀이 3

배열에 맞는 문자 출력

function solution(age) {
    var alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
    var answer = "";
    age = age.toString();
    
    // 한글자씩 for문으로 순회
    // 배열에서 해당 숫자에 해당하는 알파벳 넣어주기
    for(let i = 0; i < age.length; i++){
           answer += alphabet[i];
    }
    return answer;
}

 

주의할 점

  • 풀이1은 내가 푼 방법인데, map을 활용하긴 했지만 뭔가 복잡해보인다. 내가 풀었나 싶을 정도임.
  • 문제는 이해하기 쉽지만 구현하는 것이 꽤 까다롭다.

진료순서 정하기

문제 설명

  • 외과의사 머쓱이는 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다. 정수 배열 emergency가 매개변수로 주어질 때 응급도가 높은 순서대로 진료 순서를 정한 배열을 return하도록 solution 함수를 완성해주세요.

제한사항

  • 중복된 원소는 없습니다.
  • 1 ≤ emergency의 길이 ≤ 10
  • 1 ≤ emergency의 원소 ≤ 100

입출력 예

emergency result
[3, 76, 24] [3, 1, 2]
[1, 2, 3, 4, 5, 6, 7] [7, 6, 5, 4, 3, 2, 1]
[30, 10, 23, 6, 100] [2, 4, 3, 5, 1]

 

풀이 1

Map을 통해 정렬된 배열의 각 원소와 해당 원소의 원래 인덱스를 매핑

function solution(emergency) {

    var answer = [];  // 정답을 반환할 배열
    
    // emergency를 내림차순으로 정렬
    // 주의 : const sorted_e = emergency.sort로 쓰면 emergency가 변경됨.
    const sorted_e = [...emergency].sort((a, b) => (b - a))  // [ 76, 24, 3 ]
    
    // 해당 배열의 인덱스를 추출하여 map에 원소, 인덱스 넣기
    let m = new Map();
    for (let i = 0; i < sorted_e.length; i++) {
        m.set(sorted_e[i], i + 1)  
    }
    // 	Map(3) { 76 => 1, 24 => 2, 3 => 3 }
    // emergency 원소를 순회
    // map의 키 값과 같다면 해당 value를 반환하도록 함
    for (num of emergency) {  // [3, 76, 24]
        if (m.has(num)) {
            answer.push(m.get(num))
        }
    }    
    return answer;
}

 

풀이 2

sort와 map을 활용한 간단한 풀이

function solution(emergency) {

    var answer = [];  // 정답을 반환할 배열
    
    // emergency를 내림차순으로 정렬
    // 주의 : const sorted_e = emergency.sort로 쓰면 emergency가 변경됨.
    const sorted_e = emergency.slice().sort((a, b) => b - a);
    
    // emergency 배열의 모든 원소는 sorted_e의 인덱스 값 + 1
    return emergency.map(a => sorted_e.indexOf(a) + 1);
}

 

주의할 점

  • 자료구조 map과 배열에 쓰는 메서드 map이 헷갈림.
  • 자료구조와 메서드에 대한 이해가 부족해서 풀이가 복잡해지는 듯 싶음.

순서쌍의 개수

문제 설명

  • 순서쌍이란 두 개의 숫자를 순서를 정하여 짝지어 나타낸 쌍으로 (a, b)로 표기합니다. 자연수 n이 매개변수로 주어질 때 두 숫자의 곱이 n인 자연수 순서쌍의 개수를 return하도록 solution 함수를 완성해주세요.

제한사항

  • 1 ≤ n ≤ 1,000,000

입출력 예

n result
20 6
100 9

 

풀이 1

순서쌍의 개수를 구하라고 했으니, 약수의 개수를 출력하면 됨.

function solution(n) {
    var count = 0;  // 순서쌍의 개수
    
    for (i = 1; i <= n; i++){
         if (n % i == 0) {
             count += 1
         }
    }
    return count;   
}

 

풀이 2

풀이 1과 원리가 같으나, 제곱근을 사용해서 확인해야할 범위를 줄임

function solution(n) {
    let answer = 0;
    // n의 제곱근까지만 순회함.
    // 약수의 개수는 2개씩 증가하도록 함.
    for (let i = 1; i < Math.sqrt(n); i++)
        if (n % i === 0) answer += 2;

	// 만약 완전제곱수인 경우는 (ex. 6 * 6 = 36) 약수의 개수에 1을 더함.
    return Number.isInteger(Math.sqrt(n)) ? answer + 1 : answer;
}

 

어떤 수의 약수를 찾을 때 그 수의 제곱근보다 큰 약수를 찾을 필요가 없음.

ex. 36의 약수 : 1, 2, 3, 4, 6, 12, 36
여기서 6 * 6 = 36이므로 36의 제곱근인 6까지 찾으면 나머지 약수의 개수를 찾을 수 있음.

그러므로 특정 수의 제곱근까지만 for문으로 순회함.

 

주의할 점

  • 순서쌍의 개수를 구하라고 해서 위처럼 약수의 개수를 출력하는 것이 가능했음.
  • 만약 '순서쌍을 구하시오'라고 했으면?

순서쌍 구하기

function solution(n) {
    let pairs = [];

    for (let i = 1; i <= n; i++) {
        if (n % i === 0) {
            pairs.push([i, n / i]);
        }
    }

    return pairs;
}

// Example
console.log(solution(20));
// [ [ 1, 20 ], [ 2, 10 ], [ 4, 5 ], [ 5, 4 ], [ 10, 2 ], [ 20, 1 ] ]

 

순서쌍 중에서 순서와 무관하게 값이 중복되는 것을 제외하고 싶은 경우

function solution(n) {
    let pairs = [];

	// for문으로 제곱근까지만 순회
    for (let i = 1; i <= Math.sqrt(n); i++) {
        if (n % i === 0) {
            pairs.push([i, n / i]);
        }
    }
    return pairs;
}

// Example
console.log(solution(20));  // [ [ 1, 20 ], [ 2, 10 ], [ 4, 5 ] ]
console.log(solution(36));  // [ [ 1, 36 ], [ 2, 18 ], [ 3, 12 ], [ 4, 9 ], [ 6, 6 ] ]

 

자바스크립트에서 (,)을 쓰면 튜플이 생성되는 게 아님.

소괄호 () 안에 ,를 사용하면 그냥 뒤의 값으로 평가됨.

function solution(n) {
    let pairs = [];

    for (let i = 1; i <= n; i++) {
        if (n % i === 0) {
            pairs.push((i, n / i));  // n / i 만 나옴
        }
    }

    return pairs;
}

// Example
console.log(solution(20));
// [ 20, 10, 5, 4, 2, 1 ]

 

728x90