ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준 Node.js] 1065번 한수
    To infinity/Coding Practice 2021. 6. 26. 12:44

    2021.06.26

    Question

     

     

    1065번: 한수

    어떤 양의 정수 X의 각 자리가 등차수열을 이룬다면, 그 수를 한수라고 한다. 등차수열은 연속된 두 개의 수의 차이가 일정한 수열을 말한다. N이 주어졌을 때, 1보다 크거나 같고, N보다 작거나

    www.acmicpc.net


    Answer code

    let fs = require('fs');
    let input = fs.readFileSync('/dev/stdin');
    
    function ap(num) {
        let N = num.toString().split('')
        let n = Number(N.length);
        //let a1 = Number(N.shift()); //원본배열을 바꿈
        let a1 = Number(N[0])
        let d = num<10 ? Number(N[0]) : Number(N[1]-N[0])
        let an = Number(N.pop());
    
        if(an == a1 + (n-1)*d) return true;
    }
    
    
    let count = 0
    
    for(let i=1; i <= input; i++){
        if (ap(i)) count++;
    };
    
    console.log(count)

    How to solve?

     

    1st Trial

    //등차수열구하기
    let fs = require('fs');
    let input = 210;
    
    function ap(num) {
        let N = num.toString().split('')
        let n = Number(N.length);
        //let a1 = Number(N.shift()); //원본배열을 바꿈
        let a1 = Number(N[0])
        let an = Number(N.pop());
    
        let Sn = (n * (a1 + an)) /2;
        let Sn_1 = Sn - an;
    
        if(Sn - Sn_1 == a1) return true;
    }
    
    //
    let count = 0
    for(let i=2; i < input; i++){
        if(ap(i)) count++
    }
    
    console.log(count)

     

    등차수열의 일반항을 구하는 공식은 두가지가 있다.

     

     

     

    나는 두번째 등차수열 식을 참고하여 위와같은 코드를 짰다.

     

    하지만 백준에 나오는 결과값과 다른 값이 나왔고, '엥? 그렇게나 등차수열이 많다고?'라는 생각을 해서 다시한번 문제와 답을 확인해봤다.

     

    아무래도 110을 입력하면 99개의 답이 나오는 것을 보니 연속된 두개의 수의 차이가 일정하다는 것은 두자리수에서는 항상 적용되는 것이고 (왜냐면 항상 하나의 값이 나올테니까) 두자리수 이상에서는 각 자리수마다의 차이가 일정해야하는 것 같다.

     

     

     

    2st Trial
    //등차수열구하기
    function ap(num) {
        let N = num.toString().split('');
    
        N.reduce((arr,cur) => {
            if((cur-arr) == cur) return true
        },0)
    }
    
    let count = 0;
    for(let i=1; i < input; i++){
        if(ap(i)) count++
    }
    console.log(count);

     

    그래서 공식 말고 reduce메서드를 이용해보기로 했다.

    해당 기능을 이용해서 각 자리수를 뺀 값이 이전에 뺐던 값과 동일하면 true를 내도록 했다.

    하지만 원하는 답을 주지 않았다.

    확인해보니, 1자리 수 일때는 해당 식이 적용될 수가 없었다. 기본값(acc)을 0으로 설정해놓으면 첫번째 값과 acc를 뺀 값이 0일거고, 그 다음에 뺀 값은 각 자리수의 차이일테니 같을리가 없다. 하지만 100미만의 수는 무조건 등차수열이기 때문에 해당 기능은 사용하기 어려웠다.

     

    그런데 문득 그런생각이 들었다.

    만약 한자리수, 두자리수도 등차수열이라면 공식으로 풀었을 때 답이 나와야하는게 아닐까?

    그래서 다시 공식으로 돌아가 직접 손으로 두자리수를 넣어 풀어보았다. 답이 나왔다.

    그런데 생각해보니 해당 식은 항상 true일 수 밖에 없었다.

    그래서 1번 식으로 갈아탔다.

    그리고 답을 얻었다.

     

     

    Others

     

    function 내부를 좀 더 예쁘게 쓸 수 있지 않을까?라는 생각이 든다.

    다른사람들은 어떤 로직으로 풀었는지 찾아봐야지

     

    '나머지'라는 개념을 이용해서 문제를 많이 푸는 것 같다. 정수론이라는 모듈러공식?에 의해서 푸는 것 같은데 내가 궁금한거는 내가 풀었던 것 처럼 푸는것과 나머지를 이용해서 푸는 것 중에 어떤 것이 더 효율적인 코드인 것인가? 이다.

     

    나도 처음에는 나머지를 이용해서 풀어보려 했는데 그보다 더 효율적인 '공식'이란게 있으니 그걸 이용하는게 낫지 않을까?란 생각을 했다. 그러면 모든 수에 대해서 공통된 기준을 적용할 수 있으니까.

     

    변수를 너무 많이 써서 별로 안 좋지 않을까라는 생각을 하긴 했는데 나머지를 이용한것도 조건을 여러번 쪼개서 사용하니까 뭐가 좋은지 잘 모르겠다.

     

     

     

     


    Reference

    등차수열의 정의 및 공식

     

Designed by Tistory.