넥슨 입사문제 중에서

어떤 자연수 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 보다 작은 모든 셀프 넘버들의 합을 구하라.

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

378개의 풀이가 있습니다. 29 / 38 Page

A = range(1,5000)
B = []
for i in A:
    dn = 0
    for j in list(str(i)):
        dn += j
    dn += i
    B.append(dn)

C = []
for i in A:
    if i not in B:
        C.append(i)

S = 0
for i in C:
    S += i

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

C로 풀었습니다. 어떻게 하면 더 효율적으로 self number인지를 테스트 할 수 있는지가 관건인 것 같은데 이렇게 무식하게 밖에 생각을 못해서, 조금 더 고민을 해봐야 할 것 같습니다.

#include <stdio.h>


// self number test
int isSelf(int target);
// 문제에서 제시된 d(n)
int d(int n);
// 자리수 합 구하는 함수
int permute(int n);


int main(void)
{
    int sum = 0;
    for(int i = 1; i < 5000; i++)
    {
        sum += isSelf(i) * i;
    }
    printf("Result = %d\n", sum);
    return 0;

}

int isSelf(int target)
{
    for(int i = 1; i < target; i++)
    {
        // if generator exist
        if(d(i) == target)
        {
            return 0;
        }
    }
    return 1;
}

inline int d(int n)
{
    return n + permute(n);
}

int permute(int n)
{
    if(n < 10)
        return n;
    else 
    {
        return n % 10 + permute(n / 10);
    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include<iostream>
using namespace std;

void main() {
    int count = 1, X, Y, sum = 0;
    int self_number[5000] = { 0, };
    int result = 0;
    while (count < 5000) {
        X = count;
        sum = X;
        count++;
        while (X != 0) {
            Y = X % 10;
            X = X / 10;
            sum += Y;
        }
        if (sum < 5000)
            self_number[sum - 1] ++;
    }

    for (int i = 0; i < 5000; i++) {
        if (self_number[i] == 0) {
            cout << i + 1 << "  ";
            result += i + 1;
        }
    }
    cout <<endl << result;
}

아...5000보다면 5000이 안들어가는건가요...?? 1232365 이 나와버리네요....크 ㅋㅋ어떻게 빼야되지...

요구사항은 4999이하의 값인데 self_number는 5000까지 등록하시고 4999는 이용하지 않으셔서 0으로 초기화된 채로 더해지기 때문에 잘못된 결과가 됩니다. [4999]를 이용하도록 sum - 1에서 -1을 제거하거나, 처음 배열 생성시 4999로 생성하는 방법이 있겠네요 - 박진규, 2017/01/31 09:31 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

아름다운 코드군요 , 윗분의 답을 많이 참조했습니다 . 참고로 이건 답이 아닙니다 연습용으로 올림!

if __name__ == '__main__':
    print sum(set(range(1,5000)) -  set( x + sum([int(y) for y in str(x)]) for x in range(1,5000) ))
    #{x + sum([int(a) for a in str(x)]) for x in range(1, 5000)}



※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
numbers = range(1, 5000)

k = 0

for i in range(1, 5000):

    for j in str(i):

        k = k + int(j)

    k = k + i

    try:
        numbers[k-1] = 0
    except:
        pass

    k = 0

for i in numbers:
    k = k + i

print k

파이썬으로 작성했습니다.

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

import java.util.HashSet;

public class Number1 {

    public static void main(String[] args) {

        HashSet<Integer> numbers = new HashSet<Integer>();

        for ( int i = 1 ; i < 5000 ; i++ )
            numbers.add(i);

        for ( int i = 1 ; i < 5000 ; i++ )
            numbers.remove(generate(String.valueOf(i)));

        int sum = 0;

        for ( int i : numbers )
            sum += i;

        System.out.println(sum);

    }

    private static int generate(String number) {

        int k = 0;

        for ( int i = 0 ; i < number.length() ; i++ ) {

            k += Character.getNumericValue(number.charAt(i));

        }

        k += Integer.parseInt(number);

        return k;

    }

}

자바로 작성했습니다.

2017/01/03 13:50

K

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
$max = 4999;
$array = range(0,$max);

for($num=1;$num<=$max;$num++){
    $array_num = str_split($num);
    $sum = 0;
    foreach($array_num as $val){
        $sum += $val;
    }
    $sum += $num;
    unset($array[$sum]);
}
unset($array[0]);
foreach($array as $num) $total_sum += $num;
echo sprintf("total count:%s",count($array));
echo "\n";
echo sprintf("total sum:%s",$total_sum);
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

#include <stdio.h>

int Number (int n, int *cnt);
int Generator (int n);

int main(void)
{
    int n=0,i,dn=0;
    int arr[5001] = {0};
    int sum=0;

    for(n=0 ; dn<=5000 ; n++) {
    dn = Generator(n);
    arr[dn] = 1;    

    }

    for(n=0;n<=5000;n++)
    {
        if(arr[n] == 0)
            sum+=n; 
    }
    printf("셀프넘버들의 합은 %d",sum);      //정답 : 1227365 출력
    return 0;
}

int Generator (int n)
{
    int dn = 0,num;
    int i,cnt=0;
    int ten=1;
    num = Number(n,&cnt);

    while(num>=0)   {
        for(i=1;i<num;i++)
            ten*=10;
        dn += (n/ten) % 10;
        num--;
        ten=1;
        if(num ==0) {
            dn += n;
            break;
        }
    }
    return dn;
}

int Number (int n, int *cnt)
{
    int number;
    number = n/10;
    if(number == 0){
        *cnt+=1;
        return *cnt;
    }
    else{
        *cnt+=1;
        Number(number,cnt);
    }
}   

c언어로 작성해봤습니다. 어렵네요

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

public class SelfNumber {
    static int sum;
    public static void main(String[] args) {

        ArrayList<Integer> list = new ArrayList<Integer>();

        int finishNum = 5000;
        for(int i = 1; i < finishNum; i++){
            list.add(i);
        }
        for(int i = 1; i < finishNum; i++){
            list.remove((generateNum(i)<finishNum)?generateNum(i):false);
        }

        list.stream().forEach((i) -> {
            sum += i;
        });

        System.out.println(sum);
    }

    private static int generateNum(int i) {
        int gab = 0;
        if(i < 10){
            gab +=  (i-(i/10)*10)/1;
        } else if(i < 100){
            gab +=  (i-(i/100)*100)/10 + (i-(i/10)*10)/1;
        } else if (i < 1000){
            gab +=  (i-(i/1000)*1000)/100 + (i-(i/100)*100)/10 + (i-(i/10)*10)/1;
        } else if (i < 10000){
            gab +=  (i-(i/10000)*10000)/1000 + (i-(i/1000)*1000)/100 + (i-(i/100)*100)/10 + (i-(i/10)*10)/1;
        }
        return gab+i;
    }
}

밑에 부분 generateNum 줄일수 있을텐데 제 머리의 한계라서 혹시 아시는분은 댓글 부탁드립니다. - Min Daehong, 2017/01/06 18:59 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

다른 분 코드 참고했어요


package codingdojang;
//num1
public class nexon {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        boolean[] num=new boolean[5001];
        int a,b,c,d,result, sum=0;
        for(int i=1;i<=5000;i++){
            a=i/1000;
            b=(i%1000)/100;
            c=(i%100)/10;
            d=(i%10);

            result=a+b+c+d+i;

            if(result>0&&result<=5000){
                num[result]=true;
            }

        }
        for(int i=1;i<=5000;i++){
            if(num[i]==false)
                sum+=i;
        }
        System.out.println(sum);
    }

}

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

풀이 작성

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

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


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