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

[프로그래머스] 입문 Day 10 조건문, 배열, 수학, 시뮬레이션 (Javascript)

꼽파 2023. 12. 19. 19:04


점의 위치 구하기

문제 설명
사분면은 한 평면을 x축과 y축을 기준으로 나눈 네 부분입니다. 사분면은 아래와 같이 1부터 4까지 번호를 매깁니다.

  • x 좌표와 y 좌표가 모두 양수이면 제1사분면에 속합니다.
  • x 좌표가 음수, y 좌표가 양수이면 제2사분면에 속합니다.
  • x 좌표와 y 좌표가 모두 음수이면 제3사분면에 속합니다.
  • x 좌표가 양수, y 좌표가 음수이면 제4사분면에 속합니다.
  • x 좌표 (x, y)를 차례대로 담은 정수 배열 dot이 매개변수로 주어집니다. 좌표 dot이 사분면 중 어디에 속하는지 1, 2, 3, 4 중 하나를 return 하도록 solution 함수를 완성해주세요.

제한사항

  • dot의 길이 = 2
  • dot[0]은 x좌표를, dot[1]은 y좌표를 나타냅니다.
  • -500 ≤ dot의 원소 ≤ 500
  • dot의 원소는 0이 아닙니다.

입출력 예

dot result
[2, 4] 1
[-7, 9] 2

 

풀이 1

if - else if 조건문을 사용함

function solution(dot) {
    
    let answer = 0;
    // x, y 좌표가 각각 양수 혹은 음수인지 판별
    if (dot[0] > 0 && dot[1] > 0) {
        answer = 1;
    } else if (dot[0] < 0 && dot[1] > 0) {
        answer = 2;
    } else if (dot[0] < 0 && dot[1] < 0) {
        answer = 3;
    } else {
        answer = 4;
    }

    return answer;
}

 

풀이 2

구조분해 할당과 삼항연산자로 더 간결하게 씀.

function solution(dot) {
    const [num1, num2] = dot;
    const check = num1 > 0 && num2 > 0;  
    
    if (num1 > 0) {  // num1 > 0
        return num2 > 0 ? 1 : 4
    } else {  // num1 < 0
        return num2 < 0 ? 3 : 2
    }
}
function solution(dot) {
    const [num,num2] = dot;
    const check = num * num2 > 0;
    return num > 0 ? (check ? 1 : 4) : (check ? 3 : 2);
}

 

위 풀이에서 사용된 삼항연산자를 풀어쓰면 다음과 같음.

if (num1 > 0) {
    if (check) {
        return 1;  // num1 > 0, num 2 > 0
    } else {
        return 4;  // num1 > 0, num 2 < 0
    }
} else {
    if (check) {
        return 3;  // num 1 < 0, num 2 < 0
    } else {
        return 2;  // num 1 < 0, num 2 > 0
    }
}

 

참고 : 구조 분해 할당을 하는 이유

// 구조분해 할당 X
const num1 = dot[0];
const num2 = dot[1];

// 구조분해 할당 O
const [num1, num2] = dot;

코드가 더 간결해진다.

이 문제에서는 할당할 요소가 2개라서 별 차이가 없지만, 객체나 배열의 요소 개수가 많으면 더 유용함.


2차원으로 만들기

문제 설명

  • 정수 배열 num_list와 정수 n이 매개변수로 주어집니다. num_list를 다음 설명과 같이 2차원 배열로 바꿔 return하도록 solution 함수를 완성해주세요.
  • num_list가 [1, 2, 3, 4, 5, 6, 7, 8] 로 길이가 8이고 n이 2이므로 num_list를 2 * 4 배열로 다음과 같이 변경합니다. 2차원으로 바꿀 때에는 num_list의 원소들을 앞에서부터 n개씩 나눠 2차원 배열로 변경합니다.

제한사항

  • num_list의 길이는 n의 배 수개입니다.
  • 0 ≤ num_list의 길이 ≤ 150
  • 2 ≤ n < num_list의 길이

입출력 예

num_list n result
[1, 2, 3, 4, 5, 6, 7, 8] 2 [[1, 2], [3, 4], [5, 6], [7, 8]]
[100, 95, 2, 4, 5, 6, 18, 33, 948]  3 [[100, 95, 2], [4, 5, 6], [18, 33, 948]]

 

풀이 1

for문과 slice를 통한 부분 배열 생성

function solution(num_list, n) {
    // num_list.length에서 n을 나눔
    // n이 이차원 배열 원소 하나의 길이
    // 나눈 몫이 배열의 개수
    var answer = [];
    for (i = 0; i < num_list.length; i = i + n) {
        arr = num_list.slice(i, i + n)  // 배열 길이가 n인 부분 배열
        answer.push(arr)
    }
    return answer;
}

 

풀이 2

while문과 splice를 활용

function solution(num_list, n) {
    var answer = [];

    while(num_list.length) {  // 원본 배열의 길이가 0이 될 때까지 반복
        answer.push(num_list.splice(0,n));  // 0부터 시작해서 n개 추출
    }

    return answer;
}

 

slice 메서드를 사용하면 원본 배열의 해당 부분이 삭제되는 걸 확인할 수 있음.

    while(num_list.length) {
        answer.push(num_list.splice(0,n));
        console.log(num_list);  // num_list가 어떻게 변하는지 확인
    }

 

주의할 점

  • 풀이2 같은 기발한 방법은 어떻게 생각해내는지 모르곘음.

공 던지기

문제 설명

  • 머쓱이는 친구들과 동그랗게 서서 공 던지기 게임을 하고 있습니다. 공은 1번부터 던지며 오른쪽으로 한 명을 건너뛰고 그다음 사람에게만 던질 수 있습니다. 친구들의 번호가 들어있는 정수 배열 numbers와 정수 K가 주어질 때, k번째로 공을 던지는 사람의 번호는 무엇인지 return 하도록 solution 함수를 완성해보세요.

제한사항

  • 2 < numbers의 길이 < 100
  • 0 < k < 1,000
  • numbers의 첫 번째와 마지막 번호는 실제로 바로 옆에 있습니다.
  • numbers는 1부터 시작하며 번호는 순서대로 올라갑니다.

입출력 예

numbers k result
[1, 2, 3, 4] 2 3
[1, 2, 3, 4, 5, 6] 5 3
[1, 2, 3] 3 2

 

 

• 한 칸씩 이동하는 경우

2번째로 공을 던진다고 가정 현재 인덱스 (0) + 1
4번째로 공을 던진다고 가정 현재 인덱스 (0) + 3

→ 현재 인덱스 + (k - 1)을 하면 구할 수 있음

 

• 두 칸씩 이동하는 경우 (해당 문제)

2번째로 공을 던진다고 가정 현재 인덱스 (0) + (2 - 1) * 2 = 2 (숫자는 3)
5번째로 공을 던진다고 가정 (k = 5) 현재 인덱스 (0) + (5 - 1) * 2 = 8 (숫자는 3)

→ 현재 인덱스 + (k - 1) * 2를 하면 구할 수 있음

 

그런데 8은 배열의 길이에서 벗어남.

 해당 인덱스값을 배열의 길이만큼 나눈 나머지를 구하면 됨.

8을 배열의 길이(6)을 나눈 나머지가 2이므로

주어진 배열에서 인덱스 2에 해당하는 원소인 3이 답이 됨.

 

이를 코드로 일반화 시켜보면 다음과 같음.

function solution(numbers, k) {

    // 현재 위치의 인덱스
    current_index = 0; 
    
    // k번째 공을 던질 선수의 위치(인덱스)
    player_index =  current_index + (k - 1) * 2; 
    
    // 인덱스가 배열의 길이를 넘어가는 경우
    // → 인덱스는 인덱스에서 배열의 길이를 나눈 나머지
    if (player_index > numbers.length) {
        answer = player_index % numbers.length
    } else {
        answer = player_index
    }

    // numbers의 배열의 해당 인덱스에 맞는 원소를 출력
    return numbers[answer];

}

 

주의할 점

  • 이 문제는 시작 위치가 1번(인덱스 0)으로 고정되어 있다.
  • 그래서 사람들이 현재 인덱스 값은 굳이 표기하지 않았는데, 만약 시작 위치가 달라지는 경우는 현재 인덱스도 변수로 만들어서 풀어야 함.
  • 문제를 이해하는 건 어렵지 않은데, 논리적으로 구현하는 것이 약간 힘든 듯 싶다.

배열 회전시키기

문제 설명

  • 정수가 담긴 배열 numbers와 문자열 direction가 매개변수로 주어집니다. 배열 numbers의 원소를 direction방향으로 한 칸씩 회전시킨 배열을 return하도록 solution 함수를 완성해주세요.

제한사항

  • 3 ≤ numbers의 길이 ≤ 20
  • direction은 "left" 와 "right" 둘 중 하나입니다.

입출력 예

numbers  direction result
[1, 2, 3] "right" [3, 1, 2]
[4, 455, 6, 4, -1, 45, 6] "left" [455, 6, 4, -1, 45, 6, 4]

 

풀이 1

스프레드 연산자와 slice 메소드 사용

function solution(numbers, direction) {
    // 배열을 슬라이싱
    var answer = [];
    var end = numbers.length
    // 오른쪽 이동
    // 맨 뒤에 있는 거 맨 앞으로 이동 + 기존 배열의 인덱스 0부터 끝 - 1까지
    if (direction == "right") {
        answer = [numbers[end - 1], ...numbers.slice(0, end - 1)]
    } else {
    // 왼쪽 이동
    // 기존 배열 인덱스 1부터 끝까지 + 맨 앞에 있는거 맨 뒤로 이동
        answer = [...numbers.slice(1, ), numbers[0]]             
    }
    return answer;
}

 

풀이 2

unshift, shift, push, pop 메소드 이용

function solution(numbers, direction) {
    
    var answer = [];
    
    if (direction == "right") { // 맨 마지막 것이 맨 앞으로
        numbers.unshift(numbers.pop())
    } else {  // 맨 앞의 것이 맨 마지막으로
        numbers.push(numbers.shift())
    }
    answer = numbers
    return answer;
}

 

참고

pop 메소드는 해당 값을 반환함.

The pop() method of Array instances removes the last element from an array and returns that element

728x90