μΌ | μ | ν | μ | λͺ© | κΈ | ν |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- data communication
- Rust
- Python
- μλ°
- μλ° κΈ°μ΄
- C
- Database
- νμ΄μ¬ μ²Όλ¦°μ§
- ubuntu
- Operating System
- λ°±μ€
- νμ΄μ¬
- νμ΄μ¬ μ±λ¦°μ§
- μκ³ λ¦¬μ¦
- Reversing
- μ€λΌν΄
- νμ΄μ¬ μκ³ λ¦¬μ¦
- λ°μ΄ν° ν΅μ
- μ°λΆν¬
- λ¬μ€νΈ
- μ€λΌν΄DB
- λ°μ΄ν°λ² μ΄μ€
- μλ° κ°λ
- OS
- λ¬μ€νΈ μμ
- Python challenge
- μ΄μ체μ
- java
- λ¬μ€νΈ νλ‘κ·Έλλ° κ³΅μ κ°μ΄λ
- λ°±μ€ λ¬μ€νΈ
Archives
- Today
- Total
IT’s Portfolio
[Python] Fibonacci Sequence in Python λ³Έλ¬Έ
728x90
λ°μν
π» Fibonacci Sequence in Python
πβοΈ What Fibonacci Sequence?
- λ¨μν λ¨μ‘° μ¦κ°(monotonically increasing) μμ΄λ‘ μμ λ μλ₯Ό λν΄κ°λ©° μμ±λλ μμ΄
- $F_{i+1} = F_{i} + F_{i-1}$
Fibonacci Seq
곡μ : $F_{i} = F_{i-1} + F_{i-2}$
- $F_{0} = 0$
- $F_{1} = F_{2} = 1$
- $F_{i+1} = F_{i} + F_{i-1}$
- μμ μμλ§ λ³΄λ©΄ Fibonacci μμ΄μ nλ²μ§Έ μλ₯Ό μ°Ύλ μ½λλ μ½κ² ꡬνμ΄ κ°λ₯
- μλμμ μμ ν μ½λλ€μ 1100μ κ°κ° ν λΉνμ¬ μ£ΌνΌν° λ
ΈνΈλΆμ
%%timeit
μ μ¬μ©ν΄ μ²λ¦¬ μκ°μ νμΈν΄λ³΄μ- μ½λλ€μ print ν¨μλ₯Ό λͺ¨λ μ μΈνκ³ λ¨μ ν¨μ νΈμΆλ§μΌλ‘ μκ°μ μΈ‘μ ν¨
π λ¨μ μ¬κ·
- λ¨μν 곡μλ§ λμ νμ¬ μ¬κ·μ μΌλ‘ νμ΄ν΄λ³΄μ
def fibo(n):
return n if n<=1 else fibo(n-1) + fibo(n-2)
num = int(input())
print(fibo(num))
- 곡μμ λ°λΌ 0λ²μ§Έ μλ 0μ΄λ©° 1λ²μ§Έ μλ 1
- nμ΄ 2 μ΄μμΌ κ²½μ°λ μ¬κ· μ²λ¦¬νλ©° κ° λ°ν
- nμ μΈμκ°μ 32 μ΄μμ μ«μκ° ν λΉλλ©΄ κ²°κ³Όκ° λ°ν μλκ° λμ λκ² λλ €μ§
- νμμ ν°λ―Έλμμλ 43 μ΄μμ μ«μλΆν° νλ‘μΈμ€κ° λ©μΆλ κ²μΌλ‘ νμΈλ¨
- 1100 κ° ν λΉ -> μ°μ° λΆκ°
fibo = lambda n: n if n<=1 else fibo(n-1) + fibo(n-2)
num = int(input())
print(fibo(num))
- λ¨μ μ¬κ· μ½λλ₯Ό λλ€ννμμΌλ‘ λνλΈ μ½λ
- 1100 κ° ν λΉ -> μ°μ° λΆκ°
- ν΄λΉ λ°©λ²μ ν¨μκ° ν λ² νΈμΆλλ©΄ λ€μ λ λ² νΈμΆλκΈ° λλ¬Έμ μκ°λ³΅μ‘λλ $O(2^n)$ μ΄ λ¨
π 무μμ λ°λ³΅
- λ³΄ν΅ Fibonacci Sequenceλ μ¬κ·ν¨μμ λν κ°λ μ μ΅λνλ €κ³ κ³΅λΆνλ μκ³ λ¦¬μ¦μ΄μ§λ§ 무μμ λ°λ³΅μ ν΅ν΄ κ²°κ³Όκ°μ μ»μ μ μμ
def fibo(n):
fibo_arr = [0, 1]
for i in range(len(fibo_arr), n+1):
fibo_arr[i%2] = fibo_arr[(n-1)%2] + fibo_arr[(n-2)%2]
return fibo_arr[n%2]
num = int(input())
print(fibo(num))
- Fibonacci Sequence μ μμ λ§κ² λ³μ μ΄κΈ°ν ν nλ²μ§ΈκΉμ§ λ°λ³΅μ ν΅ν΄ λͺ¨λ νμ ꡬν¨
- 1100 κ° ν λΉ -> 125 µs ± 692 ns
def fibo(n):
if n <= 1: return n
a, b = 0, 1
for _ in range(n-1):
a, b = b, a+b
return b
num = int(input())
print(fibo(num))
- λ¨μ λ³μ λ κ°λ§μΌλ‘ ꡬνν κ°μ λ°©μμ μ½λ
- 1100 κ° ν λΉ -> 37.8 µs ± 84.6 ns
- ν΄λΉ λ°©λ²μ μ λ ₯κ°μΈ nλ§νΌ κ³μ°νκΈ° λλ¬Έμ μκ°λ³΅μ‘λλ $O(n)$
- μκ°λ³΅μ‘λλ‘ λΉκ΅ν μ λ¨μ μ¬κ·λ³΄λ€ ν¨μ¬ ν¨μ¨μ μΈ κ²μ μ μ μμ
π μ¬κ·μ λμ κ³νλ²
- λμ κ³νλ² : λΆλΆλ¬Έμ λ₯Ό ν΄κ²°νλ©΄ ν΄λΉ κ°μ μ μ₯νλ κ³΅κ° μ¬μ©
- λ°°μ΄μ μ¬μ©ν μ¬κ·μ νμ΄
- μ μ₯곡κ°μ μλ λΆλΆλ¬Έμ μ κ°μ μ°Ύκ³ μμΌλ©΄ κ³μ°
def fibo(n):
fibo_arr = [0, 1]
def iterator(n):
if n<2: return n
try:
if fibo_arr[n]: return fibo_arr[n]
except IndexError:
pass
fibo_arr.append(iterator(n-1)+iterator(n-2))
return fibo_arr[n]
return iterator(n)
num = int(input())
print(fibo(num))
- 1100 κ° ν λΉ -> 365 µs ± 188 ns
- λμ κ³νλ²μ 무μμ λ°λ³΅ μ½λμλ μ μ©μ΄ κ°λ₯ -> λ°λ³΅μ λμ κ³νλ²
- μ¬κ·μ λμ κ³νλ²μ ν¨μλ₯Ό νΈμΆνλ λ° λ°λ₯΄λ μ€λ²ν€λκ° λ°μνκΈ° λλ¬Έμ μ λμ μΌλ‘λ λ°λ³΅μ λμ κ³νλ²λ³΄λ€ μκ°μ΄ μ€λ κ±Έλ¦Ό
- νμ§λ§ λ λ€ μκ°λ³΅μ‘λλ $O(n)$
- μ€λ²ν€λ(overhead) : μ΄λ€ μ²λ¦¬λ₯Ό νκΈ° μν΄ λ€μ΄κ°λ κ°μ μ μΈ μκ°, λ©λͺ¨λ¦¬ λ±μ μΉν¨
def fibo(n, __fibo_arr={0: 0, 1: 1}):
if n in __fibo_arr: return __fibo_arr[n]
__fibo_arr[n] = fibo(n-1)+fibo(n-2)
return __fibo_arr[n]
num = int(input())
print(fibo(num))
- νμ΄μ¬ ν¨μμ λμ λ°©μμ νμ©ν μ¬κ·μ λμ κ³νλ²μ λ λ€λ₯Έ μ½λ
- λ³΄ν΅ ν¨μ λ΄μ μ μΈλ λ°μ΄ν°λ ν¨μκ° νΈμΆλ λ μμ±λκ³ ν¨μκ° μ’
λ£λ λ νκΈ°λλ©° μμ νμλ μ΄λ£¨μ΄μ§
- μ μ½λμ κ°μ΄ μνλ λ°μ΄ν°λ₯Ό ν¨μ μ μλΆμ μ μΌλ©΄ κ·Έ μλ£κ΅¬μ‘°λ ν¨μκ° μ μλ λ μμ±λμ΄ ν¨μκ° νΈμΆλκ±°λ μ’ λ£λκ±°λ μκ΄μμ΄ ν¨μ μμ²΄κ° λ©λͺ¨λ¦¬μμ μ§μμ§κΈ° μ κΉμ§ κ°μ΄ μ μ§λ¨
- ν¨μ μ€ν μ λ°μ΄ν°κ° κΎΈμ€ν λ³ννκ³ κ°μ΄ 보쑴λκΈ°μ μμνμ§ λͺ»ν μλ¬λ₯Ό λ§μ£Όν μ μλ λ°©μ
- νμ΄μ¬μ λ΄λΆ λμ λ°©μμ νμ©νκΈ°μ νμ΄μ¬μμλ§ κ΅¬ν κ°λ₯ν λ°©μ
- 1100 κ° ν λΉ -> 266 µs ± 550 ns
π νλ ¬ μ°μ°
- νλ ¬ μ°μ°μ Fibonacci 곡μ
- $(\frac{F_{n+1}} {F_{n}}$ $\frac{F_{n}} {F_{n-1}})$ $=$ $(\frac{1} {1}$ $\frac{1} {0})^n$
- νλ ¬ μ°μ° μ€ κ³±μ κ³Ό κ±°λμ κ³±μ λν ν¬μ€ν
- νλ ¬ μ°μ° μ€ νλ ¬μ κ³±μ νλ±μμ λν ν¬μ€ν
- $n^{64}$ μ ꡬνλ €λ©΄ $n$ μ 64λ² κ³±ν΄ κ΅¬ν μ μμ
- 2μ μ κ³±μλ₯Ό νμ©ν΄ κ²°κ³Όλ¬Όμ 6λ² μ κ³±νλ©΄ $n^{64}$
- $log_264$
- $(n^{1})^2 = (n^{2})^2 = (n^{4})^2 = (n^{8})^2 = (n^{16})^2 = (n^{32})^2 = n^{64}$
- 2μ μ κ³±μλ₯Ό νμ©ν΄ κ²°κ³Όλ¬Όμ 6λ² μ κ³±νλ©΄ $n^{64}$
- $n^{100}$ μ ꡬνλ €λ©΄ $n$ μ 100λ² κ³±ν΄ κ΅¬ν μ μμ
- λͺ¨λ μμ°μλ 2μ μ κ³±μμ ν©μΌλ‘ λνλΌ μ μμ
- $n^{100} = n^{64} \times n^{32} \times n^4$
- λͺ¨λ μμ°μλ 2μ μ κ³±μμ ν©μΌλ‘ λνλΌ μ μμ
- λ€μκ³Ό κ°μ λ°©λ²μ μ μ©νμ¬ λΆλΆλ¬Έμ μ κ°μ μ μ₯ν΄λκ³ νμ μ κΊΌλ΄μ μ¬μ©νλ λ°©μμ ꡬν
def fibo(n):
# 2*2 λ°°μ΄ ν¬κΈ° κ³ μ κ°
SIZE = 2
# fibonacci sequence νλ ¬ μ°μ°μ κΈ°λ³Έκ°
BASE = [[1, 1], [1, 0]]
# νλ ¬μ κ³±μ
μ λν νλ±μ
IDENTITY = [[1, 0], [0, 1]]
# νλ ¬μ κ³±μ
μ°μ° ν¨μ
def square_matrix_operation(a, b, size=SIZE):
# κ²°κ³Όκ°μ λ΄μ λ°°μ΄ μ μΈ λ° μ΄κΈ°ν
new = [[0 for _ in range(size)] for _ in range(size)]
for i in range(size):
for j in range(size):
for k in range(size):
new[i][j] += a[i][k] * b[k][j]
return new
# νλ ¬μ nμΉμ ꡬνκΈ° μν νλ¨ ν¨μ
def matrix_judgment(n):
# μ΅μ’
κ²°κ³Όλ¬Ό
matrix = IDENTITY.copy()
# μμμ μΈ λ°°μ΄
tmp = BASE.copy()
k = 0
# 0 μ΄μμ μ μ kμ λν μμ°μ nμ΄ 2**k λ₯Ό ν¬ν¨νλμ§ νλ¨νλ μ½λ
while 2 ** k <= n:
# λΉνΈ μ°μ°μμΈ &μ <<λ₯Ό μ¬μ©νμ¬ ν¬ν¨ μ¬λΆ νλ¨
if n & (1 << k) != 0:
matrix = square_matrix_operation(matrix, tmp)
k+=1
# BASEλ₯Ό ν΅ν΄ κ³μ 2**k νλ ¬μ μ μ₯νλ μ½λ
tmp = square_matrix_operation(tmp, tmp)
return matrix
return matrix_judgment(n)[0][1]
num = int(input())
print(fibo(num))
BASE
: Fibonacci Sequence νλ ¬ μ°μ° 곡μμ κΈ°λ³Έμ΄ λλ λ³μIDENTITY
: νλ ¬ κ³±μ μ νλ±μ λ³μsquare_matrix_operation
: μ λ°©ν νλ ¬μ κ³±μ μ ꡬνν ν¨μmatrix judgment
:square_matrix_operation
ν¨μμκ² μ΄λ€ κ°μ λκΈΈμ§ νλ¨νλ ν¨μmatrix
: $n$μ κ°μ΄ 0μΌ λλ₯Ό κ³ λ €νμ¬ νλ±μμ copyν λ³μtmp
: $k$μ κ°μ΄ 컀μ§μ λ°λΌ κΎΈμ€ν $2^k$ νλ ¬μ μ μ₯νλ λ³μ- $n$μ΄ $2^k$λ₯Ό ν¬ν¨νλμ§μ λν μ¬λΆλ₯Ό while λ°λ³΅λ¬Έκ³Ό λΉνΈ μ°μ°μλ‘ νλ¨
- ν¬ν¨νλ€λ©΄ $n$μ ꡬμ±νλ $2^k$ 쑰건μμ
square_matrix_operation
ν¨μμmatrix
μtmp
λ₯Ό λκΉ
- ν¬ν¨νλ€λ©΄ $n$μ ꡬμ±νλ $2^k$ 쑰건μμ
- 1100 κ° ν λΉ -> 43.9 µs ± 43.4 ns
- ν΄λΉ λ°©λ²μ μκ°λ³΅μ‘λλ $O(log_2n)$
π μΌλ°ν μ°μ°
- Fibonacci μ
- $F_{i+1} = F_i + F_{i-1}$
- $F_1 = F_2 = 1$
- $\alpha$μ $\beta$ μ μ
- $\alpha + \beta = 1$
- $\alpha\beta = -1$
- λ°©μ μ 1
- $F_{i+1} - F_i - F_{i-1} = 0$
- $F_{i+1} - F_i = \beta(F_i - F_{i-1})$
- = $\beta^2(F_{i-1} - \alpha F_{i-2})$
- = $\beta^{i-1}(F_2 - \alpha F_1)$
- = $\beta^{i-1}(1 - \alpha)$
- λ°©μ μ 2
- $F_{i+1} - F_i - F_{i-1} = 0$
- $F_{i+1} - F_i = \alpha(F_i - F_{i-1})$
- = $\alpha^2(F_{i-1} - \beta F_{i-2})$
- = $\alpha^{i-1}(F_2 - \beta F_1)$
- = $\alpha^{i-1}(1 - \beta)$
- λ°©μ μ 1κ³Ό 2 μ 리
- $F_i = \frac{1}{\alpha-\beta}\alpha^{i-1}(1 - \beta)-\beta^{i-1}(1-\alpha)$
- = $\frac{\alpha^i-\beta^i}{\alpha-\beta}$
- $\alpha$μ $\beta$ ꡬνκΈ°
- κ·Όμ λ°©μ μ μ¬μ©
- $\alpha=\frac{1+\sqrt{5}}{2}$
- $\beta=\frac{1-\sqrt{5}}{2}$
- λμ
νκΈ°
- $F_i=\frac{1}{\sqrt{5}}(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n$
def fibo(n):
sqrt_5 = 5 ** (1/2)
result = 1 / sqrt_5 * ( ((1 + sqrt_5) / 2) ** n - ((1 - sqrt_5) / 2) ** n )
return int(result)
num = int(input())
print(fibo(num))
- $n=72$λΆν° μΌλ°ν μ°μ°μ΄ 1 λ νΌ
- μμ νΉμ±μ $n$μ΄ μ»€μ§λ©΄ 컀μ§μλ‘ μ€μ°¨λ²μκ° λμ΄λ¨
- μκ°λ³΅μ‘λλ‘ λ°μ§λ©΄ ν¨μ¨μ μΈ μ½λκ° λ§μΌλ μ νλλ‘ λ°μ§λ©΄ μΈ μ΄μ κ° μλ μ½λ
- 1100 κ° ν λΉ -> 431 ns ± 0.86 ns
- ν΄λΉ λ°©λ²μ μκ°λ³΅μ‘λλ $O(log_n)$
728x90
λ°μν
'Development Study > Python' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Python] Generator (0) | 2022.11.30 |
---|---|
[Python] Iterator (0) | 2022.11.28 |
[Python] requestsμ urllib (0) | 2022.11.18 |
[Algorithm] Baekjoon - λ°λ³΅λ¬Έ λ¨κ³ (0) | 2022.10.12 |
[Python] νμ΄μ¬μ λ¬Έμμ΄ ν¬λ©ν Ver.2 (0) | 2022.10.06 |
Comments