ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 Node.js] 2577번 숫자의 개수
    To infinity/Coding Practice 2021. 6. 23. 16:09

    2021.06.23

    Question

     

     

    2577번: 숫자의 개수

    첫째 줄에 A, 둘째 줄에 B, 셋째 줄에 C가 주어진다. A, B, C는 모두 100보다 크거나 같고, 1,000보다 작은 자연수이다.

    www.acmicpc.net


    Answer code

    let input = require('fs').readFileSync('/dev/stdin').toString().split('\n').map(el => +el);
    
    let mult = String((input[0] * input[1] * input[2]));
    
    let arr = Array.from(mult)
    
    let result = arr.reduce((object, currentValue) => {
        if (!object[currentValue]) {
            object[currentValue] = 0;
        }
        object[currentValue]++;
        
        return object;
    },{});
    
    let solve = [];
    
    for(let i = 0; i < 10; i++) {
        !result[i] ? solve.push(0) : solve.push(result[i])
    }
    
    console.log(solve.join('\n'));

    How to solve?

     

    1st Trial.

     

    1. 일단 세자리 수를 곱하자.

    -> 배열의 각 요소를 인덱스로 가져와서 각각 곱하는거 말고 더 아름답게 곱할 수 있지 않을까??

     

    let mult = String(input.reduce((mul, cur) => mul * cur, 1));

    > 해당 부분을 reduce로 처리할 수 있을 것 같아 위와 같이 식을 짰다.

    vs code에선 값이 나오는데 백준에선 오류가 나온다. 뭐가 문젤까?

     

     

     

    2-1. 산출된 값을 Array.from()을 사용해 배열로 바꿔서 결과값을 각 배열의 요소로 만들어 넣는다.

    for문을 돌며 인덱스별로 객체를 만들어서 해당 인덱스와 값이 같으면 배열에 추가. filter 메서드 사용.

    그리고 for문으로 돌려서 각 숫자마다 카운팅시키면?

    -> for문도 좋지만 JS는 객체지향 프로그래밍이니 최대한 반목문과 변수 사용을 지양하고 제공해주는 메서드를 이용하도록 하자.

     

     

    2-2. reduce 메서드로 처리 (객체 내의 인스턴트 개수 세기)

    -> 이번문제는 reduce 메서드를 공부하는 문제인 듯하다.

    answer code내의 식은 기본 배포 된 내용을 그대로 가져와서 적긴 했는데 아직 무슨의민지 정확히 파악을 못했다.

    일단 해당 구문이 돌아가는지, 내가 생각한 로직이 맞는지 먼저 체크해보기위해 해당 코드를 가져와서 적용시켰고 현재 '맞았습니다!'가 나왔으니 이제 차차 어떤 내용인지 알아보도록 하자.

     

    해당 reduce메서드에 내용은 별도 포스팅 ㄱㄱ

     

    [참고문서]

     

     

    Array.prototype.reduce() - JavaScript | MDN

    reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

    developer.mozilla.org

     

     

    3.

    for(let i = 0; i < 10; i++) {
        solve.push(result[i])
    } 
    
    console.log(solve);
    // [3, 1, undefined, 2, undefined, undefined, undefined, 2, undefined, undefined]
    // 이렇게 객체에 없는 값은 undefined로 들어간다.

     

    0~9까지 각 값이 몇번 나왔는지에 대한 출력을 위해 reduce로 반환된 객체를 for문으로 돌려 각 값을 0~9까지 순서대로 배열에 넣자. 이때, 객체와 매칭되지 않는 인덱스는 undefined로 뜨면서 배열에 들어간다.

    그렇기에 객체와 매칭되지 않는 인덱스는 (즉, 객체에 프로퍼티가 없는 항목) 0의 값으로 새로운 배열에 들어가도록 해야하는데 이 부분에서 고민을 좀 했다.

    처음엔 result[i] == false (false값과 undefined값은 모두 0으로 인식할거라고 생각했는데 (지금 적으면서 생각해보니 아니네) 아니었다. 분명 이 부분에 대해 책을 읽긴 읽었는데 다시한번 봐야겠다. 헷갈린다.

     

     

    !result[i] ? solve.push(0) : solve.push(result[i])

    그래서 빈 배열을 확인하는 방법을 참고하면 빈배열에 값을 넣는 방법을 알 수 있을 것으로 생각되어 해당 내용을 찾아봤다.

    그랬더니 !를 사용하는 것을 확인할 수 있었다. 값이 없다는 것은 false니, !를 사용해서 true로 바꿔주는 건가보다. 

    -> js에서 조건식과 같이 boolean 타입으로 평가돼야 할 때 암묵적으로 타입을 바꾸는데 평소에는 undefined타입이었지만 조건식에선 false로 변환된다. 그래서 !undefined가 돼서 true가 된 것이다.

     

     

    이렇게 식이 완성됐고, '맞았습니다!'라는 기쁜 문장을 접하게 됐다.

    '틀렸습니다'와 '맞았습니다'로 나의 엔도르핀 수치가 결정되는 듯..ㅋㅋ

     

    reduce에 대해 찐하게 공부해야겠다.

     

     

    - 추가 -

    reduce 부분을 아래와 같이 적을 수도 있다.

    let obj = arr.reduce((object, cur) => {
        object[cur] = (object[cur] || 0) + 1
        return object //반환값은 객체로
    }, {});

     

     

    '객체'에 대해 좀 헷갈려서 위 식이 이해가 잘 안갔는데 풀이해보자면 다음과 같다.

     

    먼저 빈객체를 선언해줘야 한다. (위에서도 가장 끝에 {} 빈 객체를 넣어줬다)

    let obj = {}

     

    객체에 값을 넣고 싶으면 '프로퍼티 키'와 '값'을 같이 넣어줘야 한다.

    obj[key] = 1 // { key : 1 }

     

    만약, 빈 객체의 '키'만 적으면 아무변화도 일어나지 않는다. (즉, 무시된다)

    obj2[key] // ?

     

    하지만 할당된 객체의 '키'를 적으면 '값'이 나온다.

    ojb[key] // 1

     

     


    Reference

     

Designed by Tistory.