자기계발
백준
4673 · 셀프 넘버

백준 4673번 셀프 넘버

문제

양의 정수 n에 대해 d(n)을 n과 n의 각 자리수를 더한 값으로 정의한다. 예를 들어 d(75) = 75+7+5 = 87이다. 어떤 수 m에 대해 d(n) = m인 n이 있으면 n을 m의 생성자라 하고, 생성자가 없는 수를 셀프 넘버라 한다. 입력은 없으며 10000 이하의 셀프 넘버를 한 줄에 하나씩 오름차순으로 출력한다.

풀이

1부터 9999까지 각 수의 d(n)을 구해 리스트에 담고, 1부터 9999까지 돌면서 리스트에 없는 수를 출력하면 된다. 생성자가 있는 수는 모두 리스트에 들어 있으므로 리스트에 없는 수가 곧 셀프 넘버다.

get_self_num은 자릿수에 따라 분기해서 n과 각 자리 숫자의 합을 구한다. 몫(//)과 나머지(%)로 자리 숫자를 하나씩 떼어 낸다. 10000 이상의 값은 출력 범위 밖이므로 리스트를 만들 때 걸러 낸다.

def get_self_num(n):
    if n < 10:
        return n + n
    elif 10 <= n < 100:
        return n + (n // 10) + (n % 10)
    elif 100 <= n < 1000:
        return n + (n // 100) + ((n % 100) // 10)  + ((n % 100) % 10)
    elif 1000 <= n < 10000:
        return n + (n // 1000) + ((n % 1000) // 100) + ((n % 100) // 10) + ((n % 100) % 10) 
 
list_not_self_num = [get_self_num(i) for i in range(1, 10000) if get_self_num(i) < 10000]
 
for i in range(1, 10000):
    if i not in list_not_self_num:
        print(i)

자릿수별로 분기하는 대신 더 짧고 효율적인 방법이 있을 것 같다. 리스트 대신 집합을 쓰면 in 검사가 빨라진다.

출처