Front-End

프로그래머스 기초트레이닝 16일차 본문

알고리즘

프로그래머스 기초트레이닝 16일차

jeongsso 2023. 10. 3. 08:54

 

 

문제 78.  주사위 게임


문제 설명

1부터 6까지 숫자가 적힌 주사위가 세 개 있습니다.

세 주사위를 굴렸을 때 나온 숫자를 각각 a, b, c라고 했을 때 얻는 점수는 다음과 같습니다.

세 숫자가 모두 다르다면 a + b + c 점을 얻습니다.
세 숫자 중 어느 두 숫자는 같고 나머지 다른 숫자는 다르다면 (a + b + c) × (a2 + b2 + c2 )점을 얻습니다.
세 숫자가 모두 같다면 (a + b + c) × (a2 + b2 + c2 ) × (a3 + b3 + c3 )점을 얻습니다.
세 정수 a, b, c가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.

 

 

입출력 예

a b c result
2 6 1 9
5 3 3 473
4 4 4 110592

 

 

입출력 예 설명

예제 1번에서 세 주사위 숫자가 모두 다르므로 2 + 6 + 1 = 9점을 얻습니다. 따라서 9를 return 합니다.

예제 2번에서 두 주사위 숫자만 같으므로 (5 + 3 + 3) × (52 + 32 + 32 ) = 11 × 43 = 473점을 얻습니다. 따라서 473을 return 합니다.

예제 3번에서 세 주사위 숫자가 모두 같으므로 (4 + 4 + 4) × (42 + 42 + 42 ) × (43 + 43 + 43 ) = 12 × 48 × 192 = 110,592점을 얻습니다. 따라서 110592를 return 합니다.

 

 

저의 풀이!

function solution(a, b, c) {
    let 다더한거 = a + b + c;
    let 제곱 = a ** 2 + b ** 2 + c ** 2;
    let 세제곱 = a ** 3 + b ** 3 + c ** 3;

    if (a !== b && b !== c && c !== a) {
        return 다더한거;
    } else if (a === b && b === c) {
        return 다더한거 * 제곱 * 세제곱;
    } else {
        return 다더한거 * 제곱;
    }
}

console.log(solution(4, 4, 4));

 

 

메모

조건문을 사용하되, 풀이들이 복잡해서 변수로 넣어서 코드를 작성했다.

이게 최선으로 한건데.. 혹시 다른 방법이 있는지 찾아보는것도 좋을 것같다.

 

 

 

문제 79.  배열 만들기 3


문제 설명

정수 배열 arr와 2개의 구간이 담긴 배열 intervals가 주어집니다.

intervals는 항상 [[a1, b1], [a2, b2]]의 꼴로 주어지며 각 구간은 닫힌 구간입니다. 
닫힌 구간은 양 끝값과 그 사이의 값을 모두 포함하는 구간을 의미합니다.

이때 배열 arr의 첫 번째 구간에 해당하는 배열과 두 번째 구간에 해당하는 배열을 앞뒤로 붙여
새로운 배열을 만들어 return 하는 solution 함수를 완성해 주세요.

 

입출력 예

arr intervals result
[1, 2, 3, 4, 5] [[1, 3], [0, 4]] [2, 3, 4, 1, 2, 3, 4, 5]

 

 

입출력 예 설명

첫 번째 구간에 해당하는 배열은 [2, 3, 4] 입니다.
두 번째 구간에 해당하는 배열은 [1, 2, 3, 4, 5] 입니다.
따라서 이 두 배열을 앞뒤로 붙인 배열인 [2, 3, 4, 1, 2, 3, 4, 5]를 return 합니다.

 

저의 풀이!

function solution(arr, intervals) {
    let 첫번째 = arr.slice(intervals[0][0], intervals[0][1] + 1);
    let 두번째 = arr.slice(intervals[1][0], intervals[1][1] + 1);

    return [...첫번째, ...두번째];
}

console.log(
    solution(
        [1, 2, 3, 4, 5],
        [
            [1, 3],
            [0, 4],
        ]
    )
);

 

 

메모

slice를 이용해서 합쳐야할 배열 앞 뒤를 변수에 담아두고, 
담긴 변수 배열을 스프레드를 이용해서 배열을 하나로 합쳤습니다.

구조분해 할당으로도 풀 수 있어서 풀어봤습니다.

[[a, b], [c, d]] 로 a, b, c, d 변수로 알아보기 쉽게 코드를 작성할 수 있습니다.

function solution1(arr, intervals) {
    const [[a, b], [c, d]] = intervals;
    return [...arr.slice(a, b + 1), ...arr.slice(c, d + 1)];
}
 
console.log(
    solution1(
        [1, 2, 3, 4, 5],
        [
            [1, 3],
            [0, 4],
        ]
    )
);

 

 

 

 

 

문제 80.  9로 나눈 나머지


문제 설명

음이 아닌 정수를 9로 나눈 나머지는 그 정수의 각 자리 숫자의 합을 9로 나눈 나머지와 같은 것이 알려져 있습니다.
이 사실을 이용하여 음이 아닌 정수가 문자열 number로 주어질 때, 
이 정수를 9로 나눈 나머지를 return 하는 solution 함수를 작성해주세요.

입출력 예

number result
"123" 6
"78720646226947352489" 2

 

 

입출력 예 설명

예제 1번의 number는 123으로 각 자리 숫자의 합은 6입니다. 6을 9로 나눈 나머지는 6이고, 
실제로 123 = 9 × 13 + 6입니다. 따라서 6을 return 합니다.

예제 2번의 number는 78720646226947352489으로 각자리 숫자의 합은 101입니다. 
101을 9로 나눈 나머지는 2이고, 
실제로 78720646226947352489 = 9 × 8746738469660816943 + 2입니다. 따라서 2를 return 합니다.

 

 

저의 풀이!

function solution(number) {
    return [...number].reduce((a, c) => a + +c) % 9;
}

console.log(solution('123'));

 

 

메모

저의 풀이는 reduce를 이용해서 현재값에 누산기를 더하면서 나온 값을 9로 나눈 나머지값이 출력되도록 풀었습니다.
그치만 '78720646226947352489' 이 값에 대해서는 계산하지 못했습니다.
왜냐하면 자바스크립트가 읽을 수 있는 최대의 숫자보다 크기 때문에 인식을 못해서 그렇다고 합니다.
그래서 만약 저 숫자를 자바스크립트가 읽도록 하고 싶다면 정수 크기제한을 늘려주는 메서드를 사용하면 된다고 해서 풀어봤습니다. 

const solution3 = number => BigInt(number) % 9n;

console.log(solution3('78720646226947352489'));

 

기본적으로 사용하는 반복문을 이용해서도 문제를 풀 수 있습니다.

answer라는 변수에 숫자를 담아서 number의 length 만큼 그자리의 글자를 숫자로 변경해서 더해주는 식으로 answer를 업데이트하고,

그 후에 9로 나눈 나머지 값을 출력하도록 설정했습니다.

 

function solution1(number) {
    let answer = 0;

    for (let i = 0; i < number.length; i++) {
        answer += Number(number[i]);
    }
    return answer % 9;
}

console.log(solution1('78720646226947352489'));

 

 

 

 

문제 81.  수 조작하기 2


문제 설명

정수 배열 numLog가 주어집니다.
처음에 numLog[0]에서 부터 시작해 "w", "a", "s", "d"로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다고 합시다.

"w" : 수에 1을 더한다.
"s" : 수에 1을 뺀다.
"d" : 수에 10을 더한다.
"a" : 수에 10을 뺀다.
그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog입니다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있습니다.

주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 함수를 완성해 주세요.

입출력 예

numLog result
[0, 1, 0, 10, 0, 1, 0, 10, 0, -1, -2, -1] "wsdawsdassw"

 

 

입출력 예 설명

result인 "wsdawsdassw"를 따라 numLog[0]에서부터 시작해 조작을 하면
numLog의 값과 순서대로 일치합니다. 따라서 "wsdawsdassw"를 return 합니다.

 

 

저의 풀이!

function solution(numLog) {
    let answer = '';

    for (let i = 1; i < numLog.length; i++) {
        let 차이 = numLog[i] - numLog[i - 1];

        if (차이 === 1) {
            answer += 'w';
        } else if (차이 === -1) {
            answer += 's';
        } else if (차이 === 10) {
            answer += 'd';
        } else if (차이 === -10) {
            answer += 'a';
        }
    }
    return answer;
}

console.log(solution([0, 1, 0, 10, 0, 1, 0, 10, 0, -1, -2, -1]));

 

 

메모

차이라는 변수는 numLog의 숫자에 계산되었던 게 어떤식인지 확인 하기 위해 만든 변수입니다.
그 변수가 무엇인가에 따라서 answer에 글자가 추가되게끔 식을 만들었습니다.

 

 

 

 

문제 82.  등차수열의 특정한 항만 더하기


문제 설명

두 정수 a, d와 길이가 n인 boolean 배열 included가 주어집니다.
첫째항이 a, 공차가 d인 등차수열에서 included[i]가 i + 1항을 의미할 때,
이 등차수열의 1항부터 n항까지 included가 true인 항들만 더한 값을 return 하는 solution 함수를 작성해 주세요.

 

입출력 예

a d included result
3 4 [true, false, false, true, true] 37
7 1 [false, false, false, true, false, false, false] 10

 

 

입출력 예 설명

예제 1번은 a와 d가 각각 3, 4이고 included의 길이가 5입니다. 이를 표로 나타내면 다음과 같습니다.

1항    2항   3항    4항   5항
 3       7      11      15     19
true false false true true
따라서 true에 해당하는 1항, 4항, 5항을 더한 3 + 15 + 19 = 37을 return 합니다.

 

 

저의 풀이!

function solution(a, d, included) {
    let answer = [a];

    for (let i = 0; i < included.length; i++) {
        answer.push(answer[i] + d);
    }
    return answer.filter((_, i) => (a = included[i])).reduce((a, c) => a + c);
}

console.log(solution(3, 4, [true, false, false, true, true]));

 

 

메모

일단 저는 등차수열을 배열에 담아두고, filter를 이용해서 included가 true인 경우만 빼낸 후 reduce로 그 값들을 더해주었습니다.
알고리즘 고수님왈 : 이건 등차수열에 쓰는 식이 따로 또 있습니다!!

function solution1(a, d, included) {
    let answer = 0;

    for (let i = 0; i < included.length; i++) {
        if (included[i]) {
            answer += a + i * d;
        }
    }
    return answer;
}
console.log(solution1(3, 4, [true, false, false, true, true]));

저 코드를 보면 a + i * d 가 되어있는데 이 계산 식이 등차수열을 나타내는 식이라고 합니다 ㅎㅎㅎ
저는 몰랏지만~ 여튼 그렇다고 하니 알아두면 이해하고 풀기 좋습니다.

 

 

 

 

 

문제 83.  세로 읽기


문제 설명

문자열 my_string과 두 정수 m, c가 주어집니다.
my_string을 한 줄에 m 글자씩 가로로 적었을 때
왼쪽부터 세로로 c번째 열에 적힌 글자들을 문자열로 return 하는 solution 함수를 작성해 주세요.

 

입출력 예

my_string m c result
"ihrhbakrfpndopljhygc" 4 2 "happy"
"programmers" 1 1 "programmers"

 

 

입출력 예 설명

예제 1번의 my_string을 한 줄에 4 글자씩 쓰면 다음의 표와 같습니다.


2열에 적힌 글자를 세로로 읽으면 happy이므로 "happy"를 return 합니다.

 

 

예제 2번의 my_string은 m이 1이므로 세로로 "programmers"를 적는 것과 같고 따라서 1열에 적힌 글자를 세로로 읽으면 programmers입니다. 따라서 "programmers"를 return 합니다.

 

저의 풀이!

function solution(my_string, m, c) {
    let answer = '';

    for (let i = 0; i < my_string.length / m; i++) {
        answer += my_string[i * m + c - 1];
    }
    return answer;
}

console.log(solution('ihrhbakrfpndopljhygc', 4, 2));

 

 

메모

i의 조건을 보면 my_string.length / m 으로 되어있는데, 이유는 m글자씩 가로로 적을 때 c 번째의 글자들을 모아서 
리턴하면 되기 때문에

생각한게 length 를 m으로 나눠서 c번째에 있는 글씨를 변수에 담으면되겠다 생각해서 /m을 적어서 풀이했습니다.

 

 

 
Comments