ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [파이썬/Python] 백준 1001번(A-B) - 단계별로 풀어보기 + [0 < A, B < 10 조건 명시하기]
    깜빡의 취미/파이썬을 합니다. 2021. 6. 20. 18:13
    728x90

    문제는 아래와 같다.

     

    1001번: A-B

    두 정수 A와 B를 입력받은 다음, A-B를 출력하는 프로그램을 작성하시오.

    www.acmicpc.net

     

    1000번(A+B)을 풀어 본 사람이라면 금세 해결할 수 있다. 사실 1000번의 답안을 복붙한 다음 '+'를 '-'로 바꾸면 된다. 혹시라도 1000번을 풀어보지 않은 독자 분들을 위해 설명을 이어가기 전에, 잠시 필자의 제출 현황을 공개해 본다.

     

    그냥 똑같은 설명만 하면 재미 없으니, 저 255바이트짜리 코드가 무슨 수로 튀어나온 건지도 함께 설명해볼 예정이다. 


    우선 문제를 풀기 위해 반드시 알아두어야 할 것은 A와 B를 '입력 받'아야 한다는 것이다. 이때 쓰이는 함수가 input 함수로, 입력한 값을 문자열로 돌려준다.

    >>> a = input()
    여기에 입력을 하면 이렇게 됩니다.
    >>> a
    '여기에 입력을 하면 이렇게 됩니다.'

     

    우리는 두 숫자를 뺀 결과를  얻어야 하기 때문에 문자열을 정수형으로 바꾸어 주어야 한다. 이 때는 int 함수를 결합하면 된다.

    >>> a = int(input())
    20210618
    >>> a
    20210618

     

    동시에 A, B라는 두 개의 숫자를 구분하여 입력해 주기 위해 split 함수를 함께 이용해야 한다. split 함수는 위의 두 함수와는 달리 a.split()과 같은 기본형을 가지고 있으며, 공백을 기준으로(필자는 띄어쓰기 단위라고 이해했다.) 입력한 값을 리스트로 치환해 준다.

    >>> a = '내일은 하지라고 합니다. 물을 잘 마셔서 건강을 지킵시다.'
    >>> a.split()
    ['내일은', '하지라고', '합니다.', '물을', '잘', '마셔서', '건강을', '지킵시다.']

      

    int 함수를 A,B값에 한꺼번에 적용하기 위해 마지막으로 map 함수를 활용하면 다음과 같이 답을 도출할 수 있다.

    [예시 답안 1]
    A, B = map(int, input().split())
    print(A-B)

     

    물론 map 함수라는 녀석에 대한 이해가 부족하다고 느낀다면 다음과 같이 조금 길게 풀어쓸 수도 있다.

    [예시 답안 2]
    A,B = input().split()
    가 = int(A)
    나 = int(B)
    print(가-나)

    참고로 위 식에 대한 보다 자세한 설명은 다음의 게시글에 담아 두었습니다. 매 글에 이렇게 길게 적어낼 수 없고, 워낙 백준 문제에서 계속해서 사용되는 녀석이니만큼 따로 게시글을 작성했습니다. 

     

    [파이썬 / Python] map(int, input().split())에 대해

    위 식은 백준의 다른 문제를 풀이할 때 계속해서 사용하게 될 것이다. 따라서 좀 더 구체적으로 첫 줄에 들어 있는 함수들이 무엇이고, 또 어떻게 변형할 수 있는지 알려드리고자 한다. 미리 공

    ccamppak.tistory.com


    자, 이제 본론으로 들어가 보자. 바로 이 녀석에 대한 이야기를 해 볼 생각이다.

    항상 백준 문제를 보며 조건에 대해 궁금해하곤 했다. 입력란에 항상 아래와 같이 조건이 붙어 있기 때문이다.

    첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

     

    물론 입력하는 사람이 인간이기 때문에, 알아서 해당 범위 내에 맞추어 입력해줄 것이 분명하다. 그렇지만 만일 A에 -1을, B에 2를 넣었다면? 위의 예시 답안은 조건에 맞지 않는 숫자들도 여과 없이 술술 계산해줄 것이다. 뭔가 마음에 들지 않았다.

     

    서론이 길었다. 오류를 발생시키는 방법을 통해 필자는 A,B에 맞는 숫자만을 입력하도록 조정할 수 있었다. 아래는 백준 사이트에 제출한 답안 예시이다. 아래의 책에서 배운 방법이다.

     

    위키독스

    온라인 책을 제작 공유하는 플랫폼 서비스

    wikidocs.net

    전문가 분들이 구성할 수 있는 식보다는 훨씬 퀄리티가 떨어질 것이라고 생각합니다. 초심자의 그것이라고 생각해 주시면 감사하겠습니다.

    [답안 예시3]
    class Oryu(Exception):
        def __str__(self):
            return "잘못된 식입니다."
    
    def e():
        a, b = map(int, input().split())
        if not 0 < a < 10 or not 0 < b < 10:
            raise Oryu()
        print(a-b)
    
    try:
        e()
    except Oryu as o:
        print(o)

     

    우선 Exception이라는 내장 클래스를 이용하면 오류를 생성할 수 있다. 이때 그냥 오류를 생성하려면 다음의 식으로도 족하다. 

    class Oryu(Exception):
    	pass

    다만 필자는 __str__(self) 함수를 이용해, 오류가 나왔을 때 오류 메시지를 출력하는 것까지 실습하고자 했다. 참고로 Exception 클래스가 오류이므로 이를 상속한 Oryu 또한 오류이다... 정도로 이해하면 될 듯하다.

     

    Exception 클래스를 상속한 Oryu 클래스를 raise 함수를 이용하여 발생시킨다. 이때 오류가 발생할 수 있는 상황을 e()라는 함수로 새롭게 정의했다. 아까 0 < A, B < 10이라는 조건이 있었으므로, 해당 조건을 반영한다. 좀 더 자세한 설명은 아래를 참고.

    def e():							-> e()라는 함수를 정의.  
        a, b = map(int, input().split())				-> a,b를 입력했을 때
        if not 0 < a < 10 or not 0 < b < 10:			-> 0 < a,b < 10이 아니라면
            raise Oryu()						-> Oryu 클래스를 작동합시다.
        print(a-b)							-> 이후 print(a-b)를 실행합니다.

     

    이제 e()라는 함수가 만들어졌으니, 해당 함수를 시도하여 오류가 발생할 경우 어떻게 할지를 정해주면 된다. try... except... 를 이용하였다. 

    try:	
        e()			-> e() 함수를 실행해 봅니다.
    except Oryu as o:	-> Oryu(=오류)가 발생하면 o라고 간주합시다.
        print(o)		-> 이 o를 출력해 주세요.

    앞서 Oryu라는 클래스는 "잘못된 식입니다."라는 메시지를 출력하기로 약속된 상태이다. 따라서 만일 앞서 설정해 둔 조건에 맞지 않는 상황이 발생하면, "잘못된 식입니다."하고 출력해줄 것이다.

     

    위의 복잡한 과정을 거치면 입력과 결과를 다음과 같이 얻을 수도 있게 된다.

    2 -1
    잘못된 식입니다.

     

    이 글을 쓰는 시점의 저는 단계별로 풀어보기에서 함수까지 풀었습니다. 점점 푸는 속도가 더뎌지는 게 저의 사고력과 논리력의 한계가 다가오는 것 같습니다. 최대한 여러 시각에서 문제를 풀어보는 게, 다음 단계로 나아갈 때 좋은 영향을 줄 것이라고 믿습니다. 저도 코딩 시작한 지 두 달 만에 이 정도 생각을 해볼 수 있게 되었습니다. 여러분도 할 수 있어요!

    댓글

Designed by Tistory.