코딩 공부/코딩테스트

자바스크립트 코딩테스트 입문 (22)

천서리 2023. 6. 6. 01:06
QUOTE THE DAY

“ 당신이 6개월 이상 한 번도 보지 않은 코드는 다른 사람이 다시 만드는 게 훨씬 더 나을 수 있다. ”

- 이글슨 (Eagleson)
반응형

코딩테스트 입문 Day 22 dp, 수학, 조건문, 배열

출처 : https://programmers.co.kr/

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


저주의 숫자 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

 

입출력 예 설명

 

입출력 예 #1

  • 15를 3x 마을의 숫자로 변환하면 25입니다.

입출력 예 #2

  • 40을 3x 마을의 숫자로 변환하면 76입니다.

 

solution.js

function solution(n) {
    let arr = [];
    let num = 0;
    while (arr.length !== n && ++num) if (num%3!==0 && !(''+num).includes('3')) arr.push(num);
    return arr.pop();
}
  1. 먼저 빈 배열 arr을 선언합니다.
  2. 변수 num을 0으로 초기화합니다.
  3. arr의 길이가 n과 같지 않을 때까지 반복합니다.
  4. 반복문에서 num을 1씩 증가시킵니다.
  5. 만약 num이 3의 배수가 아니고, 문자열로 변환한 후에 '3'을 포함하지 않는다면, 조건이 참이 되어 arr에 num을 추가합니다.
  6. 반복문이 종료되면 arr의 마지막 요소를 반환합니다.

평행

문제

점 네 개의 좌표를 담은 이차원 배열  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

 

입출력 예 설명

 

입출력 예 #1

  • 점 [1, 4], [3, 8]을 잇고 [9, 2], [11, 6]를 이으면 두 선분은 평행합니다.

입출력 예 #2

  • 점을 어떻게 연결해도 평행하지 않습니다.

 

solution.js

function solution(dots) {
  const [p1, p2, p3, p4] = dots;

  const slope1 = (p2[1] - p1[1]) / (p2[0] - p1[0]);
  const slope2 = (p3[1] - p2[1]) / (p3[0] - p2[0]);

  const parallel1 = slope1 === (p4[1] - p3[1]) / (p4[0] - p3[0]);
  const parallel2 = slope1 === (p4[1] - p2[1]) / (p4[0] - p2[0]);
  const parallel3 = slope2 === (p4[1] - p1[1]) / (p4[0] - p1[0]);

  if (parallel1 || parallel2 || parallel3) {
    return 1;
  } else {
    return 0;
  }
}
  1. 주어진 4개의 점을 p1, p2, p3, p4로 분해하여 변수에 할당합니다.
  2. 두 개의 점으로 만들어지는 선분의 기울기를 계산합니다. 이를 위해 slope1은 p1과 p2의 기울기를, slope2는 p2와 p3의 기울기를 계산합니다.
  3. 각 점을 기준으로 다른 두 개의 점과의 기울기를 계산하여 평행 여부를 확인합니다. 총 3개의 변수 parallel1, parallel2, parallel3를 계산합니다.
  4. parallel1, parallel2, parallel3 중 하나라도 true인 경우, 즉 어느 한 선분이 다른 선분과 평행한 경우 1을 반환합니다.
  5. 위의 조건이 모두 false인 경우, 즉 세 개의 선분이 모두 평행하지 않은 경우 0을 반환합니다.

겹치는 선분의 길이

문제

선분 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

 

입출력 예 설명

 

입출력 예 #1

  • 두 번째, 세 번째 선분 [2, 5], [3, 9]가 [3, 5] 구간에 겹쳐있으므로 2를 return 합니다.

입출력 예 #2

  • 겹친 선분이 없으므로 0을 return 합니다.

입출력 예 #3

  • 첫 번째와 두 번째 선분이 [3, 5] 구간에서 겹칩니다.
  • 첫 번째와 세 번째 선분 [1, 5] 구간에서 겹칩니다.
  • 두 번째와 세 번째 선분 [3, 9] 구간에서 겹칩니다.
  • 따라서 [1, 9] 구간에 두 개 이상의 선분이 겹쳐있으므로, 8을 return 합니다.

 

solution.js

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)
}
  1. 길이가 200이고 모든 요소가 0인 배열 line을 생성합니다.
  2. lines 배열을 forEach 메서드를 사용하여 각 선분을 순회합니다.
  3. 각 선분을 [a, b] 형태로 받아와서, a부터 b까지의 구간을 반복합니다.
  4. 구간 내의 인덱스에 해당하는 line 배열의 요소 값을 1씩 증가시킵니다. 인덱스 a+100은 -100부터 99까지의 범위를 나타냅니다.
  5. 모든 선분에 대한 처리가 완료되면, line 배열을 reduce 메서드를 사용하여 요소를 순회합니다.
  6. 각 요소 c가 1보다 큰 경우, 즉 겹치는 구간이 있다면 a에 1을 더하고 그렇지 않으면 그대로 유지합니다.
  7. reduce 메서드가 완료되면 최종 결과값 a를 반환합니다.

유한소수 판별하기

문제

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

  • 기약분수로 나타내었을 때, 분모의 소인수가 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

 

입출력 예 설명

 

입출력 예 #1

  • 분수 7/20은 기약분수 입니다. 분모 20의 소인수가 2, 5 이기 때문에 유한소수입니다. 따라서 1을 return합니다.

입출력 예 #2

  • 분수 11/22는 기약분수로 나타내면 1/2 입니다. 분모 2는 소인수가 2 뿐이기 때문에 유한소수 입니다. 따라서 1을 return합니다.

입출력 예 #3

  • 분수 12/21는 기약분수로 나타내면 4/7 입니다. 분모 7은 소인수가 7 이므로 무한소수입니다. 따라서 2를 return합니다.

 

Hint

  • 분자와 분모의 최대공약수로 약분하면 기약분수를 만들 수 있습니다.
  • 정수도 유한소수로 분류합니다.

 

solution.js

function solution(a, b) {
  const gcd = getGCD(a, b);
  
  const numerator = a / gcd;
  const denominator = b / gcd;
  
  if (isFiniteFraction(denominator)) {
    return 1;
  } else {
    return 2;
  }
}

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

function isFiniteFraction(num) {
  while (num % 2 === 0) {
    num /= 2;
  }
  while (num % 5 === 0) {
    num /= 5;
  }
  
  return num === 1;
}
  1. getGCD 함수를 사용하여 a와 b의 최대공약수(gcd)를 계산합니다.
  2. gcd를 사용하여 기약분수로 만듭니다. numerator는 a를 gcd로 나눈 값이고, denominator는 b를 gcd로 나눈 값입니다.
  3. denominator의 소인수를 확인합니다. 이를 위해 isFiniteFraction 함수를 사용합니다.
  4. isFiniteFraction 함수에서는 num이 2로 나누어질 수 있는 동안 2로 나누고, 5로 나누어질 수 있는 동안 5로 나눕니다.
  5. num이 1이 되면 denominator는 2와 5를 소인수로 갖지 않으므로 유한한 소수입니다. 따라서 1을 반환합니다.
  6. 그렇지 않으면 denominator는 2와 5 이외의 다른 소인수를 가지므로 무한한 소수입니다. 따라서 2를 반환합니다.

이 함수의 목표는 입력된 분수 a/b가 유한한 소수인지 무한한 소수인지 판단하는 것입니다. 반환되는 값은 유한한 소수인 경우 1을, 무한한 소수인 경우 2를 나타냅니다.

 

예를 들어, a가 5이고 b가 2인 경우, 분수 5/2는 무한한 소수입니다. 따라서 solution(5, 2)를 호출하면 2가 반환됩니다.

반응형
Adventure Time - BMO