문제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입니다.