Bomb Kirby Running

코딩 테스트 챌린지

코딩 테스트 22

^. ̫ .^ 2023. 6. 6. 23:45

728x90

문제1 저주의 숫자3

3x 마을 사람들은 3을 저주의 숫자라고 생각하기 때문에 3의 배수와 숫자 3을 사용하지 않습니다. 3x 마을 사람들의 숫자는 다음과 같습니다.

10진법 3x 마을에서 쓰는 숫자 10진법 3x 마을에서 쓰는 숫자
1 1 6 8
2 2 7 10
3 4 8 11
4 5 9 14
5 7 10 16

정수 n이 매개변수로 주어질 때, n을 3x 마을에서 사용하는 숫자로 바꿔 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • 1 ≤ n ≤ 100

입출력 예

n result
15 25
40 76
function solution(n) {
    let result = 0;
    let count = 0;

    while (true) {
        result++;

        if (result % 3 === 0 || result.toString().includes('3')) {
            continue;
        }

        count++;

        if (count === n) {
            break;
        }
    }

    return result;
}


 `answer` 변수는 변환된 숫자를 저장하기 위한 변수이고, `count` 변수는 변환된 숫자의 카운트를 저장하기 위한 변수입니다.
`while` 반복문은 `count` 변수가 n보다 작은 동안 반복됩니다. 반복문 안에서는 `answer` 변수를 1씩 증가시키면서 변환된 숫자를 찾습니다.
`if` 문에서는 현재 숫자가 3의 배수가 아니고, 숫자에 3이 포함되어 있지 않은지를 확인합니다. 만약 해당되는 경우라면 `count` 변수를 1 증가시킵니다. 이렇게 함으로써 변환된 숫자의 카운트를 증가시키고, n번째 숫자까지 카운트를 증가시키면 반복문이 종료됩니다.
 마지막으로, `answer` 변수를 반환하여 변환된 숫자를 출력합니다.

 

문제2 평행

점 네 개의 좌표를 담은 이차원 배열  dots가 다음과 같이 매개변수로 주어집니다

  • [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]

주어진 네 개의 점을 두 개씩 이었을 때, 두 직선이 평행이 되는 경우가 있으면 1을 없으면 0을 return 하도록 solution 함수를 완성해보세요.

 

제한사항

  • dots의 길이 = 4
  • dots의 원소는 [x, y] 형태이며 x, y는 정수입니다.
    • 0 ≤ x, y ≤ 100
  • 서로 다른 두개 이상의 점이 겹치는 경우는 없습니다.
  • 두 직선이 겹치는 경우(일치하는 경우)에도 1을 return 해주세요.
  • 임의의 두 점을 이은 직선이 x축 또는 y축과 평행한 경우는 주어지지 않습니다.

입출력 예

dots result
[[1, 4], [9, 2], [3, 8], [11, 6]] 1
[[3, 5], [4, 1], [2, 4], [5, 10]] 0

 

function solution(dots) {
    if (calculateSlope(dots[0], dots[1]) === calculateSlope(dots[2], dots[3]))
        return 1;
    if (calculateSlope(dots[0], dots[2]) === calculateSlope(dots[1], dots[3]))
        return 1;
    if (calculateSlope(dots[0], dots[3]) === calculateSlope(dots[1], dots[2]))
        return 1;
    return 0;
}

function calculateSlope(arr1, arr2) {
    return (arr2[1] - arr1[1]) / (arr2[0] - arr1[0]);
}

 

`calculateSlope` 함수를 정의합니다. 
`solution` 함수에서는 세 가지 경우를 확인합니다.
   - 첫 번째 조합: dots[0]-dots[1]와 dots[2]-dots[3]의 기울기가 같은지 확인합니다.
   - 두 번째 조합: dots[0]-dots[2]와 dots[1]-dots[3]의 기울기가 같은지 확인합니다.
   - 세 번째 조합: dots[0]-dots[3]와 dots[1]-dots[2]의 기울기가 같은지 확인합니다.
위 세 가지 조합 중 어느 하나라도 기울기가 같은 경우, 즉 두 직선이 평행한 경우 1을 반환합니다. 그렇지 않으면 0을 반환합니다.

문제3 겹치는 선분의 길이

선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

 

lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.

선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.

 

제한사항

  • lines의 길이 = 3
  • lines의 원소의 길이 = 2
  • 모든 선분은 길이가 1 이상입니다.
  • lines의 원소는 [a, b] 형태이며, a, b는 각각 선분의 양 끝점 입니다.
    • -100 ≤ a < b ≤ 100

입출력 예

lines result
[[0, 1], [2, 5], [3, 9]] 2
[[-1, 1], [1, 3], [3, 9]] 0
[[0, 5], [3, 9], [1, 10]] 8
function solution(lines) {
    let line = new Array(200).fill(0);

    lines.forEach(([a, b]) => {
        for(; a < b; a++) line[a+100]++;
    });

    return line.reduce((a, c) =>  c > 1 ? a + 1 : a, 0)
}


길이가 200인 배열 `line`을 생성하고 0으로 초기화합니다. 이 배열은 -100부터 99까지의 인덱스를 갖습니다.
lines` 배열의 각 요소 `[a, b]`에 대해서, `a`부터 `b-1`까지 반복하면서 `line` 배열의 해당 인덱스 값을 1씩 증가시킵니다. 이는 해당 구간에 선분이 겹치는 횟수를 카운트하는 것입니다.
`line` 배열을 순회하면서 값이 2 이상인 요소의 개수를 세어 반환합니다. 이는 두 개 이상의 선분이 겹치는 구간의 개수를 나타냅니다.

 

문제4 유한소수 판별하기

소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

  • 기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.

두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.

 

제한사항

  • a, b는 정수
  • 0 < a ≤ 1,000
  • 0 < b ≤ 1,000

입출력 예

a b result
7 20 1
11 22 1
12 21 2
function solution(a, b) {
    let gcd = getGCD(a, b); 
    b /= gcd; 

    while (b % 2 === 0) {
        b /= 2;
    }

    while (b % 5 === 0) {
        b /= 5;
    }

    if (b === 1) {
        return 1; 
    } else {
        return 2; 
    }
}


function getGCD(a, b) {
    if (b === 0) {
        return a;
    } else {
        return getGCD(b, a % b);
    }
}

 

`getGCD` 함수는 두 수의 최대공약수를 구하는 함수입니다. 유클리드 호제법을 사용하여 재귀적으로 최대공약수를 구합니다.

`solution` 함수에서는 주어진 분자 `a`와 분모 `b`를 입력받습니다.
먼저, 최대공약수 `gcd`를 구합니다. 이를 통해 분자와 분모를 서로소로 만들어 기약분수를 만들기 위함입니다.
분모 `b`를 최대공약수 `gcd`로 나누어 기약분수로 만듭니다.
그 후, 분모 `b`를 2와 5로 나눌 수 있는 만큼 나누어줍니다. 이는 유한소수 여부를 판별하기 위한 과정입니다.

만약 `b`가 1이 되었다면, 2와 5로만 소인수분해되므로 유한소수로 판정합니다. 따라서 1을 반환합니다.
 그렇지 않은 경우, 2와 5 이외의 다른 소수로도 나누어진다는 의미이므로 무한소수로 판정합니다. 따라서 2를 반환합니다.

 

유클리드 호제법

유클리드 호제법(Euclidean algorithm)은 두 수의 최대공약수를 구하는 알고리즘입니다. 주어진 두 수를 이용하여 재귀적으로 최대공약수를 구하는 방법입니다.

두 수 a와 b의 최대공약수를 구하려면 다음과 같이 합니다:

1. 만약 b가 0이라면, a가 최대공약수입니다. 즉, `gcd(a, 0) = a`입니다.
2. 그렇지 않다면, b로 a를 나눈 나머지를 구합니다. `r = a % b`.
3. 이제 b와 r의 최대공약수를 구합니다. `gcd(b, r)`을 재귀적으로 호출합니다.
4. 위 과정을 반복하여 b가 0이 될 때까지 진행합니다. 최종적으로 a와 b의 최대공약수를 구할 수 있습니다.

이 방법은 두 수를 반복적으로 나누는 과정을 통해 최대공약수를 구하는데, 이러한 과정을 유클리드 호제법이라고 합니다. 이 알고리즘은 수의 크기에 상관없이 효율적으로 최대공약수를 계산할 수 있습니다.

예를 들어, 48과 18의 최대공약수를 구하는 경우:

1. 48을 18로 나눈 나머지는 12입니다. (`48 % 18 = 12`)
2. 18을 12로 나눈 나머지는 6입니다. (`18 % 12 = 6`)
3. 12를 6으로 나눈 나머지는 0입니다. (`12 % 6 = 0`)
4. 나머지가 0이 되면, 직전의 나누는 수인 6이 최대공약수입니다. 따라서 48과 18의 최대공약수는 6입니다.