넥슨 입사문제 중에서

어떤 자연수 n이 있을 때, d(n)을 n의 각 자릿수 숫자들과 n 자신을 더한 숫자라고 정의하자.

예를 들어

d(91) = 9 + 1 + 91 = 101

이 때, n을 d(n)의 제네레이터(generator)라고 한다. 위의 예에서 91은 101의 제네레이터이다.

어떤 숫자들은 하나 이상의 제네레이터를 가지고 있는데, 101의 제네레이터는 91 뿐 아니라 100도 있다. 그런데 반대로, 제네레이터가 없는 숫자들도 있으며, 이런 숫자를 인도의 수학자 Kaprekar가 셀프 넘버(self-number)라 이름 붙였다. 예를 들어 1,3,5,7,9,20,31 은 셀프 넘버 들이다.

1 이상이고 5000 보다 작은 모든 셀프 넘버들의 합을 구하라.

2011/08/14 14:32

길가의풀

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

5개의 풀이가 있습니다.

console.info("selfNumber Start \n1이상이고 5000보다 작은 모든 셀프 넘버들의 합을 구하라");

// 1부터 5000보다 작은 숫자들의 배열을 생성한다.
var selfArray = new Array(4998);
var tot = 0;
for(var i = 1; i < 5000; i++){
selfArray[i] = i;
}

//제너레이터는배열에 gen라고 입력한다.
for(var i = 1; i < 5000; i++){
var genNum = parseInt(i%10) + parseInt((i/10)%10) +parseInt((i/100)%10) + parseInt((i/1000)%10) + i; //제너레이터
if(genNum > 5000) break;
selfArray[genNum] = "gen";  //해당 배열에 gen 이라고 입력
}

//self 넘버의 합계를 더한다.

for(var i=1; i<5000; i++){
if(selfArray[i] != "gen") tot += selfArray[i];
}
console.info(tot);

배열로 풀어봤어요..결과는 1227365 나왔습니다.

2014/02/28 14:34

김세연

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

JavaScript

var i = 0
var arr = new Array(5001).join('0').split('').map(parseInt);
while (1) {
    var j = i++;
    var s = j;
    while(j > 0) {
        s += j - parseInt(j / 10) * 10;
        j = parseInt(j / 10);
    }
    if (s >= 5000) break;
    arr[s] = 1;
}

var r = 0;
arr.forEach(function(e, n) {
  r += e ? 0 : n;
});

console.log(r);
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

자바스크립트로 풀었스빈당.

<script>
var val_sum = 0;

for(var i=1; i<5000; i++)
{
    if(calc_gen(i))
        val_sum += i;
}

console.log(val_sum);

function calc_gen(val)
{               
    for(var i=1; i<val; i++)
    {
        var str = i.toString();
        var sum = i;

        for(var j=0; j<str.length; j++)
        {
            sum += parseInt(str[j]);
        }
        if(val == sum)
            return false;;
    }
    return true;
}       
</script>

답 : 1227365

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

자바 스크립트 입니다.

var arr = new Array(5001);

for(var i = 1; i <= 5000; i++){
    var tmpNum = i;
    var sum = i;
    while(tmpNum > 0){
        sum += (tmpNum % 10);
        tmpNum = parseInt(tmpNum / 10);
    }

    if(sum <= 5000){
        arr[sum] = 1;
    }
}

var selfSum = 0;

for(var i = 1; i <= 5000; i++){
    if(arr[i] == undefined) selfSum += i;
}

document.write("selfSum : " + selfSum);

  1. 1~5000까지 자신부터 시작해서 10의 나머지를 하나씩 더하여 해당 인덱스에 단순히 1을 채우는 구조입니다.
  2. 1이 채워지지 않은 배열이 있다면 셀프 넘버로 볼 수 있기 때문에 undefined을 체크해서 해당 인덱스의 합을 구하는 구조입니다.
  3. 자바 스크립트에서 배열의 초기값은 undefined 입니다.
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

javascript(ES6)

var selfnumbers = Array.from(Array(5000), (_, i) => i + 1);
var add = (a, b) => a + b;
var str2int = s => parseInt(s, 10)
var gen = n => n + ("" + n).split('').map(str2int).reduce(add);

for (let i = 1; i <= 5000; i++) {
    selfnumbers[gen(i) - 1] = 0;
}

var sum = selfnumbers.reduce(add);

console.log(sum);

for 문 없이 아래와 같이 할 수도 있는데, 그러면 selfnumbers 가 chain 되지 않아서 .reduce 를 chain 할 수가 없음

selfnumbers.map((v, i, a) => { a[gen(i + 1) - 1] = 0 })
var sum = selfnumbers.reduce(add);

파이썬 코드에 감명받아서, 차집합으로 다시 풀어봤습니다.

var numbers = Array.from(Array(5000), (value, index) => index + 1);
var add = (a, b) => (+a) + (+b);
var genned = new Set(numbers.map(n => n + `${n}`.split('').reduce(add, 0)));
var selfsum = numbers.filter(x => !genned.has(x)).reduce(add, 0);

console.log(selfsum);
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 395
python x 136
기 타 x 61
java x 73
matlab x 5
scala x 9
cs x 15
cpp x 59
php x 6
delphi x 3
ruby x 6
haskell x 2
lisp x 2
javascript x 5
r x 3
clojure x 2
erlang x 1
perl x 1
objectivec x 5
go x 1