728x90

◯문제 링크

 

[백준,10809]알파벳 찾기

 

◯코드 미리보기

Test_str = input()

alphabet_dict = {}

for i in range(97, 123):
    alphabet_dict[chr(i)] = -1
    
for i in range(len(Test_str)):
    if alphabet_dict[Test_str[i]] == -1:
        alphabet_dict[Test_str[i]] = i
    
Ans = list(alphabet_dict.values())

for i in range(len(Ans)):
    print(Ans[i],end=" ")

설명

Test_str = input()
alphabet_dict = {}

먼저 입력한 문장을 받는 변수이다.

그 뒤에 따라오는 코드는 딕셔너리 선언을 위한 코드이다. 이름에서 알 수 있듯이, 알파벳과 숫자를 같이 정리하기 위한 딕셔너리이다.

 

for i in range(97, 123):
    alphabet_dict[chr(i)] = -1

먼저 아스키 코드를 사용해서 모든 알파벳을 key로 넣어주면서, value를 -1로 할당해 준다.

 

 

for i in range(len(Test_str)):
    if alphabet_dict[Test_str[i]] == -1:
        alphabet_dict[Test_str[i]] = i

다음은 해당 코드를 활용하기 위한 코드이다. 

for문은 문장의 길이만큼 반복을 해준다.

if문과 그 아래 코드는 입력받은 문장에 해당하는 알파벳을 key로 입력했을 때 value가 -1이면 value를 자릿값으로 교체하기 위한 코드이다.

if문을 활용한 이유는, 단어가 여러번 사용되는 경우에는 맨 처음 오는 자릿수만 저장한다고 했기 때문이다. if문의 조건을 충족한다는 것은 그 이전에는 같은 문자가 없었다는 의미이다.

 

Ans = list(alphabet_dict.values())
for i in range(len(Ans)):
    print(Ans[i],end=" ")

다음은 이렇게 정리가 끝난 value값들을 모두 출력해주기 위한 작업이다.

.values()함수를 활용하면 원하는 딕셔너리의 value값들을 list형태로 저장할 수 있다. 다만 이것은 완전한 list는 아니다. 그래서 list로서 사용을 하기 위해서는 list함수로 변환이 이루어져야한다.

for문은 처리가 완료된 value값들을 한줄로 출력해주기 위한 코드이다. print의 end값을 공백 한칸으로 바꾸었다.

 

 

배운 것

⩥딕셔너리의 key와 value는 list형태로 꺼내 올 수 있다. 다만 온전한 list로 사용하려면 list로 변환해주어야 한다.

⩥딕셔너리에 원소를 추가하려면 (딕셔너리 이름)[key] = (value)의 형태로 코드를 짜면 된다.

728x90
728x90

◯문제 링크

 

[백준,2675]문자열반복

 

◯코드 미리보기

Test_case = int(input())

for i in range(Test_case):
    S, P = input().split( )
    S = int(S)
    for k in range(len(P)):
        for z in range(S):
            print(P[k],end="")
    print("")

 

설명

Test_case = int(input())

for i in range(Test_case):

먼저 문제의 반복을 위해서 반복 시킬 만큼의 test case를 입력받는다. 이렇게 입력받은 값은 for문으로 반복시킨다. 

 

그럼 for문의 안을 살펴보자.

    S, P = input().split( )
    S = int(S)

일단 문제에서 주어진 변수를 한 줄로 입력받기 위해서  split을 사용했다.

다만 S부분은 숫자이기 때문에 나중에 정수형을 변환해준다.

 

    for k in range(len(P)):
        for z in range(S):
            print(P[k],end="")

다음은 P의 길이만큼 for문을 돌린다. 이것은 문자열 인덱싱을 사용하기 위해서이다.

for문 안에 for문은 문자를 반복 출력하기 위한 for문이다. 범위는 당연히 S로 지정한다.

마지막줄은 문자를 출력해주는 print문이다. 끝부분에 end의 값을 여백이 없는 것으로 바꾸었는데, 이는 문제에서 원하는 출력을 해주기 위함이다.

 

    print("")

모든 코드가 작동하고 나서 케이스 구분을 해주기 위해서 줄바꿈을 위해 빈 print문을 하나 출력해준다.

 

배운 것

⩥print함수의 변형(end)

 

728x90

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

[백준/2231]분해합  (0) 2021.10.28
[백준,10809]알파벳 찾기  (0) 2021.03.04
[백준, 11654] 아스키코드  (0) 2021.03.04
[백준,1011]Fly me to the Alpha Centauri  (0) 2021.02.23
[백준,1065]/한수  (0) 2021.02.22
728x90

◯문제 링크

 

[백준, 11654] 아스키코드

 

◯코드 미리보기


Test_text = ord(input())

print("%s"%Test_text)

 

 

 

 

설명

 

아스키코드에 관한 함수 두가지만 알면 쉽게 풀 수 있는 문제이다.

이 문제에서 사용된 ord함수와 그 짝을 이루는 chr함수이다.

 

ord함수는 괄호안에 입력받은 문자열을 아스키코드로 변환해주는 함수이다. 주의할 점은 str형만 입력이 가능하다는 것이다. 숫자를 입력하고 싶어도 int형태로 입력하면 안되고, str형으로 변환해서 입력해야 한다.

 

chr함수는 괄호 안에 입력받은 정수형을 그 번호에 해당하는 아스키 코드로 변환해주는 함수이다. ord함수와는 반대로, 괄호 안에 int형만 와야한다.

 

 

배운 것

⩥ord함수 : 괄호안에 입력받은 문자열을 아스키코드로 변환해주는 함수

⩥chr함수 : 괄호 안에 입력받은 정수형을 그 번호에 해당하는 아스키 코드로 변환해주는 함수

 

 

 

 

 

 

728x90

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

[백준,10809]알파벳 찾기  (0) 2021.03.04
[백준,2675]문자열반복  (0) 2021.03.04
[백준,1011]Fly me to the Alpha Centauri  (0) 2021.02.23
[백준,1065]/한수  (0) 2021.02.22
[백준,4673]셀프 넘버  (0) 2021.02.22
728x90

수강한 강의

14.조건문과 반복문-03.반복문 이해하기(while)-1

15.조건문과 반복문-04.반복문 이해하기(while)-2

16.조건문과 반복문-05.반복문 이해하기(for).연습문제-1

17.조건문과 반복문-06.반복문 이해하기(for).연습문제-2

18.조건문과 반복문-03.조건문, 반복문 연습 문제 풀이

19.함수 이해 및 활용-01.함수의 이해 및 활용, 기본 파라미터, 키워드 파라미터 이해, 변수의 스코프 이해-1

20.함수 이해 및 활용-02.함수의 이해 및 활용, 기본 파라미터, 키워드 파라미터 이해, 변수의 스코프 이해-2

21.함수 이해 및 활용-03.함수의 이해 및 활용, 기본 파라미터, 키워드 파라미터 이해, 변수의 스코프 이해-3

22.함수 이해 및 활용-04.람다(lambda)함수의 이해 및 사용하기

 

 

 

복습

반복문

특정한 조건을 만족하는 동안 같은 코드를 반복해서 실행하는 문법이다.

반복문을 사용할 때 가장 주의해야 하는 것은 무한루프가 발생하지 않도록 코딩하는 것이다.

▷while문의 경우엔 조건이 true일 경우에 코드 블록을 수행하고 다시 while의 조건 부분으로 돌아온다.

 

Break

반복문 중간에 반복을 멈추고 싶을 때 사용하는 코드이다.

 

Continue

반복문의 특정 조건에서 코드를 수행하지 않고 조건으로 되돌아가기 위해 사용한다. 이렇게 하면 결과적으로 원하는 부분에서 건너뛸 수 있다.

 

for

순회 가능한 객체를 순회하면서 코드를 처리한다.

  ▷여기서 말하는 순회 가능한 객체는 리스트, 튜플, 딕셔너리 같은 것을 의미한다. 인덱싱이 가능한 것들이라고 생각해도 된다.(딕셔너리는 예외)

모든 아이템이 순회 되고 나면 for블록은 종료된다.

▷breakcontinue 둘 다 적용가능 하다.

▷loop중첩은 반복문 블록 안에 반복문을 넣는 것을 말한다. 반복할 때마다 depth가 깊어진다고 말한다.

▷for문의 범위에서 자주 쓰이는 함수로 len()함수와 range()함수가 있다.

  ▷len()함수

    ▷collection들의 길이를 구하는 함수이다.

    ▷python 내장함수이다.

  ▷range함수

    ▷리스트를 간단하게 생성하는 함수이다.

    ▷숫자를 하나만 입력 : 0부터 그 숫자-1까지 생성한다.

    ▷숫자를 두 개만 입력 : 앞 숫자부터 뒤 숫자-1까지 생성한다.

    ▷숫자를 세 개만 입력 : 마지막 숫자는 건너뛰는 숫자의 개수를 의미하고, 나머지는 위랑 동일하다.

 

 

함수

함수는 코드를 매핑한 것이다.

모든 함수는 입력과 그에 따른 출력이 존재한다.

코드를 중복 없이 재사용하기 위해서 사용한다.

내장함수 이외에도 내가 함수를 만들고 사용할 수 있다.

정의를 할 때는 def()를 사용한다.

  ▷괄호 안에는 변수를 넣을 수 있다. 이 변수는 함수 안에서만 사용된다. 이를 매개변수라고 부른다. 함수가 사용될 경우에 들어가는 값은 인자라고 부른다.

  ▷[def() : ]다음에 오는 부분을 함수의 body라고 부른다.

▷return을 통해 함수의 출력 값을 지정해줄 수 있다.

  ▷return을 만나게 되면 그 함수는 작동이 중지된다.

  ▷return뒤에 아무런 말도 없으면 None값을 출력한다.

  ▷return이 없을 때는 코드를 끝까지 실행한 뒤에 None값을 출력한다.

  ▷return을 사용할 때는 여러 개의 값을 출력할 수 도 있다. 이는 튜플을 사용한 것이다.

함수를 사용할 때는 함수가 요구하는 인자(parameter)를 정확히 입력해야만 함수가 오류 없이 동작을 한다.

함수의 이름을 정할 때는 무엇을 위한 함수인지, 어떻게 작동하는지 등 함수의 정보를 알아보기 쉽게 정해야 한다. 다만 이름이 너무 길어서는 안 된다.

함수에 인자가 꼭 필요한 것은 아니다.

함수 선언 시에, 매개변수에 대체연산자를 사용해 값을 넣어줄 수 있는데, 이를 기본파라미터라고 부른다.

  ▷기본 파라미터는 해당 매개변수에 특별한 값이 입력되지 않으면 자동으로 적용되는 값이다.

  ▷코드의 오류를 줄일 수 있다.

  ▷기본 파라미터는 매개변수 선언 중간에 올 수 없다. 무조건 끝에 와야 한다.

키워드 파라미터는 인자를 입력할 때 내가 원하는 매개변수에 값을 넣기 위해 매개변수와 대입 연산자를 같이 적어주는 것을 말한다.

  ▷사용하든 안하든 상관없지만, 통일성 있는 코드를 짜야 한다.

매개변수를 포함한 함수에서 사용된 모든 변수는 전부 함수 내부에서만 사용된다. 이것을 생명주기라고 부른다.

매개변수 앞에 *을 붙이면 가변 길이 파라미터가 된다.

  ▷가변길이 파라미터는 함수 사용 시에 내가 원하는 만큼 인자를 추가할 수 있는 매개변수를 말한다.

    ▷print()함수 같은 경우를 생각하면 된다.

  ▷함수 내부에서는 튜플로 인식한다

  ▷입력 시에는 쉼표(,)를 이용해서 값을 넣어야 한다. 값을 아예 넣지 않을 수도 있다.

  ▷가변길이 매개변수의 이름은 args로 하는 것이 좋다. 이는 파이썬의 관례이다.

매개변수 앞에 **을 붙이면 가변 길이 키워드 파라미터가 된다.

  ▷함수 내부에서는 dict로 인식한다.

  ▷함수 호출시에 이름과 값을 함께 전달할 수 있다.

  ▷가변길이 키워드 파라미터의 이름은 kwargs로 하는 것이 좋다. 이 역시 파이썬의 관례이다.

  ▷가변길이 키워드 함수를 사용하는 대표적인 경우는 format()

    ▷문자열 중간에 {}중괄호를 입력하고, 문자열이 끝나는 부분에 .format()을 붙이고 괄호 안에 넣고 싶은 변수를 입력하면 된다.

 

 

람다함수

▷def함수랑 동일하지만, 한 줄로 정의할 수 있는 것이 특징이다.

익명함수(이름이 없는 함수)라고도 부른다.

정의하는 방법 ==>a = lambda x : x**2

  ▷lambda : 람다함수를 사용할 것임을 암시한다. :을 기준으로 왼쪽은 입력값, 오른쪽은 출력값이다.

  ▷return은 적으면 안 된다.

  ▷매개변수가 여러 개인 경우에는 쉼표로 구분한다.

람다함수가 많이 쓰이는 함수

  ▷sort함수의 key매개변수

    ▷key는 내가 원하는 순서대로 정렬할 수 있게 하는 변수인데, 인자를 함수로 입력받는다. 여기서만 사용하는 함수를 lambda를 이용해서 한 줄로 입력해주면 코드가 굉장히 깔끔해진다.

  ▷filter함수

    ▷filter(a,b) : a의 규칙에 따라서 거른 원소들을 b에 저장한다.

    ▷a에 들어가는 부분도 lambda함수를 이용해서 간단하게 입력할 수 있다.

  ▷reduce함수

    ▷functools라는 모듈에 있는 함수

    ▷주어진 원소가 있는 경우에, 차례대로 2개의 원소를 가지고 연산하고 연산의 결과가 또 다음 연산의 입력으로 진행되는 함수이다. 최종적으로는 한 개의 원소만이 남게 된다.

    ▷reduce() -> 괄호 안에 lambda함수를 이용해서 어떤 연산을 할지 입력할 수 있다. 괄호 부분에는 함수가 들어가야 한다.

    ▷reduce(계산할 함수, 계산할 컬랙션)의 형태로 사용한다.

 

22강 마지막에 있는 연습문제

1,2,3번 문제

def _AVG(list1):
    import functools
    _sum = functools.reduce(lambda x,y:x+y,list1)
    Avg = _sum/len(list1)
    return int(Avg)

def PrimeNum(n):
    last = n
    if n % 2 == 0:
        last = int(n/2)

    if(n <= 1):
        return False

    for i in range(2,last):
        if n%1 == 0 :
            return False
        
    return True

def AllPrimeNum(n):
    Prime_List= []
    for i in range(2,n+1):
        if PrimeNum(i) == True:
            Prime_List.append(i)

        return len(Prime_List)


a = list(map(int,input().split( )))
print(_AVG(a))
if PrimeNum(_AVG(a)) == True:
    print("소수입니다.")

elif PrimeNum(_AVG(a)) == False:
    print("소수가 아닙니다")

print(AllPrimeNum(_AVG(a)))

 

 

 

https://bit.ly/3cx6kMd

728x90

'python > 강의 복습' 카테고리의 다른 글

[딥러닝 강의]10~13강 복습  (0) 2021.02.25
[딥러닝 강의]6~9강 복습  (0) 2021.02.18
[딥러닝 강의]1~5강 복습  (0) 2021.02.17
728x90

수강한 강의

10.데이터 타입과 컬렉션-07.컬렉션 타입 이해-4(dict)

11.데이터 타입과 컬렉션-07.컬렉션 타입 이해-4(set)

12.조건문과 반복문-01.조건문(if,elif,else)활용하기

13.조건문과 반복문-02.조건문(if,elif,else)활용하기

 

 

 

 

 

복습

 

딕셔너리

파이썬에서 가장 많이 사용되는 컬렉션 타입이다.

키와 값을 쌍으로 가지는 데이터 구조이다.

순서가 없다. 따라서 인덱싱도 불가능 하다.

  ▷인덱싱의 기능은 사용이 가능한데, 키를 입력하는 방식을 사용하는 것이다. 키를 전부 숫자로 만들면 마치 인덱싱을 하는 것처럼 사용할 수 있다. 하지만 눈에 보이는 것만 그럴뿐 실제로 인덱싱을 한 것은 아니다.

    ▷이것의 키가 내부적으로 hash값을 가지기 때문에 가능한 것이다.

  ▷순서가 없어서 원소에 접근하는데 걸리는 시간도 0이다.

    ▷딕셔너리가 keyvalue를 찾는데 최적화되어있는 구조이기 때문이다.

딕셔너리를 만들 때는 중괄호를 사용한다. keyvalue:로 연결한다.

  Ex) dictA = { ‘a’ : 1, ‘b’ : 6 }

  ▷빈 딕셔너리를 생성하려면 중괄호 안을 비우면 된다.

▷keyvalue를 추가하려면 딕셔너리이름[key이름] = value 이름을 사용하면 된다.

  ▷해당 key가 이미 딕셔너리 안에 존재한다면, value가 변한다.

▷keyvalue를 삭제하는 방법은 두 가지가 존재한다.

  1.pop

    ▷값을 한번 반환하고 삭제한다.

Ex) a.pop(b) => bvalue가 반환된다.

    ▷list의 그것과 동일하다.

  2.del

    ▷범용적으로 사용된다.

Ex) del a[b] / del one / del listA

 ->a딕셔너리의 b라는 key를 삭제, one이라는 변수 삭제, listA라는 리스트 삭제

▷Value Acess

  ▷dict[key]의 형태로 접근한다. 이 때, 키가 존재하지 않을 때는 에러가 발생한다.

  ▷.get함수를 사용하는 방법도 있다. 이 때, 키가 존재하지 않으면 None값이 반환된다.

    ▷a.get(b)의 형태로 사용한다.

  ▷프로그램을 방어적으로 설계하고 싶으면 get을 사용하는 것이  

딕셔너리의 함수

  ▷update

    ->딕셔너리 두 개를 합칠 때 사용한다.

    ->ex) a.update(b)

->ab에 같은 key가 존재할 경우 bvalue로 바뀐다.

  ▷clear

    -딕셔너리의 모든 값을 삭제한다.

    ->a.clear의 형태로 사용한다.

  ▷in

    -딕셔너리 안에서 key를 찾을 때 사용한다.

    -list의 그것과 동일한 형태로 작동하지만 큰 차이점이 하나 존재한다. 원소가 매우 많을 경우(수억 개 정도)list는 모든 원소를 다 확인하느라 성능 저하가 발생하지만, 딕셔너리는 바로 key를 찾아와서 그렇지 않다는 것이다.

      -이것은 딕셔너리의 핵심적인 기능이므로 매우 중요하다.

    -if의 조건으로 사용할 수도 있다.

  ▷keys()values()

    -각각 딕셔너리에서 모든 keyvalue를 가져와서 리스트로 만드는 함수이다.

    -a.keys() / a.values()의 형태로 사용한다.

  ▷items()

    -keyvalue를 튜플의 형태로 저장하는 함수이다.

 

Set

중복이 안 되고 순서가 없는 데이터 구조이다.

  ▷수학에서의 집합과 동일한 개념이다.

  ▷순서가 없기 때문에 인덱싱이 안된다.

딕트와 마찬가지로 중괄호로 만들 수 있다. 이 때, 원소가 keyvalue형태로 있는게 아니라 그냥 나열되어 있어야한다.

▷set(원하는 변수)형태로 사용하면 다른 자료형을 set자료형으로 바꿀 수 있다.

▷set은 집합에 적용되는 연산을 적용할 수 있다.

  ▷합집합 : a.union(b)

  ▷교집합 : a.intersection(b)

  차집합 : a.difference(b)

  부분집합인지 아닌지 -> a.issubset(b)

    값은 boolean형태로 변환된다. ba의 부분집합일 때는 true, 아닐 때는 false를 반환한다.

 

조건문

코드의 실행을 제어하는 문법이다.

조건문에 사용되는 조건의 데이터 타입은 boolean값이다. 때문에 앞서 말했던 boolean이 나오는 코드들은 전부 조건으로 사용할 수 있다.

  ▷사실 파이썬은 다른 타입도 들어 갈 수 있다. 이 경우에는 각 타입의 기본값(None, 0, 0.0, etc)들이 False를 담당함.

▷if로 특정 경우의 수를 걸러내고, else로 이외의 경우를 처리한다.

▷elifif이후에 하나씩 조절할고 싶을 때 사용하는 코드이다.

  ▷if를 여러 개 사용하면 각자 하나의 코드이지만, elif를 사용하면 전체가 하나의 코드여서 한 조건만 맞으면 다른 경우는 전부 무시한다. 결과적으로 효율이 높아진다.

조건문은 중첩으로 사용할 수 있다. 중첩이 쌓이는 것을 ‘depth(깊이)’라고 부른다.

  ▷조건문에 depth에 제한은 없다. 하지만 가독성을 위해서는 길이를 줄이는 것이 좋다.

 

 

 

https://bit.ly/3cx6kMd

728x90

'python > 강의 복습' 카테고리의 다른 글

[딥러닝 강의] 14~22강 복습  (0) 2021.02.28
[딥러닝 강의]6~9강 복습  (0) 2021.02.18
[딥러닝 강의]1~5강 복습  (0) 2021.02.17
728x90

◯문제 링크

 

[백준,1011]Fly me to the Alpha Centauri

 

◯코드 미리보기

def MRange(Range_X_to_Y):
    Move_Range = 0
    Len_of_Move_Range = 0
    for i in range(1,2**23):
        Len_of_Move_Range += i
        Move_Range += 1
        if Len_of_Move_Range >= Range_X_to_Y:
            return Move_Range
        Len_of_Move_Range += i
        Move_Range += 1
        if Len_of_Move_Range >= Range_X_to_Y:
            return Move_Range


TestCase = int(input())

for i in range(TestCase):
    x,y = map(int,input().split( ))
    print(MRange(y-x))

 

 

설명

정말 어려웠던 문제다. 어떻게 풀어야 할지 감이 전혀 오지 않았다. 그래서 해본 것이 엑셀에다가 모든 경우의 수를 적기 시작한 것이었다. 그러다보니 패턴이 보였다. 

바로 거리가 1+1+2+2+3+3+4+4+... 순서로 증가할 때마다 움직이는 횟수가 1씩 증가한다는 것이다.

그렇게 해서 코드를 짜게 되었다.

 

def MRange(Range_X_to_Y):
    Move_Range = 0
    Len_of_Move_Range = 0
    for i in range(1,2**31):
        Len_of_Move_Range += i
        Move_Range += 1
        if Len_of_Move_Range >= Range_X_to_Y:
            return Move_Range
        Len_of_Move_Range += i
        Move_Range += 1
        if Len_of_Move_Range >= Range_X_to_Y:
            return Move_Range

가장 먼저 한것은 내가 이해한 것을 코드로 구현하는 것이었다.

Move_Range는 이동거리, Len_of_Move_Range는 순서를 의미한다. Range_X_to_Y는 x와 y 사이의 거리이다.

거리와 순서 모두 거리가 반복적으로 증가하므로 for문을 사용했다. 범위는 1부터 입력의 최대값인 2의 31까지로 했다. 중간에 조건이 만족하면 식은 알아서 멈추고, 이것보다 큰 값은 나올 수 없기 때문이다.

for문의 처음은 거리와 순서를 위에서 말했던 방식으로 증가시키는 것이다. 이 과정이 끝나면 입력받은 값과 거리를 비교해서 값이 거리보다 작을 때 순서를 반환한다. 아닐 때는 앞선 과정을 한번 더 반복한다.

 

TestCase = int(input())

for i in range(TestCase):
    x,y = map(int,input().split( ))
    print(MRange(y-x))

이제 함수를 사용해줄 차례이다.

먼저 테스트케이스를 입력받는다. 그리고 그만큼 for문을 반복시킨다.

for문 안에서는 x와 y를 입력받는다. 이 때 한줄로 입력받기 위해서 map함수를 사용한다.

입력받은 값에서 구해야하는 거리를 계산한다음 아까 만든 MRange함수에 집어넣는다. 그리고 반환되는 값을 출력해준다.

 

배운 것

⩥엑셀을 이용해서 예제를 적어보는 것도 패턴 파악에 도움이 될 수 있다. 머리로만 고민하지 말자!

 

 

 

 

 

 

728x90

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

[백준,2675]문자열반복  (0) 2021.03.04
[백준, 11654] 아스키코드  (0) 2021.03.04
[백준,1065]/한수  (0) 2021.02.22
[백준,4673]셀프 넘버  (0) 2021.02.22
[백준/15596] 정수 N개의 합  (0) 2021.02.14
728x90

◯문제 링크

 

[백준,1065]/한수

 

◯코드 미리보기

def HanSu(Input_Num):
    if Input_Num < 100:
        return Input_Num

    else :
        Count_HanSu = 0

        for i in range(100,Input_Num+1):
            Base_Num = str(i)
            First = int(Base_Num[0])
            Second = int(Base_Num[1])
            Third = int(Base_Num[2])
            if Second - First == Third - Second :
                Count_HanSu += 1

        Final_Num = Count_HanSu + 99
        return Final_Num



Num = int(input())
print(HanSu(Num))

 

설명

코드에 들어가기 전에 이번 문제에서 제일 중요한 개념을 설명하겠다. 문제 이름에도 나와있는 한수이다. 문제에서 주어진 설명을 정리하면, 한수는 각 자리 숫자가 등차수열을 이루고 있는 숫자이고, 등차수열은 연속된 두개의 수의 차이가 일정한 수열이라는 것이다. 

자릿수가 3자리인 경우에는 비교가 가능하니 그냥 등차수열인지만 알아내면 되지만, 두자리와 한자리일 때는 그렇지 않으니 애매해진다. 이 문제를 해결할 방법을 우리는 예제에서 알 수 있다. 예제 2를 보면 입력된 값이 1이고 출력된 값이 1이다. 이는 한자리 숫자도 한수에 포함됨을 의미한다. 이 결과를 가지고 예제 1로 가보자. 예제 1에서 입력값은 110이고 출력값은 99이다. 100번대의 숫자들은 등차수열이 성립할 수 없다. 1에서 0으로 가는데 숫자가 1 감소했기 때문이다. 남은 숫자들은 1부터 99까지인데, 출력값이랑 일치한다. 즉, 두자리 숫자도 한수에 포함된다는 것이다. 이 두개의 결과를 가지고 우리는 문제에 접근해야한다.

 

def HanSu(Input_Num):

이번 문제도 함수를 선언해준다.

 

if Input_Num < 100:
    return Input_Num

먼저 주어진 값이 100보다 작은(=두자리거나 한자리 수일 때) 경우에는 입력값을 그대로 반환한다. 위에서도 말했듯이, 한자리 숫자와 두자리 숫자는 모두 한수이기 때문이다.

 

    else :
        Count_HanSu = 0

아닌 경우에는 한수들을 구해야한다.

일단 기본적인 변수부터 선언해준다. Count_HanSu는 한수의 갯수를 저장할 변수이다.

 

       for i in range(100,Input_Num+1):
            Base_Num = str(i)
            First = int(Base_Num[0])
            Second = int(Base_Num[1])
            Third = int(Base_Num[2])
            if Second - First == Third - Second :
                Count_HanSu += 1

for문의 범위는, 앞서 두자리와 한자리는 모두 걸렀기 때문에 100부터 시작하고, 마지막 숫자는 포함되지 않기 때문에 마지막 숫자에 1을 더해준다.

Base_Num은 자릿수들을 인덱싱으로 꺼내오기 위해 숫자 i를 문자열로 바꾼것이다. i를 바꾸는 이유는 for문이 반복하면서 계속해서 테스트하는 변수가 바로 i이기 때문이다.

First, Second, Third는 각각 첫째, 둘째, 셋째 자릿수를 의미한다. 주어지는 값의 최대가 999이고 최소가 100이기 때문에 세자리 수만 고려하면 된다.

if문의 조건은 등차수열인지를 검증한다. 조건이 True일 때, i는 한수임으로 Count_HanSu변수의 값을 1 올린다.

 

        Final_Num = Count_HanSu + 99
        return Final_Num

이렇게 for문이 종료되고 나면 세자리 숫자의 한수는 전부 세게 된다. 두자리와 한자리 숫자는 세지 않았으므로, 99를 더해준다. 그 값을 Final_Num을 저장하고 반환한다.

 

이렇게 하면 함수가 끝나게된다.

 

 

Num = int(input())
print(HanSu(Num))

이제 Num값을 입력받고, 함수의 결과값을 출력해주면 문제가 해결된다.

 

 

배운 것

따로 새롭게 배운 개념은 없다.

728x90

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

[백준, 11654] 아스키코드  (0) 2021.03.04
[백준,1011]Fly me to the Alpha Centauri  (0) 2021.02.23
[백준,4673]셀프 넘버  (0) 2021.02.22
[백준/15596] 정수 N개의 합  (0) 2021.02.14
[백준/2588] 곱셈  (0) 2021.02.03
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