난이도:(보통?)
이것은 사람이모여서치킨을먹을때
피보나치의 수열을이용하여 가장이상적인 사람과치킨의황금비를 알려주는 수열이다
1인1닭 3인2닭 같이 최적의 포만감을얻을수있는 황금의비율 즉 ## '황금비' 를일컫는다!
이럴때 피보나치수열안의수가아닌 다른 자연수 를 입력받았을때 피보나치수열과
제켄도르프의정리의 의거하여 최고의 황금비 를 출력하시오
그리고 다같이 맜있는 치킨을 뜯읍시다!
피보나치의 수열이란 ? 간단히말하면 1부터 시작하여 다음수를더하여 그다음칸에 적어나가는 수이다.
1.1.2.3.5.8.13.21.34.55.89.....
황금비란 ? 피보나치의 수열 안의 가주어질때에 그것에 바로전에오는 숫자와의비율이다.
21:13 , 89:55 , 3:2 ...
제켄도르프의 정리란 ? 다른자연수에대한 피보나치수열의 황금비 를 피보나치수열들의 합으로 뽑기의한 것인데
예를들면 78이란 수의의황금비는 55(34)+21(13)+2(1)=78(48) 이가성립된다.
(설명이 이상하여 사람들이못푸는건가..)
(출처:프로글래머 님의 사이트에있는 코딩질... http://fibonachicken.herokuapp.com/ 자신의출력값과 일치하는지확인)
12개의 풀이가 있습니다.
def get_fibo_num(num):
fNum = 1
sNum = 1
list_fibo = [fNum, sNum]
while True:
tNum = fNum + sNum
if tNum < num:
list_fibo.append(tNum)
fNum = sNum
sNum = tNum
else:
break
return list_fibo
def get_golden_ratio(num):
list_fibo = sorted(get_fibo_num(num), reverse=True)
sum = 0
for i in range(len(list_fibo)):
if list_fibo[i] <= num:
num = num - list_fibo[i]
sum += list_fibo[i+1]
return sum
num = int(input("Enter a natual number: "))
print("A golden ratio of {} is {}".format(num, get_golden_ratio(num)))
최대한 직관적으로 작성했습니다.
python 3.6
def chicken(x):
if x == 0: return 0
if x == 1: return 1
a,b = 1,1
while 1:
c = a+b
if c > x: return a + chicken(x-b)
elif c == x: return b
a, b = b, c
num = int(input('자연수: '))
print('황금비: {}'.format(chicken(num)))
자연수: 78
황금비: 48
자연수: 2018
황금비: 1247
def fibonacci(n):
if n == 1:
return n
f1, f2, f3 = 0, 1, 1
while f3 <= n:
f1 = f2
f2 = f3
f3 = f1 + f2
return f2;
def zeke(n):
result=[]
while n > 0 :
f=fibonacci(n)
n=n-f
result.append(f)
return result
zeken_sum=sum(map(lambda x: fibonacci(x-1),zeke(int(input('황금비 숫자:')))))
print(zeken_sum)
코딩하게된지얼마안되어 코드가 약간복잡한데 양해바랍니다....
Python
n = 1193
fib = [0] * n
fib[0] = 1
fib[1] = 1
for i in range(2, n):
fib[i] = fib[i-1] + fib[i-2]
if fib[i] > n:
break
fib = sorted(fib, reverse=True)
#print(fib)
ans = []
while sum(ans) != n:
for i in range(len(fib)):
if fib[i] <= n-sum(ans):
ans.append(fib[i])
fib.pop(i)
break
#print(ans)
print(ans)
inNum=int(input("Input Num : "))
def getFibonacciList(num):
#inNum = 78
i=0
hwm = 0
# 주어진 수보다 작은 피보나치 수열 만들
fn = [1,1]
while hwm < int(num):
hwm = fn[i] + fn[i+1]
if hwm < int(num):
fn.append(hwm)
i = i + 1
return fn;
def getZeken(f):
#제켄도르프 정의
selNum = []
i = 0
s = 0
f.reverse()
for i in f:
if (i+s <= inNum):
s = i + s
selNum.append(i)
return selNum;
fiboNum = getFibonacciList(inNum)
print(fiboNum)
print(getZeken(fiboNum))
python 3.0
def num(res, n):
pi = [1,1]
for i in range(2,100):
m = pi[i-2]+pi[i-1]
pi.append(m)
for j in range(n,0,-1):
if res - pi[j] >= 0:
print("%d (%d)" %(pi[j],pi[j-1]))
res = res - pi[j]
if res == 0:
print("치킨냠냠")
break
n = 1193 fib = [0] * n fib[0] = 1 fib[1] = 1 for i in range(2, n): fib[i] = fib[i-1] + fib[i-2] if fib[i] > n: break fib = sorted(fib, reverse=True)
ans = [] while sum(ans) != n: for i in range(len(fib)): if fib[i] <= n-sum(ans): ans.append(fib[i]) fib.pop(i) break #print(ans) print(ans)
처음에 부분수열을 다 구해서 할랬는데 다른 분들 하신 거 보니 재미난 과정이 숨어있네요. 나만 바보된 거 같음;;
def fib_seq_under(N):
seq = [1, 1]
while seq[-1] < N:
seq.append(seq[-1] + seq[-2])
return seq[:-1]
def golden_ratio(N):
seq = fib_seq_under(N)
chicken = 0
while N:
f = seq.pop()
if f <= N:
N -= f
chicken += seq[-1]
return chicken
def fibonachicken(n):
fibo,ans = [1,1],0
while fibo[-1] < n:
fibo+= [fibo[-1]+fibo[-2]]
i = -2
while n != 0:
if fibo[i] <= n:
n -= fibo[i]
ans += fibo[i-1]
else:
i -= 1
return ans
def zeckendorf(n):
L = [1, 1]
while L[-1] <= n:
L.append(L[-2] + L[-1])
ans1 = []
ans2 = []
while n > 0:
L = list(filter(lambda x : x <= n, L))
ans1.append(L[-1])
ans2.append(L[-2])
n -= L[-1]
print(str(sum(ans1)) + ':' + str(sum(ans2)) )
>>> zeckendorf(78)
78:48
>>> zeckendorf(104)
104:64
def fibo(num):
cur=1
last=1
list_a=[]
while last<=num:
temp=last
last+=cur
cur=temp
list_a.append(cur)
return list_a
In=int(input("몇 명에서 치킨 ? "))
list_a=fibo(In)
if In in list_a:
Index=list_a.index(In)-1
print(list_a[Index],"마리 먹으면 된다.")
else:
list_b=[]
for i in range(len(list_a)-1,-1,-1):
if list_a[i]<=In:
In-=list_a[i]
if i-1<0:
list_b.append(1)
else:
list_b.append(list_a[i-1])
print(sum(list_b),"마리 먹으면 된다.")
def fiboNum(num):
fibo_lst = [1, 1]
while fibo_lst[-1]+fibo_lst[-2] < num:
fibo_lst.append(fibo_lst[-1]+fibo_lst[-2])
return fibo_lst
def searchGoldenRatio(idx, curr, ns, num):
if num == 0:
res_ratio.append(ns)
res_curr.append(curr)
return
for i in range(idx+1, len(lst)-1):
searchGoldenRatio(i, curr + str(lst[i]) + '(' + str(lst[i+1]) + ') ', ns + lst[i+1],
num - lst[i])
su = 78
lst = sorted(fiboNum(su), reverse=True)
res_ratio = []
res_curr = []
searchGoldenRatio(-1, '', 0, su)
print("+".join(res_curr[0].split()), '= {0}({1})'.format(su, res_ratio[0]))
print('{0}이란 수의의황금비는 {1} : {2}'.format(su, su, res_ratio[0]))