μ€λ μ¬κ· ν¨μλ₯Ό 곡λΆνλ©΄μ μ μ νμλ λ°±μ€ λ¬Έμ κ° μκ°μ΄ λμ κ°μ΄ μ 리ν΄λ³΄κ³ μ κ°μ§κ³ μλ€.
π μ¬κ·ν¨μ(Recursion Function)
- μ½κ² λ§νλ©΄, μκΈ° μμ μ νΈμΆνλ ν¨μ.
- μμΈν μ€λͺ μ μ¬κ·ν¨μ μν€νΌλμ μ°Έκ³
- μνμ κ·λ©λ²κ³Ό λΉμ·ν¨
- μ€μ²΄νμ§ μλ κ°λ μ μνμ λͺ¨λΈλ‘ λ§λ€κ³ , κ·Έ μνμ λͺ¨λΈμ νλμ© μ°¨κ°μμΌκ°λ©΄μ νΈμΆνλ κ²λ§μΌλ‘λ λ¬Έμ κ° ν΄κ²°λκ² νλ κ²
1 ) μ¬κ·ν¨μμ νμ©
- μ¬κ·μ μΌλ‘ λ¬Έμ λ₯Ό νΌλ€λ κ² : κ°μ ννμ λ μμ λ¬Έμ λ₯Ό νκ³ , λΆλΆ λ¬Έμ μ λ΅μ μ΄μ©ν΄μ κΈ°μ‘΄ λ¬Έμ λ₯Ό νΈλ κ²! 1
- μ¬κ·μ μΌλ‘ νκΈ° μν΄μλ νμ μλμ κ°μ΄ λ caseλ₯Ό λλμ΄μ μκ°ν΄μΌνλ€.
- Base case: μ΄λ―Έ λ¬Έμ κ° μΆ©λΆν μμμ, λ μμ λΆλΆ λ¬Έμ λ‘ λλμ§ μκ³ λ λ°λ‘ λ΅μ μ μ μλ κ²½μ°
- Recursive case: ν λ¬Έμ κ° λ무 컀μ, κ°μ ννμ λ μμ λΆλΆ λ¬Έμ λ₯Ό μ¬κ·μ μΌλ‘ νΈλ κ²½μ°
- μμ : ν©ν λ¦¬μΌ λ¬Έμ
'''[ν©ν 리μΌ]'''
# μ¬κ·μ νμ΄
def factorial(n):
# base case
if n == 0:
return 1
# recursive case
return factorial(n - 1) * n
print(factorial(3))
# λ°λ³΅λ¬Έ νμ΄
def factorial_loop(n):
result = 1
for i in range(1, n + 1):
# print(i) # 1, 2, 3
result *= i
return result
print(factorial_loop(3))
2) μ¬κ·ν¨μ vs λ°λ³΅λ¬Έ
μμ ν©ν λ¦¬μΌ μμ μμλ μ μ μλ―, λλΆλΆμ μ¬κ·ν¨μλ λ°λ³΅λ¬Έ(iteration, loop)κ³Ό λ³μλ₯Ό μ΄μ©νλ λ°λ³΅μ μκ³ λ¦¬μ¦μΌλ‘ ꡬνμ΄ κ°λ₯νκ³ κ·Έ μλ μ±λ¦½νλ€.
- λ°λ³΅λ¬Έμ μ½λμμ λλκ³ 'μ΄ λΈλ‘μ λ°λ³΅λ κ²μ'νκ³ μλ €μ£Όλ κ²κ³Ό λ€λ₯΄κ² μ¬κ·λ λ³λ€λ₯Έ νμ μμ΄ νΌμ λκ² λλ―λ‘ μ½λ λ΄μμ κ°λ μ±μ΄ λ¨μ΄μ§κ³ νλ¦μ μΆμ νκΈ° μ΄λ ΅λ€.
- μ¬κ·μ μΌλ‘ λ무 λ§μ ν¨μ νΈμΆμ΄ μλ μκ³ λ¦¬μ¦(Call Stackμ΄ λ§μ΄ μμ¬ μ€λ₯κ° λλ μκ³ λ¦¬μ¦)μΌ κ² κ°μ κ²½μ°μλ κ³ΌλΆνλ‘ νλ‘κ·Έλ¨μ΄ μ€λ¨ λ μ μλ€.(stack overflow) μ΄λ¬ν κ²½μ°μλ λ°λ³΅λ¬Έμ μ¬μ©νλ κ²μ κΆμ₯! 2
- μ¬κ·ν¨μ μ€κ³ μ, μ λ ₯κ°μ΄ μ’ λ£ μ‘°κ±΄μΌλ‘ μλ ΄νλμ§λ₯Ό κΌ κ²μ¦ν΄μΌ νλ€.
- κ·ΈλΌμλ λΆκ΅¬νκ³ μ¬κ·ν¨μλ₯Ό λ°°μμΌ νλ μ΄μ λ λ¨μν κΈ°κ³μ μΈ μ΅μ ν μμ€μ μ΄μΌκΈ°λ₯Ό λμ΄μ, μκ³ λ¦¬μ¦μ μΈ‘λ©΄μμ 보μλ©΄ μ¬κ·μ μ¬κ³ λ°©μμ νμμ μ°μ΅νλ κ²μ΄ λ§€μ° μ€μνκΈ° λλ¬Έ! μ¬κ·μ μ¬κ³ λ°©μμ νν λ§νλ λΆν μ 볡μ κΈ°μ΄λ₯Ό λλ€.
- μ΄λ€ 리μ€νΈμ ν©μ ꡬνλ κ²½μ°λ₯Ό μκ°ν΄λ³΄μ. λ¨μν λͺ λ Ήν μ¬κ³ μ μ΅μν΄μ‘λ€λ©΄ μ΄λ₯Ό $O(n)$μΌλ‘ ꡬνκ³ , κ·Έ λ΅μ λ§μ‘±νμ κ²μ΄λ€. νμ§λ§ μ΄ λ¬Έμ λ μ¬κ·μ μΌλ‘ μκ°ν κ²½μ° $O(log n)$λ§μ ν΄κ²°ν μ μλ€. μ΄μ²λΌ κΈ°κ³μ μμ€μ μ΅μ νκ° μλλΌ, λ λμ μμ€μ μμ°μ±κ³Ό ν¨μ¨μ μΆκ΅¬νλ€λ©΄ νμμ μ¬κ·μ μΌλ‘ μ¬κ³ νλ μ΅κ΄μ λ€μ¬μΌ νλ€! πͺ
3) Call Stack 1000κ°(κΈ°λ³Έ κ°) μ΄μμΌλ‘ λ리λ λ°©λ²
sys λΌμ΄λΈλ¬λ¦¬λ₯Ό ν΅ν΄ νμ¬ νκ³λ₯Ό μΆλ ₯ν΄μ νμΈμ΄ κ°λ₯νκ³ , κ°μ μμ ν μλ μλ€. π₯π
import sys
# κΈ°λ³Έ κ° : 1000
print(sys.getrecursionlimit())
# νκ³ λ리기
sys.setrecursionlimit(3000)
# λλ €μ§ νκ³ νμΈ : 3000
print(sys.getrecursionlimit())
π μ ν΄λ¦¬λ νΈμ λ²(Euclidean algorithm)
- 2κ°μ μμ°μ λλ μ μμ 3μ΅λ곡μ½μ(GCD)λ₯Ό ꡬνλ μκ³ λ¦¬μ¦μ νλ
- νΈμ λ² : λ μκ° μλ‘ μλλ°© μλ₯Ό λλμ΄μ κ²°κ΅ μνλ μλ₯Ό μκ³ λ¦¬μ¦μ λ§νλ€.
- μ ν΄λ¦¬λ νΈμ λ²μ λλμ λ§ λ°λ³΅ν΄μ μ΅λ곡μ½μλ₯Ό ꡬν μ μλ€.
- λ μκ° μ무리 컀λ μ ν΄μ§ μμλ‘ κ³μ°νλ©΄ ν¨μ¨μ μΌλ‘ μ΅λ곡μ½μλ₯Ό ꡬν μ μλ€.
- λ°©λ² : 2κ°μ μμ°μ $x, y$μ λν΄μ $x$λ₯Ό $y$λ‘ λλ λλ¨Έμ§λ₯Ό $r$μ΄λΌκ³ νλ©΄, $x$μ $y$μ μ΅λ곡μ½μλ $y$μ $r$μ μ΅λ곡μ½μμ κ°λ€. μ΄ μ±μ§μ λ°λΌ, $y$λ₯Ό $r$λ‘ λλ λλ¨Έμ§ $r'$λ₯Ό ꡬνκ³ λ€μ $r$μ $r'$λ‘ λλ λλ¨Έμ§λ₯Ό ꡬνλ κ³Όμ μ λ°λ³΅νμ¬ λλ¨Έμ§κ° 0μ΄ λμμ λ λλλ μκ° $x$μ $y$μ μ΅λ곡μ½μμ΄λ€.
- μμλ₯Ό 보면 μ΄ν΄κ° λΉ λ₯΄λ€.
- 19μ 7μ μ΅λ곡μ½μλ₯Ό ꡬν΄λ³΄μ
- 19μ 7μ μ΅λ곡μ½μλ 7μ 5μ μ΅λ곡μ½μμ κ°λ€. μ΄ μ±μ§μ λ°λΌ, 7λ₯Ό 5λ‘ λλ λλ¨Έμ§ 2λ₯Ό ꡬνκ³ λ€μ 5μ 2λ‘ λλ λλ¨Έμ§λ₯Ό ꡬνλ κ³Όμ μ λ°λ³΅νμ¬ λλ¨Έμ§κ° 0μ΄ λμμ λ λλλ μμΈ 1μ΄ 19μ 7μ μ΅λ곡μ½μμ΄λ€.
19 = 7x2 + 5
7 = 5x1 + 2
5 = 2x2 + 1
2 = 1X2 + 0
λ°±μ€ 2609 [μ΅λ곡μ½μμ μ΅μ곡배μ]
π Problem
https://www.acmicpc.net/problem/2609
π Note
- 곡μ½μ : λ μ μ¬μ΄μμ 곡ν΅μΌλ‘ μ‘΄μ¬νλ μ½μ
- μ΅λ곡μ½μ(GCD, Greate Common Divisor) : 곡μ½μ μ€μ κ°μ₯ ν° κ³΅μ½μ
- 곡배μ : λ μμ 곡ν΅μ μΈ λ°°μ
- μ΅μ곡배μ(LCM, Least Common Multiple) : 곡배μ μ€μ μ μΌ μμ 곡배μ
'''
π» code
1. gcd(a, b)
κ³μν΄μ aλ₯Ό bλ‘ λλμ΄μ bλ₯Ό aμ λλ λλ¨Έμ§ bλ₯Ό λμ
μμΌμ bκ° 0μ΄ λ λκΉμ§ λ°λ³΅νλ©΄
λ¨λ aμ κ°μ΄ μ΅λ곡μ½μκ° λλ€
def gcd(a, b):
while b > 0:
a, b = b, a % b
return a
2. lcm(a, b)
a, bμ κ³±μ a, bμ μ΅λ곡μ½μλ‘ λλ κ°μ΄λ€.(λͺ« : //)
gcd * lcm= num1 * num2
def lcm(a, b):
return a * b // gcd(a, b)
'''
π Submission Code
# case 1 : μ΄λ―Έ ꡬνμ΄ λμ΄μλ math λͺ¨λμ μν¬νΈν΄μ μ¬μ©ν μ μλ€.
import math
num1, num2 = map(int, input().split())
print(math.gcd(num1, num2))
print(math.lcm(num1, num2))
# case 2 : μ ν΄λ¦¬λ νΈμ λ²
num1, num2 = map(int, input().split())
def gcd(num1, num2):
while num2 > 0:
num1, num2 = num2, num1 % num2
return num1
def lcm(num1, num2):
return num1 * num2 // gcd(num1, num2)
print(gcd(num1, num2))
print(lcm(num1, num2))
π μ¬κ·ν¨μμ μ΅μ곡μ½μ
def factor(num1, num2):
# μ ν΄λ¦¬λ νΈμ λ²
remain = num1 % num2
# check
print(f"num1: {num1}, num2: {num2}, λλ¨Έμ§ : {remain}")
# base case
if remain == 0:
return num2
# recursive case
return factor(num2, remain)
'''
μΆλ ₯ :
num1: 7, num2: 19, λλ¨Έμ§ : 7
num1: 19, num2: 7, λλ¨Έμ§ : 5
num1: 7, num2: 5, λλ¨Έμ§ : 2
num1: 5, num2: 2, λλ¨Έμ§ : 1
num1: 2, num2: 1, λλ¨Έμ§ : 0
1
'''
π Reference
- μ¬κ·ν¨μ λ무μν€
- μ ν΄λ¦¬λ νΈμ λ² μν€λ°±κ³Ό
- νμ΄μ¬ λ©λͺ¨λ¦¬ μκ°ννλ©΄μ μ½λ© κ°λ₯ν μ¬μ΄νΈ
- μ¬κ·ν¨μ μ¬μ¨ gif μΆμ²
- μ½λμ μκ³ λ¦¬μ¦μ μ μ κ°μ
- (= λΆλΆ λ¬Έμ , Subproblem) [λ³Έλ¬ΈμΌλ‘]
- μ½ μ€ν μ΄λ μ»΄ν¨ν° νλ‘κ·Έλ¨μμ νμ¬ μ€ν μ€μΈ μλΈλ£¨ν΄μ κ΄ν μ 보λ₯Ό μ μ₯νλ μ€ν μλ£κ΅¬μ‘°μ΄λ€. [λ³Έλ¬ΈμΌλ‘]
- γμνγ λ¬Έμκ° λ μμΌλ‘, λνκΈ°, λΉΌκΈ°, κ³±νκΈ°μ ννκ³ , λλλ μΌμ΄ μλ μ 리μ. [λ³Έλ¬ΈμΌλ‘]