Front-End

프로그래머스 기초트레이닝 23일차(마지막!!!) 본문

알고리즘

프로그래머스 기초트레이닝 23일차(마지막!!!)

jeongsso 2023. 11. 13. 00:57

이제 길고 길던, 기초트레이닝이 끝났습니다!!!

 

 

 

문제 111.  배열 만들기 6


문제 설명

0과 1로만 이루어진 정수 배열 arr가 주어집니다. arr를 이용해 새로운 배열 stk을 만드려고 합니다.

i의 초기값을 0으로 설정하고 i가 arr의 길이보다 작으면 다음을 반복합니다.

만약 stk이 빈 배열이라면 arr[i]를 stk에 추가하고 i에 1을 더합니다.
stk에 원소가 있고, stk의 마지막 원소가 arr[i]와 같으면 stk의 마지막 원소를 stk에서 제거하고 i에 1을 더합니다.
stk에 원소가 있는데 stk의 마지막 원소가 arr[i]와 다르면 stk의 맨 마지막에 arr[i]를 추가하고 i에 1을 더합니다.
위 작업을 마친 후 만들어진 stk을 return 하는 solution 함수를 완성해 주세요.

단, 만약 빈 배열을 return 해야한다면 [-1]을 return 합니다.

 

입출력 예

my_string result
[0, 1, 1, 1, 0] [0, 1, 0]
[0, 1, 0, 1, 0] [0, 1, 0, 1, 0]
[0, 1, 1, 0] [-1]

 

 

입출력 예 설명

 

 

 

 

저의 풀이!

function solution(arr) {
    let stk = [];
   
    for (i = 0; i < arr.length; i++) {
        if (stk.length === 0 || stk[stk.length - 1] !== arr[i]) {
            stk.push(arr[i]);
        } else {
            stk.pop();
        }
    }

    return stk.length === 0 ? [-1] : stk;
}
console.log(solution([0, 1, 1, 1, 0]));

 

 

메모

일단 새로운 배열을 만들라 했으니, stk 변수로 빈배열을 만들어 줍니다!
그리고 조건들을 확인해서 반복문안에 조건을 넣어서 마지막에 내보내주면 됩니다.

 

 

 

 

문제 112.  정사각형으로 만들기


문제 설명

이차원 정수 배열 arr이 매개변수로 주어집니다. 
arr의 행의 수가 더 많다면 열의 수가 행의 수와 같아지도록 각 행의 끝에 0을 추가하고, 
열의 수가 더 많다면 행의 수가 열의 수와 같아지도록 
각 열의 끝에 0을 추가한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.



입출력 예

arr result
[[572, 22, 37], [287, 726, 384], [85, 137, 292], [487, 13, 876]] [[572, 22, 37, 0], [287, 726, 384, 0], [85, 137, 292, 0], [487, 13, 876, 0]]
[[57, 192, 534, 2], [9, 345, 192, 999]] [[57, 192, 534, 2], [9, 345, 192, 999], [0, 0, 0, 0], [0, 0, 0, 0]]
[[1, 2], [3, 4]] [[1, 2], [3, 4]]

 

 

입출력 예 설명

입출력 예 #1
예제 1번의 arr은 행의 수가 4, 열의 수가 3입니다. 행의 수가 더 많으므로 열의 수를 4로 만들기 위해 arr의 각 행의 끝에 0을 추가한 이차원 배열 [[572, 22, 37, 0], [287, 726, 384, 0], [85, 137, 292, 0], [487, 13, 876, 0]]를 return 합니다.

 

입출력 예 #2
예제 2번의 arr은 행의 수가 2, 열의 수가 4입니다. 열의 수가 더 많으므로 행의 수를 4로 만들기 위해 arr의 각 열의 끝에 0을 추가한 이차원 배열 [[57, 192, 534, 2], [9, 345, 192, 999], [0, 0, 0, 0], [0, 0, 0, 0]]을 return 합니다.

 

입출력 예 #3
예제 3번의 arr은 행의 수와 열의 수가 2로 같습니다. 따라서 0을 추가하지 않고 [[1, 2], [3, 4]]을 return 합니다.

 

 

 

저의 풀이!

function solution(arr) {
    let answer = arr;
    let = arr[0].length;
    let = arr.length;

    // 행이 열보다 길경우
    if ( > ) {
         let 차이 = - ;
        let 차이배열 = Array(차이).fill(0);
        return arr.map(a => [...a, ...차이배열]);
    }

    // 행이 열보다 짧은 경우
    if ( < ) {
        let 차이 = - ;
        let 차이배열 = Array().fill(0);

        for (let i = 0; i < 차이; i++) {
            arr.push(차이배열);
        }
    }
    return answer;
}

console.log(
    solution([
        [572, 22, 37],
        [287, 726, 384],
        [85, 137, 292],
        [487, 13, 876],
    ])
);

 

메모

일단 전형적인 행열의 차이를 알아야 한다.

1행은 572 22 37 이고

1열은 572 287 85 487 이다.

이때 행과 열을 변수로 담았습니다. 

행은 arr[0]의 length 이고, 행은 arr의 length이다.

행이 열보다 클 경우 열과 행의 차이만큼 Array(열)로 fill(0) 0으로 새로 배열을 만들어 넣어야 한다.

그리고 arr에 차이만큼 push 하면 된다.

 

 

 

문제 113.  무작위로 K개의 수 뽑기


문제 설명

랜덤으로 서로 다른 k개의 수를 저장한 배열을 만드려고 합니다. 적절한 방법이 떠오르지 않기 때문에 일정한 범위 내에서 무작위로 수를 뽑은 후, 지금까지 나온 적이 없는 수이면 배열 맨 뒤에 추가하는 방식으로 만들기로 합니다.

이미 어떤 수가 무작위로 주어질지 알고 있다고 가정하고, 실제 만들어질 길이 k의 배열을 예상해 봅시다.

정수 배열 arr가 주어집니다. 문제에서의 무작위의 수는 arr에 저장된 순서대로 주어질 예정이라고 했을 때, 완성될 배열을 return 하는 solution 함수를 완성해 주세요.

단, 완성될 배열의 길이가 k보다 작으면 나머지 값을 전부 -1로 채워서 return 합니다.

 

입출력 예

arr k result
[0, 1, 1, 2, 2, 3] 3 [0, 1, 2]
[0, 1, 1, 1, 1] 4 [0, 1, -1, -1]

 

 

입출력 예 설명

입출력 예 #1
앞에서부터 서로 다른 k개의 수를 골라내면 [0, 1, 2]가 됩니다. 따라서 [0, 1, 2]를 return 합니다.

 

입출력 예 #2
서로 다른 수의 개수가 2개뿐이므로 서로 다른 수들을 앞에서부터 차례대로 저장한 [0, 1]에서 이후 2개의 인덱스를 -1로 채워 넣은 [0, 1, -1, -1]을 return 합니다.

 

 

저의 풀이!

function solution(arr, k) {
    const set = new Set(arr);

    return set.size < k
        ? [...set, ...Array(k - set.size).fill(-1)]
        : [...set].slice(0, k);
}

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

 

 

 

메모 

new Set(배열) 메서드는 중복된 항목을 제거하고 남은 항목만 객체로 내뱉어줍니다. 
Set(4) { 0, 1, 2, 3 }   이것처럼 말입니다!

 

객체의 길이를 구하는 법은 length가 아니고 size로 알아볼 수 있습니다.
중복을 제거한 set변수의 길이(size)가 k(길이)까지만 잘라내야 합니다.
조건으로 만약 k보다 set길이가 더 길다면 slice로 잘라내면 되고, 짧다면 -1로 채워 넣어줘야 합니다!

 

 

문제 114. 그림 확대


문제 설명

직사각형 형태의 그림 파일이 있고, 
이 그림 파일은 1 × 1 크기의 정사각형 크기의 픽셀로 이루어져 있습니다.
이 그림 파일을 나타낸 문자열 배열 picture과 정수 k가 매개변수로 주어질 때,
이 그림 파일을 가로 세로로 k배 늘린 그림 파일을 나타내도록 문자열 배열을 return 하는 solution 함수를 작성해 주세요.

 

입출력 예

picture k result
[".xx...xx.", 
 "x..x.x..x",
 "x...x...x",
 ".x.....x.",
 "..x...x..",
 "...x.x...",
 "....x...."]
2 ["..xxxx......xxxx..", 
 "..xxxx......xxxx..",
 "xx....xx..xx....xx",
 "xx....xx..xx....xx",
 "xx......xx......xx",
 "xx......xx......xx",
 "..xx..........xx..",
 "..xx..........xx..",
 "....xx......xx....",
 "....xx......xx....",
 "......xx..xx......",
 "......xx..xx......",
 "........xx........",
 "........xx........"]
["x.x",
  ".x.",
 "x.x"]
3 ["xxx...xxx", 
 "xxx...xxx",
 "xxx...xxx",
 "...xxx...",
 "...xxx...",
 "...xxx...",
 "xxx...xxx",
 "xxx...xxx",
 "xxx...xxx"]

잘 알아보시려나요..?!
위에는 하트고 아래는 

xx

 x

xx 

이 모양입니다.

 

입출력 예 설명

 

 

 

저의 풀이!

function solution(picture, k) {
    let answer = [];

    for (let i = 0; i < picture.length; i++) {
        let string = picture[i];
        let 추가된글씨 = '';

        for (let j = 0; j < string.length; j++) {
            let str = string[j];

            for (let a = 0; a < k; a++) {
                if (str === '.') {
                    추가된글씨 += '.';
                }
                if (str === 'x') {
                    추가된글씨 += 'x';
                }
            }
        }
        for (let l = 0; l < k; l++) {
            answer.push(추가된글씨);
        }
    }

    return answer;
}

console.log(
    solution(
        [
            '.xx...xx.',
            'x..x.x..x',
            'x...x...x',
            '.x.....x.',
            '..x...x..',
            '...x.x...',
            '....x....',
        ],
    2
);

 

 

메모

저는 빈 배열을 변수로 만들어놓고, 반복문을 돌렸습니다.

picture의 한 인자마다 반복문안에서 변수로 담아두고, k만큼 늘 리라 하여서 다시 k만큼 반복하여 추가해 주었습니다.


놀란 방법 중 하나는 forEach문을 이용해서 풀 수 있다고 합니다!!(저의 선생님 왈ㅎㅎ)
picture 배열을 forEach를 이용해서 배열의 각요소를 처리하고,
forEach 한 원소들이 한 행을 나타내는데, 그 안에 것을 k번 반복한 문자열을 저장해서
다시 for문으로 k번 반복해서 새로 만들어낼 수 있습니다!!.... (경악)

 

function solution1(picture, k) {
    let answer = [];
    let 추가된문자 = '';

    picture.forEach(element => {
        const R = [...element].map(a => a.repeat(k)).join('');
        for (let i = 0; i < k; i++) {
            answer.push(R);
        }
    });
    return answer;
}

console.log(
    solution1(
        [
            '.xx...xx.',
            'x..x.x..x',
            'x...x...x',
            '.x.....x.',
            '..x...x..',
            '...x.x...',
            '....x....',
        ],
        2
    )
);
 

 

 

 

 

 

문제 115.  qr code


문제 설명

0번부터 n - 1번까지 n명의 학생 중 3명을 선발하는 전국 대회 선발 고사를 보았습니다. 
등수가 높은 3명을 선발해야 하지만,
개인 사정으로 전국 대회에 참여하지 못하는 학생들이 있어 참여가 가능한 학생 중 등수가 높은 3명을 선발하기로 했습니다.

각 학생들의 선발 고사 등수를 담은 정수 배열 rank와 
전국 대회 참여 가능 여부가 담긴 boolean 배열 attendance가 매개변수로 주어집니다. 
전국 대회에 선발된 학생 번호들을 등수가 높은 순서대로 각각 a, b, c번이라고 할 때 
10000 × a + 100 × b + c를 return 하는 solution 함수를 작성해 주세요.

 

입출력 예

rank attendance result
[3, 7, 2, 5, 4, 6, 1] [false, true, true, true, true, false, false] 20403
[1, 2, 3] [true, true, true] 102
[6, 1, 5, 2, 3, 4] [true, false, true, false, false, true] 50200

 

 

입출력 예 설명

입출력 예 #1
예제 1번에서 1등은 6번 학생이지만 전국 대회에 참석 불가능하므로 넘어갑니다. 2등은 2번 학생이고 전국 대회에 참석 가능하므로 1순위로 선발됩니다. 3등은 0번 학생이고 전국 대회에 참석 불가능 하므로 넘어갑니다. 4등과 5등은 각각 4번, 3번 학생이고 두 학생 모두 전국 대회에 참석 가능하므로 각각 2순위, 3순위로 선발됩니다. 3명을 선발하였으므로 6등과 7등은 확인하지 않아도 됩니다. 따라서 10000 × 2 + 100 × 4 + 3 = 20403을 return 합니다.

 

입출력 예 #2
예제 2번에서 1, 2, 3등은 각각 0번, 1번, 2번 학생이고 세 학생 모두 전국 대회에 참석 가능하므로 각각 1순위, 2순위, 3순위로 선발됩니다. 따라서 10000 × 0 + 100 × 1 + 2 = 102를 return 합니다.

 

입출력 예 #3
예제 3번에서 1, 2, 3등은 각각 1번, 3번, 4번 학생이지만 세 학생 모두 전국 대회에 참석 불가능합니다. 다음으로 4, 5, 6등은 각각 5번, 2번, 0번 학생이고 세 학생 모두 전국 대회에 참석 가능하므로 각각 1순위, 2순위, 3순위로 선발됩니다. 따라서 10000 × 5 + 100 × 2 + 0 = 50200을 return 합니다.

 

 

저의 풀이!

function solution(rank, attendance) {
    let 참여가능 = rank
        .filter((a, i) => attendance[i])
        .sort((a, b) => a - b)
        .slice(0, 3);

    const [s, e, k] = 참여가능;

    let a = rank.indexOf(s);
    let b = rank.indexOf(e);
    let c = rank.indexOf(k);

    return 10000 * a + 100 * b + c;
}

console.log(
    solution([3, 7, 2, 5, 4, 6, 1], [false, true, true, true, true, false, false])
);

 

 

메모

일단 rank의 배열을 filter를 돌려서 attendance가 true인 것만 빼서 오름차순으로 한 다음~

slice로 3개만 잘라낸 것을 변수에 담아뒀습니다.

그리고 담아둔 변수를 구조분해 할당으로 하나씩 변수로 담아두었습니다.
그리고서 그 배열을 기존 rank배열에 몇 번째 인덱스인지 다시 적어두고, 계산식으로 return을 했습니다~~

 

 

 

문제 116.  배열 만들기 2


문제 설명

정수 l과 r이 주어졌을 때, 
l 이상 r이하의 정수 중에서 숫자 "0"과 "5"로만 이루어진 모든 정수를 
오름차순으로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.

만약 그러한 정수가 없다면, -1이 담긴 배열을 return 합니다.

 

입출력 예

l r result
5 555 [5, 50, 55, 500, 505, 550, 555]
10 20 [-1]

 

입출력 예 설명

입출력 예 #1
5 이상 555 이하의 0과 5로만 이루어진 정수는 작은 수부터 5, 50, 55, 500, 505, 550, 555가 있습니다. 따라서 [5, 50, 55, 500, 505, 550, 555]를 return 합니다.

 

입출력 예 #2
10 이상 20 이하이면서 0과 5로만 이루어진 정수는 없습니다. 따라서 [-1]을 return 합니다.

 

저의 풀이!

function solution(l, r) {
    let answer = [];

    for (let i = l; i <= r; i++) {
        let 글자로 = String(i);

        if (![...글자로].every(v => v === '0' || v === '5')) continue;

        answer.push(i);
    }
    return answer.length ? answer : [-1];
}

console.log(solution(5, 555));

 

 

메모

every라고 배열의 모든 것을 확인해 주는 메서드가 있습니다.
v 하나의 인자가 어떤 건지 확인해서 그 인자가 우리가 필요한 인자라면 넘어가고~ 
아니라면 그 인자를 answer 변수 빈배열에 push 해서 내보냅니다!
만약 없다면 [-1]을 내보내라는 삼항연산자를 이용해서 return 했습니다.

 

 

 

 

문제 117.  배열 조각하기


문제 설명

정수 배열 arr와 query가 주어집니다.

query를 순회하면서 다음 작업을 반복합니다.

짝수 인덱스에서는 arr에서 query[i]번 인덱스를 제외하고 배열의 query[i]번 인덱스 뒷부분을 잘라서 버립니다.
홀수 인덱스에서는 arr에서 query[i]번 인덱스는 제외하고 배열의 query[i]번 인덱스 앞부분을 잘라서 버립니다.
위 작업을 마친 후 남은 arr의 부분 배열을 return 하는 solution 함수를 완성해 주세요.



입출력 예

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

 

 

입출력 예 설명

 

저의 풀이!

function solution(arr, query) {
   
    let copy = [...arr];

    for (let i = 0; i < query.length; i++) {
        if (i % 2 === 0) {
            copy = copy.slice(0, query[i] + 1);
        } else {
        // 0부터 query[i]까지 제거하라
            copy = copy.slice(query[i]);
        }
    }
    return copy;
}

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

 

메모

저는 일단 query를 반복을 돌려서 조건문을 시행하였습니다.
짝수 인덱스에서는 arr에서 query[i]번 인덱스를 제외하고 배열의 query[i]번 인덱스 뒷부분을 slice로 잡아서 버렸습니다.
홀수 인덱스에서는 arr에서 query[i]번 인덱스는 제외하고 배열의 query[i]번 인덱스 앞부분을 slice로 잡아서 버렸습니다.
짜잔~


splice로도 가능해서 splice로 했습니당.

 

 

 

 

 

문제 118.  주사위 게임


문제 설명

1부터 6까지 숫자가 적힌 주사위가 네 개 있습니다. 
네 주사위를 굴렸을 때 나온 숫자에 따라 다음과 같은 점수를 얻습니다.

네 주사위에서 나온 숫자가 모두 p로 같다면 1111 × p점을 얻습니다.
세 주사위에서 나온 숫자가 p로 같고 나머지 다른 주사위에서 나온 숫자가 q(p ≠ q)라면 (10 × p + q)2 점을 얻습니다.
주사위가 두 개씩 같은 값이 나오고, 나온 숫자를 각각 p, q(p ≠ q)라고 한다면 (p + q) × |p - q|점을 얻습니다.
어느 두 주사위에서 나온 숫자가 p로 같고 나머지 두 주사위에서 나온 숫자가 각각 p와 다른 q, r(q ≠ r)이라면 q × r점을 얻습니다.
네 주사위에 적힌 숫자가 모두 다르다면 나온 숫자 중 가장 작은 숫자만큼의 점수를 얻습니다.
네 주사위를 굴렸을 때 나온 숫자가 정수 매개변수 a, b, c, d로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.


입출력 예

a b c d result
2 2 2 2 2222
4 1 4 4 1681
6 3 3 6 27
2 5 2 6 30
6 4 2 5 2

 

 

 

입출력 예 설명

"r"보다 "l"이 먼저 나왔기 때문에 "l"의 왼쪽에 있는 문자열들을 담은 리스트인 ["u", "u"]를 return 합니다.

"l"의 왼쪽에 문자열이 없기 때문에 빈 리스트를 return 합니다.

 

 

저의 풀이!

function solution(a, b, c, d) {
   
    const diceCounts = new Map();
    // Map객체는 키-값쌍의 집합이다.

    [a, b, c, d].forEach(die => {
        diceCounts.set(die, (diceCounts.get(die) || 0) + 1);
    });
    // new Map()으로 정의한 변수를 .set()으로 우리가 원하는 객체로 변경한다.

    const sortedValues = Array.from(diceCounts.values()).sort();
    // 만들어둔 객체에서 value값만 빼서 오름차순으로 정의한다.
 
    const sortedKeys = Array.from(diceCounts.keys()).sort(
        (x, y) => diceCounts.get(x) - diceCounts.get(y)
    );
    // 만들어둔 객체에서 key값들로 오름차순 할예정이지만, value가 작은 순먼저 나열하게끔했다.

    const valuesStr = sortedValues.toString();

    switch (valuesStr) {
        case '4':
            return 1111 * sortedKeys[0];
        case '1,3':
            const [smaller, larger] = sortedKeys;
            return Math.pow(10 * larger + smaller, 2);
        case '2,2':
            const [first, second] = sortedKeys;
            return (first + second) * Math.abs(first - second);
        case '1,1,2':
            const [min1, min2] = sortedKeys;
            return min1 * min2;
        default:
            return Math.min(...sortedKeys);
    }
}

console.log(solution(2, 5, 2, 6));

 

 

 

메모 

이건... 풀이가 어렵습니다.
저도 도움을 받아 풀었는데, 이해한 바로 설명해 보겠습니다!

일단 맨 위에 있는 new Map 키와 값을 쌍으로 보유하고 모든 값을 키 또는 값으로 불러올 수 있습니다.

set으로 원하는 key와 value 값을 지정할 수 있습니다.
a, b, c, d를 forEach를 돌려서 key 값으로 a, b, c, d를 두고 그 값이 있다면 +1 을 카운트해주는 식으로 해서 새 객체를 만들어 냅니다.

 

그리고 sortedValues 라고 변수를 잡아서 Array.from 배열로 만들어줍니다. form() 인자에 있는 값을,
그 인자 안에는 객체 변수인 diceCounts의 values 값들을 sort 오름차순으로 변경한 값을 넣어줍니다.

 

그리고 sortedKeys도 변수를 잡아서 그 인자안에는 key값을 넣어주지만, 순서 sort는 values의 오름차순으로 정렬해 줍니다.

 

valuesStr은 sortedValues변수를 string으로 변경해서 담아주고,

switch문을 이용해서 case에 담아줍니다.

 

case 에 적히는 '4', '1, 3', '2, 2' '1, 1, 2'는

주사위가 4개가 같은 경우, 3개가 같고 하나만 다른 경우, 두 개씩 다른 경우, 하나-하나-두 개가 다른 경우를 의미합니다.
그리고 그 case인 경우 계산식을 넣어주면 됩니다!

설명을 했는데도 어렵죠..? 
이 문항 같은 경우는 하나씩 console을 찍어보면서 값들을 확인하면 이해하기 훨씬 수월해질 겁니다.

 

 

그리고 사실 아직 한 문제 못 풀었습니다...
'정수를 나선형으로 배치하기' 라는 문제인데 이것도 공부해서 진행하도록 하겠습니다.

 

Comments