728x90

◯문제 링크

 

[백준,4673]셀프 넘버

 

◯코드 미리보기

def SelfNum(list1):
    from contextlib import suppress
    for i in range(1,100001):
        Base_Num = str(i)
        Plus_Num = 0 
        
        for z in range(len(Base_Num)):
             Plus_Num += int(Base_Num[z])
        Plus_Num += int(Base_Num)
       
        with suppress(ValueError): list1.remove(Plus_Num)
    return list1



Base_List = list(range(10000))
Base_List.remove(0)
Base_List.append(10000)

Self_Num_List = SelfNum(Base_List)


for i in range(len(Self_Num_List)):
    print(Self_Num_List[i])

 

설명

def SelfNum(list1):

먼저 SelfNum이라는 함수를 선언해 주었다. 문제의 분류가 함수 쪽에 들어가 있어서 함수를 선언했지만, 안에 있는 코드를 그냥 꺼내서 붙여넣어도 상관없지 않을까 싶다.

 

 

    from contextlib import suppress

먼저 contextlib이라는 모듈에서 suppress라는 함수를 가져왔다. try-except의 대용으로 오류를 무시하기 위해 가져온 것인데, 자세한 것은 나중에 suppress함수가 나오는 부분에서 설명하겠다.

 

    for i in range(1,100001):
        Base_Num = str(i)
        Plus_Num = 0 
        
        for z in range(len(Base_Num)):
             Plus_Num += int(Base_Num[z])
        Plus_Num += int(Base_Num)
       
        with suppress(ValueError): list1.remove(Plus_Num)

함수의 가장 큰 뼈대를 이루고 있는 for 문이다. for 문을 사용한 이유는 두 가지 정도인데, 범위를 정하기 편하다는 것과 i가 알아서 증가한다는 점이다. 그러므로 [i += 1]같은 코드를 추가하지 않더라도 범위에 해당하는 모든 숫자를 테스트해볼 수 있다. 

Base_Num은 인덱싱을 사용하기 위해 테스트할 i 값을 문자열로 바꾸어준 변수이다. Plus_Num은 값을 더하기 위한 변수로, 매 루프마다 0으로 초기화 해주어야 한다. 이는 이전 값과 섞이지 않게하기 위해서이다. 

for 문 안에 들어오는 for 문은 밑에 있는 Plus_Num으로 시작하는 코드까지 세트이다. 이 코드들은 문제에서 말하고 있는 함수 d(n)를 표현하기 위한 코드이다. 이 코드가 완료되면 Plus_Num이 가지고 있는 값은 셀프넘버가 아닌 숫자이다.

그래서 제일 아래의 코드로 입력받은 list에서 Plus_Num에 들어온 값을 제거해주는 것이다.

여기서 주의할 점은, Plus_Num에 들어가는 숫자가 중복으로 생길 수도 있다는 것이다. 문제에서 예시를 들었듯이 숫자 101같이 생성자를 91과 100 2개를 가질 수가 있고, 이런 경우가 얼마나 생길지는 모른다. 게다가, remove함수는 찾고자 하는 원소가 해당 list에 존재하지 않을 때 ValueError가 발생하게 된다. 이 에러를 무시하기 위해 사용한 코드가 바로 suppress함수이다. 이렇게 되면 Plus_Num변수에서 중복이 발생하게 돼서 지워야 하는 숫자가 이미 list에서 지워진 경우에도 문제없이 다음 숫자로 넘어갈 수 있게 된다.

 

    return list1

이렇게 for문이 끝나고 나면, 매개변수 list1 안에는 우리가 원하는 셀프넘버들만 들어가 있게 된다. 이 값을 return을 통해 반환하게 되면 함수 SelfNum의 코드가 끝나게 된다. 

 

Base_List = list(range(10000))
Base_List.remove(0)
Base_List.append(10000)

Self_Num_List = SelfNum(Base_List)


for i in range(len(Self_Num_List)):
    print(Self_Num_List[i])

다음은 위에서 선언한 함수를 사용하게 되는 메인 코드이다.

먼저 Base_List를 선언해준다. 1부터 10000까지의 숫자가 전부 들어가야 하므로 range 선언, remove 함수, append 함수 가지 사용해준다. 

그다음, SelfNum함수에 인자 Base_List를 넣어준다. 그렇게 해서 나온 반환 값인 셀프넘버들로 이루어진 list를 대입 연산자를 통해 Self_Num_List에 넣어준다. 

마지막으로, 문제에서 제시하는 출력값대로 출력하기 위해서 for문을 활용하게 되면 문제가 끝이 난다. 

 

배운 것

⩥에러를 무시할 때 사용하는 함수로 try-except 말고도 suppress 함수가 존재한다. 이 함수는 from-import를 사용해서 contextlib 에서 꺼내와야 사용할 수 있다. 이 함수의 장점으로는 한 줄로 끝낼 수 있어서 간편하다는 점이다. 단점은 예외처리가 필요한 코드마다 전부 입력해야 한다는 점이다.

⩥문제에서 요구하는 것이 무엇인지 정확히 파악해야 한다. 문제를 적어가면서 이해해보도록 하자.

728x90

'python > 문제' 카테고리의 다른 글

[백준,1011]Fly me to the Alpha Centauri  (0) 2021.02.23
[백준,1065]/한수  (0) 2021.02.22
[백준/15596] 정수 N개의 합  (0) 2021.02.14
[백준/2588] 곱셈  (0) 2021.02.03
[백준,10757]큰 수 A + B  (0) 2021.02.01

+ Recent posts