Python 최대공약수(유클리드 호제법) 코드 분석

분석 대상 코드

def gcd_process(a, b): while b != 0: print(f"{a} ÷ {b} = {a // b} ... {a % b}") a, b = b, a % b print("최대공약수:", a) # 한 줄 입력 a, b = map(int, input("두 정수 입력: ").split()) gcd_process(a, b)

코드의 목적: 사용자에게 두 정수를 입력받아, 유클리드 호제법을 사용하여 최대공약수(GCD, Greatest Common Divisor)를 구하는 과정을 단계별로 출력하고 최종 결과를 보여줍니다.


[1] 상세 개념 5가지

1. 최대공약수 (GCD, Greatest Common Divisor)

최대공약수란, 0이 아닌 두 개 이상의 정수의 공통된 약수 중에서 가장 큰 수를 말합니다. 예를 들어, 12와 18의 공약수는 1, 2, 3, 6이며, 이 중 가장 큰 수인 6이 최대공약수입니다.

2. 유클리드 호제법 (Euclidean Algorithm)

이 코드가 사용하는 핵심 알고리즘입니다. 유클리드 호제법은 두 양의 정수 a, b (a > b)에 대하여, "a를 b로 나눈 나머지를 r이라고 할 때, a와 b의 최대공약수는 b와 r의 최대공약수와 같다"는 원리를 이용합니다. (즉, gcd(a, b) = gcd(b, a % b)) 이 과정을 계속 반복하여 나누는 수(b)가 0이 되었을 때, 나누어지는 수(a)의 값이 바로 두 수의 최대공약수가 됩니다. 이 방법은 숫자가 매우 크더라도 효율적으로 최대공약수를 찾을 수 있게 해줍니다.

3. while 반복문과 종료 조건

while b != 0:은 'b가 0이 아닐 동안 계속 반복하라'는 의미입니다. 유클리드 호제법의 원리에 따라, 나누는 수(b)가 0이 되면 계산이 종료됩니다. 매 단계마다 b의 값은 a % b (나머지)로 바뀌는데, 나머지는 항상 나누는 수보다 작기 때문에 b의 값은 계속해서 작아지다가 결국 0이 될 수밖에 없습니다. 따라서 이 반복문은 항상 종료가 보장됩니다.

4. 튜플을 이용한 다중 할당 (a, b = b, a % b)

이 한 줄은 유클리드 호제법의 핵심을 간결하게 표현한 Python의 문법입니다. 이 코드는 다음과 같이 동작합니다.

  1. 오른쪽의 값들, 즉 현재의 b 값과 a % b(a를 b로 나눈 나머지) 값을 먼저 계산합니다.
  2. 계산된 두 값을 각각 왼쪽의 변수 ab에 동시에 할당합니다.
결과적으로, 기존의 b가 새로운 a가 되고, 기존의 나머지(a % b)가 새로운 b가 되어 다음 단계의 나눗셈을 준비합니다.

5. 사용자 입력 처리 (map, split)

a, b = map(int, input().split())는 사용자로부터 한 줄에 공백으로 구분된 두 개의 숫자를 입력받기 위한 관용적인 표현입니다.


[2] OX 퀴즈 5개

문제 1

while 루프는 a의 값이 0이 되면 종료된다.

정답: X
상세 풀이: 코드의 조건문은 while b != 0: 입니다. 따라서 나누는 수인 b의 값이 0이 될 때 루프가 종료됩니다.

문제 2

두 수 18과 48을 입력하면, 큰 수인 48이 항상 첫 번째 인자로 들어가야 코드가 정상 동작한다.

정답: X
상세 풀이: 만약 a=18, b=48로 시작하더라도, 첫 번째 반복에서 a, b = b, a % b가 실행되면 a는 48, b는 18(18 % 48의 결과)이 되어 자동으로 큰 수가 앞으로 오게 됩니다. 유클리드 호제법은 입력 순서에 상관없이 항상 올바르게 동작합니다.

문제 3

최종적으로 출력되는 최대공약수는 루프가 끝나기 직전의 b 값이다.

정답: X
상세 풀이: 루프는 b가 0이 되면 끝납니다. 최대공약수는 루프가 끝났을 때의 a 값입니다. 이 a 값은 루프의 마지막 단계에서 나누는 수였던 b의 값과 같습니다.

문제 4

코드의 a, b = b, a % b 라인은 a = bb = a % b 두 줄로 나누어 써도 결과가 동일하다.

정답: X
상세 풀이: 만약 두 줄로 나누어 쓰면, a = b가 먼저 실행되어 a의 원래 값이 사라집니다. 그 다음 줄인 b = a % b를 실행할 때는 이미 변해버린 a(원래 b값)를 사용하게 되어 b = b % b가 되므로 결과는 0이 됩니다. 올바른 값을 유지하기 위해 다중 할당이나 임시 변수가 반드시 필요합니다.

문제 5

두 수 17과 5를 입력하면, while 루프는 총 3번 실행된다.

정답: O
상세 풀이:
  1. (1회) a=17, b=5 → (a, b) = (5, 2)
  2. (2회) a=5, b=2 → (a, b) = (2, 1)
  3. (3회) a=2, b=1 → (a, b) = (1, 0)
b가 0이 되었으므로 루프가 종료됩니다. 따라서 총 3번 실행됩니다.

[3] 5지선다형 문제 5개

문제 1. 두 정수 1071과 1029를 입력했을 때, 코드의 첫 번째 단계에서 출력되는 내용은?

정답: 1번
상세 풀이: 처음 a=1071, b=1029로 함수가 시작됩니다. print(f"{a} \div {b} = {a // b} ... {a % b}") 구문은 1071 // 1029(몫)는 1, 1071 % 1029(나머지)는 42를 계산하여 "1071 \div 1029 = 1 ... 42"를 출력합니다.

문제 2. 이 코드가 기반으로 하는 핵심적인 수학 원리는 무엇인가?

정답: 4번
상세 풀이: 이 코드는 gcd(a, b) = gcd(b, a % b)라는 원리를 반복적으로 적용하여 최대공약수를 찾고 있으며, 이는 유클리드 호제법의 정의와 정확히 일치합니다.

문제 3. gcd_process(91, 39)를 실행했을 때, while 루프가 종료되는 시점의 변수 ab의 값은 각각 무엇인가?

정답: 3번
상세 풀이:
  1. 시작: a=91, b=39
  2. 1단계 후: a=39, b=13 (91 % 39 = 13)
  3. 2단계 후: a=13, b=0 (39 % 13 = 0)
b가 0이 되었으므로 이 시점에서 루프가 종료됩니다. 이때의 a는 13, b는 0입니다.

문제 4. 코드에서 a, b = map(int, input().split()) 라인의 역할에 대한 설명으로 가장 올바르지 않은 것은?

정답: 4번
상세 풀이: 해당 라인은 사용자 입력을 받아 두 개의 정수 변수 a와 b에 저장하는 역할만 합니다. 실제 최대공약수 계산은 gcd_process 함수 내에서 이루어집니다.

문제 5. 만약 두 정수로 29와 0을 입력하면 어떤 결과가 나오는가?

정답: 5번
상세 풀이: a=29, b=0으로 함수가 시작됩니다. while b != 0: 조건을 처음부터 만족하지 않으므로(b가 0이므로), while 루프는 단 한 번도 실행되지 않습니다. 따라서 루프 다음 줄인 print("최대공약수:", a)가 바로 실행되어 "최대공약수: 29"가 출력됩니다. (두 수 중 하나가 0일 때 최대공약수는 0이 아닌 다른 수입니다.)