########################################################################################
##############################   Rekurzia princip  #####################################
'''
def f_recursion(PARAMS):
    #stop condition - params are small result is simple
    if PARAMS <= c:
        return result

    #compute solution of smaller problem / problems  - smaller params
    sol1 = f_recursion(params)
    sol2 = f_recursion(params)
    ...

    combine solution of smaller problems (smaller params) to solution of big problem defined by PARAMS
    return combine(sol1, ... ,sol2)
'''
def factorial_recursion(N):
    if N <= 1:
        return 1
    sol = factorial_recursion(N - 1)
    return sol*N

########################################################################################
####################################Jednoducha rekurzia#################################
'''
#naprogramujte funkciu ktora spocita rad 1 + 2 + ... + n
def sum1toN(n):
    if ??:
        return ??
    return ??

#Naprogramujte funkciu ktora spocita prvkov zoznamu
#Idea: suma celeho zoznamu =  prvy prvok + suma najakeho zoznamu   
def list_sum(S):
    if len(S) == 1:
        return ??
    return S[??] + list_sum(S[??:??])


#Idea: suma celeho zoznamu =  suma nejakeho zoznamu + suma nejakeho zoznamu
def list_sum_2_lists(S):
    if len(S) == 2:
        return ??
    half = len(S)//2
    return list_sum2(S[??:??]) + list_sum2(S[??:??])


print(sum1toN(5))
L = [1,2,4,6,7,11]
print(list_sum(L))
print(list_sum_2_lists(L))
'''

##############################   Rekurzia problemy  #####################################

# limit na hlbku vnorenia default = 999
print(factorial_recursion(10000))


#zvysit import sys
sys.setrecursionlimit(1000000000)

#chyba stop condiction
# "vyzere pamat"
def sum1toN(N):
    return N  + sum1toN(N-1)
#sum1toN(10)

# opakujuce sa volanie pre danu hodnotu - riesenie ulozit si vysledky napr. do slovniku!
def fibonaci(N):
    if N == 1 or N == 2:
        return 1
    return fibonaci(N-1) + fibonaci(N-2)

def fibonaci_save(N, dict):
    pass


########################################################################################
#################################### Rekurzia priklady - jednoduche#####################

#1 + 2 + 3 ... n
def sum1ton(n):
    pass

#return True/False ak retazec je palidrom
def palindrom(s):
    pass

#funkcia na otocenie retazca
def reverse(s):
    pass


#print(sum1ton(5))
#print(palindrom("abcba"))
#print(reverse("ahojky"))

########################################################################################
#################################### Rekurzia fraktaly  ########################

# urobte _/\_ ciaru kde dlzka kazdej ciary je n
def line(n):
    pass

#nahradte kazdu ciaru rovnakym utvarom 1/3 dlzky - nahradte ciary (vnorte sa) len raz
def Line(n):
    pass


########################################################################################
#################################### Rekurzia priklady - tazsie ########################

# kolkymi sposobmi mozno rozlozit number ako sucet cisel zo zoznamu L - prvky sa mozu opakovat
def decomposition(L, number):
    pass

# kolkymi sposobmi mozno rozlozit number ako sucet cisel zo zoznamu L - prvky sa mozu opakovat
def decomposition(L, number):
    pass

#https://en.wikipedia.org/wiki/Tower_of_Hanoi
def hanoi_towers():
    pass






















########################################################################################
#################################Hanojske veze##########################################

A = [3, 2, 1]
B = []
C = []

def move(n, source, target, auxiliary):
    if n > 0:
        # move n - 1 disks from source to auxiliary, so they are out of the way
        move(n - 1, source, auxiliary, target)

        # move the nth disk from source to target
        target.append(source.pop())

        # Display our progress
        print(A, B, C, '##############', sep = '\n')

        # move the n - 1 disks that we left on auxiliary onto target
        move(n - 1, auxiliary, target, source)

# initiate call from source A to target C with auxiliary B
move(3, A, C, B)