어떤 자연수 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 보다 작은 모든 셀프 넘버들의 합을 구하라.
###
풀이: Self Number을 판별하는 함수를 만들고 그 함수가 반환하는 값(참 or 거짓)에 따라 Self Number 여부를 판별하고 참이 나온 수들을 결과값에 해당하는 Result 변수에 저장한다.
제너레이터는 주어진 변수보다 커질 수 없기 때문에, Self_Num 함수에서 반복문의 범위를 var 미만으로 설정했다.
ex) 101의 제너레이터를 구하기 위해 1 부터 100까지 Self_Num 함수를 사용하여 계산한다. 91을 계산하는 순간, 101과 일치하기 때문에 (결과 값이 변수(var)와 같으면? (제너레이터가 존재하면?) -> Self Number가 아니다.) flag를 거짓으로 변경 후 반복문을 빠져나온다.
그 후 flag를 반환한다.(거짓) 만약, 일치하는 수가 없는 경우(제너레이터가 존재하지 않는 경우) 에는 Self Number 이므로 참을 반환한다.
좀 더 효율적인 방법을 찾아봐야할 것 같습니다.
#include <stdio.h>
#define MAX 5000
#define TRUE 1
#define FALSE 0
int Self_Num(int var);
int main(void)
{
int i, result;
result = 0;
for (i = 1; i < MAX; i++)
{
if (Self_Num(i) == TRUE)
result += i;
else
continue;
}
printf("Sum of Self Numbers: %d\n", result);
return 0;
}
int Self_Num(int var) //Self Number을 판별하는 함수//
{
int i, digit_sum, result, temp, flag;
digit_sum = 0;
flag = TRUE;
for (i = 1; i < var; i++)
{
temp = i;
while (i >= 10)
{ //각 자릿수의 합//
digit_sum += i % 10;
i /= 10;
}
digit_sum += i;
result = temp + digit_sum; //각 자릿수 + 원래 숫자//
if (result == var)
{ //결과 값이 변수와 같으면? (제너레이터가 존재하면? -> Self Number가 아니다.)
flag = FALSE;
break;
}
else
{
digit_sum = 0;
i = temp;
continue;
}
}
return flag;
}