📒 Today I Learn/🐍 Python

[Python] 3진법 뒤집기 (직접 구하기, divmod, int)

se0ehe 2024. 9. 4. 10:59

 

 

 

 

 

 

3진법 뒤집다가 나도 뒤집어지기..
오늘도 문제에 대해서 부가 설명이 길어질 것으로 예상 되어.. 따로 글로 정리해본당..

 

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/68935

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

 

 

 

✳️ 작성한 코드 설명

def solution(n):
    result = []
    answer = 0
    
    while n != 0:
        result.append(n % 3)
        n = n // 3
        
    for i in range(len(result)):
        answer += ((3 ** (len(result) - i - 1)) * result[i])
        
    return answer

 

🧐 n = 45 일때 라는 예시로 과정을 작성해봄

 

💟 result = [] 과 answer = 0

  • result는 숫자 n을 3진법으로 변환한 결과를 저장할 빈 리스트 생성
  • sum은 변환된 값을 다시 10진법으로 합산할 때 사용할 변수

 

💟 while n != 0:

  • 주어진 숫자 n이 0이 될 때까지 반복한다.

 

💟 result.append(n % 3)

  • n을 3으로 나눈 나머지를 result 리스트에 추가
  • 3진법의 각 자릿수를 구하는 과정

 

💟 n = n // 3 

  • n을 3으로 나눈 몫으로 갱신 ( n을 3으로 나누고 몫을 n에 다시 할당하는 역할 )
  • n이 점점 작아져 결국 n = 0이 되어 while 루프가 종료
  • 만약 이 과정이 없다면 n은 변하지 않고 계속 같은 값으로 남아 있게 되며,
    while n != 0 조건이 무한히 참이 되어 루프가 종료되지 않음

 

⭐ while 루프를 통한 10진법 → 3진법

🟠 1번째 반복

  • n = 45
  • 45 % 3 = 0 → result에 0 추가
  • n = 45 // 3 = 15
  • result = [0]

 

🟠 2번째 반복

  • n = 15
  • 15 % 3 = 0 → result에 0 추가
  • n = 15 // 3 = 5
  • result = [0, 0]

 

🟠 3번째 반복

  • n = 5
  • 5 % 3 = 2 → result에 2 추가
  • n = 5 // 3 = 1
  • result = [0, 0, 2]

 

🟠 4번째 반복

  • n = 1
  • 1 % 3 = 1 → result에 1 추가
  • n = 1 // 3 = 0
  • result = [0, 0, 2, 1]

 

🟢 현재 result 리스트에 저장된 값

  • result = [0, 0, 2, 1]

 

 

💟 for i in range(len(result): 

  • result 리스트에 저장된 3진법 자릿수를 다시 10진법으로 변환하기 위해 반복

 

💟 answer += ((3 ** (len(result) - i -1) * result[i])

  • result 리스트에 저장된 3진법 숫자를 다시 10진법으로 변환하는 과정
  • 세부사항
    • result[i] : result 리스트의 i번째 요소, 즉 3진법 숫자의 각 자리 값
    • len(result) - i - 1 : 리스트의 길이에서 현재 인덱스 i를 뺀 값
    • 3 ** (len(result) - i - 1) : 3의 거듭제곱. 이는 3진법에서 각 자리의 위치에 해당하는 가중치
  • 최종적으로 이 값을 모두 더해서 answer에 저장

 

⭐ for문을 이용한 3진법 10진법

  • len(result) = 4
  • result = [0, 0, 2, 1]

 

🟠 1번째 반복 (i = 0)

  • result[0] = 0
  • 지수 :
    len(result) - i - 1
    = 4 - 0 - 1
    = 3
  • 3^3 = 27
  • 더할 값: 0 * 27 = 0
  • answer = 0 + 0 = 0

 

🟠 2번째 반복 (i = 1)

  • result[1] = 0
  • 지수 :
    len(result) - i - 1
    = 4 - 1 - 1
    = 2
  • 3^2 = 9
  • 더할 값: 0 * 9 = 0
  • answer  = 0 + 0 = 0

 

🟠 3번째 반복 (i = 2)

  • result[2] = 2
  • 지수 :
    len(result) - i - 1
    = 4 - 2 - 1
    = 1
  • 3^1 = 3
  • 더할 값: 2 * 3 = 6
  • answer = 0 + 6 = 6

 

🟠 4번째 반복 (i = 3)

  • result[3] = 1
  • 지수 :
    len(result) - i - 1
    = 4 - 3 - 1
    = 0
  • 3^0 = 1
  • 더할 값: 1 * 1 = 1
  • answer = 6 + 1 = 7

 

🟢 answer에 저장된 값

  • 7! 따라서 반환값도 7이 된다!

 

 

💟 return answer

  • 최종적으로 answer에 저장된 뒤집한 3집법 숫자를 10집법으로 변환한 값을 반환

 

 


 

 

✳️ divmod, int 를 이용해서 코드 작성

def solution(n):
    answer = ''

    while n > 0:
        n, r = divmod(n, 3)  # n을 3으로 나눈 몫과 나머지
        answer += str(r)
        
    return int(answer, 3)

💟 answer = ''

  • answer는 3진법으로 변환된 숫자를 저장하는 문자열
  • 이번에는 리스트를 이용하지 않고 문자열의 형태로 저장함
  • int 함수가 문자열을 입력 받아서 변환을 해주기 때문!

 

💟 while n > 0

  • n이 0보다 큰 동안 루프를 반복

 

💟 n, r = divmod(n, 3)

  • divmod(n, 3)는 n을 3으로 나누어 몫과 나머지를 반환
    • n은 몫으로 업데이트 됨
    • r은 현재 자릿수의 값으로, 3진법에서의 나머지

 

💟 answer += str(r)

  • 현재 자릿수의 값을 문자열로 변환하여 answer 문자열에 추가
  • 이 단계에서 answer는 3진법 숫자의 자릿수를 오른쪽부터 차례로 추가
    예를 들어, n = 10일 때, answer는 01로 변환 됨

 

💟 return int(answer, 3)

  • answer는 현재 3진법 숫자를 역순으로 저장하고 있으므로,
    이를 3진법 문자열로 간주하고 int(answer, 3)을 통해 10진법으로 변환
  • int(answer, 3)는 3진법 문자열을 10진법 정수로 변환

 

 


 

 

✳️ divmod()

  • 두 숫자를 입력받아 두 가지 결과를 반환해줌
    • : 첫 번째 숫자를 두 번째 숫자로 나눈 결과의 정수 부분
    • 나머지 : 첫 번째 숫자를 두 번째 숫자로 나눈 결과의 나머지
divmod(a, b)
  • a는 나누어지는 숫자
  • b는 나누는 숫자

 

  • 반환 값
    • divmod(a, b)는 (a // b, a % b)의 튜플을 반환
      • a // b는 a를 b로 나눈 몫
      • a % b는 a를 b로 나눈 나머지

 

 

✳️ int()

  • 다양한 방식으로 정수를 생성할 수 있는 함수

 

🟢 기본 사용법 : 문자열을 정수로 반환

int(x)

 

  • x는 정수로 변환할 문자열
  • 문자열이 정수로 변환되며, 이 경우 기본적으로 10진법으로 해석

 

🟢 진법을 지정하여 반환 : 특정 진법을 사용해 문자열을 정수로 반환

int(x, base)
  • x는 변환할 문자열
  • base는 숫자가 표현된 진법 (2부터 36까지 지원)