티스토리 뷰

728x90
반응형

목차

     

    문제

     

    도현이는 바구니를 총 N개 가지고 있고, 각각의 바구니에는 1번부터 N번까지 번호가 매겨져 있다. 

    바구니에는 공이 1개씩 들어있고, 처음에는 바구니에 적혀있는 번호와 같은 번호가 적힌 공이 들어있다.

    도현이는 앞으로 M번 공을 바꾸려고 한다. 

    도현이는 공을 바꿀 바구니 2개를 선택하고, 두 바구니에 들어있는 공을 서로 교환한다.

    공을 어떻게 바꿀지가 주어졌을 때, M번 공을 바꾼 이후에 각 바구니에 어떤 공이 들어있는지 구하는 프로그램을 작성하시오.

     

    입력

     

    첫째 줄에 N (1 ≤ N ≤ 100)과 M (1 ≤ M ≤ 100)이 주어진다.

    둘째 줄부터 M개의 줄에 걸쳐서 공을 교환할 방법이 주어진다. 

    각 방법은 두 정수 i j로 이루어져 있으며, i번 바구니와 j번 바구니에 들어있는 공을 교환한다는 뜻이다. (1 ≤ i ≤ j ≤ N)

    도현이는 입력으로 주어진 순서대로 공을 교환한다.

     

    출력

     

    1번 바구니부터 N번 바구니에 들어있는 공의 번호를 공백으로 구분해 출력한다.

     

    풀이

     

    조건문과 반복문 때는 그저 그랬는데, 배열 단계에 들어오니 자바스크립트의 흥미로운 부분을 많이 만나게 된다.

     

    그중에는 편한 것도 있고, 불편한 것도 있고, 의미를 모르겠으나 관례상 필요한 부분도 있는데

     

    이게 또 기존의 자바와 파이썬에서는 느낄 수 없는 부분이라 다소 즐겁다.

     

    어쨌건 문제는 인덱스와 동일한 숫자의 공이 들어있는 바구니 n개에서, 위에 적힌 규칙을 따라 m번을 뒤섞은 뒤

     

    결과를 출력하는 문제이다. 알고리즘 자체는 별 거 아니라 지난 문제와 비슷하게 풀었는데,

     

    다른 사람의 풀이를 보니 내가 전혀 모르던 방식이 많이 나와서 꽤 배울 수 있었다.

     

    배열 초기화

     

    순서대로 적어보면, 우선 배열을 초기화하는 방법이다.

    baskets = Array.from({ length: n }, (_, index) => index + 1);

    지난 글에서는 배열의 길이가 주어졌을 때 모든 요소를 같은 숫자로 초기화하는 법이었는데

     

    이번에는 한 단계 더 나가서 길이를 주고 해당 인덱스마다 특별한 규칙을 가지고 초기화할 수 있는 방법이다.

     

    여기서 index는 배열의 인덱스를 가리키며, 지난 문제처럼 1번 인덱스부터 채우는 것이 아닌 0번 인덱스부터 +1 한 값을 채우고 있다.

     

    그 이유는 뒤에 출력 부분에서 알게 된다.

     

    그리고 또 하나 흥미로운 점은

    (_, index)

    여기서 '_'의 역할인데, 도무지 왜 쓰인 것이고 어디에서 사용되는지 알 수가 없었다.

     

    해서 조금 알아보니 위와 같은 표현은 요소의 값에는 관심이 없고 index만 필요할 때 사용하는 관례적인 표현이다.

     

    파이썬에서의 쓰임과 조금 비슷해 보이는데, 하여간 위와 같은 표현은 해당 위치에서는 요소가

    해당 위치에서 사용되지 않을 것임을 분명히 하기에 가독성 측면에서 좋다고 한다.

     

    배열의 두 요소 자리 바꾸기

     

    계속해서 배열의 두 요소를 바꾸는 방법이다.

     

    자바와 파이썬에서는 temp 변수를 만들어서 한 바퀴 돌리며 바꿔주는 형태를 취해야 했는데,

     

    자바스크립트에서는 아래의 한 줄로 끝난다.

    [baskets[i - 1], baskets[j - 1]] = [baskets[j - 1], baskets[i - 1]];

    처음 보는 기능이라 재미있다고 생각했다.

     

    Console.log()로 배열 출력하기

     

    여기서 위 구현에서 굳이 인덱스를 0번부터 사용한 이유가 나온다.

     

    출력을 아래와 같이 하면 지난번 문제처럼 반복문을 돌며 배열의 요소를 출력할 필요가 없다.

    console.log(baskets.join(' '));

    위 식의 의미는 물론, baskets 배열의 요소를 ' '로 연결해 출력하는 것이다.

     

    그러나 다소 허무하게도, 위 방법으로도 첫 번째 인덱스, 혹은 마지막 인덱스를 제외하고 출력하는 것이 가능하다.

     

    표현은 아래와 같다.

    console.log(baskets.slice(1).join(' ')); // 첫 번째 인덱스 제외
    console.log(baskets.slice(0, -1).join(' ')); // 마지막 인덱스 제외
    console.log(baskets.filter((_, index) => index !== 3).join(' ')); // 특정 인덱스 제외
    
    // 특정 인덱스 제외(2)
    baskets.splice(3, 1);
    console.log(baskets.join(' '));

    위에 쓰인 filter와 splice는 특정 인덱스의 요소를 (한 개) 제거한 새로운 배열을 만드는 기능을 한다.

     

    재밌는 부분은 끝났고, 코드 구현을 보고 글을 마치자.

     

    JavaScript

     

    const rl = require('readline').createInterface({
        input: process.stdin,
        output: process.stdout,
    });
    
    let n = 0;
    let m = 0;
    let baskets = [];
    
    rl.on('line', (line) => {
        if (n === 0) {
            [n, m] = line.split(' ').map(Number);
            baskets = Array.from({ length: n }, (_, index) => index + 1);
        } else {
            const [i, j] = line.split(' ').map(Number);
            [baskets[i - 1], baskets[j - 1]] = [baskets[j - 1], baskets[i - 1]];
            
            m--;
    
            if (m === 0) {
                rl.close();
            }
        }
    }).on('close', () => {
        console.log(baskets.join(' '));
        process.exit(0)
    })
    반응형
    댓글
    공지사항
    최근에 올라온 글
    최근에 달린 댓글
    Total
    Today
    Yesterday
    링크
    «   2024/06   »
    1
    2 3 4 5 6 7 8
    9 10 11 12 13 14 15
    16 17 18 19 20 21 22
    23 24 25 26 27 28 29
    30
    글 보관함