1
+ #6 { Retos para Programadores } Recursividad
2
+ """
3
+ * EJERCICIO:
4
+ * Entiende el concepto de recursividad creando una función recursiva que imprima
5
+ * números del 100 al 0.
6
+ *
7
+ * DIFICULTAD EXTRA (opcional):
8
+ * Utiliza el concepto de recursividad para:
9
+ * - Calcular el factorial de un número concreto (la función recibe ese número).
10
+ * - Calcular el valor de un elemento concreto (según su posición) en la
11
+ * sucesión de Fibonacci (la función recibe la posición).
12
+ """
13
+
14
+ log = print # Shortening print function to log
15
+
16
+ # A recursive function typically is formed when a function calls itself by name
17
+ def count_back (n ):
18
+ log (n )
19
+ if n == 0 :
20
+ return # None
21
+ return count_back (n - 1 )
22
+
23
+ log (count_back (100 ))
24
+
25
+ # Without recursion
26
+ def power_v1 (base , exponent ):
27
+ result = 1 if exponent == 0 else base
28
+ for i in range (2 , exponent + 1 ):
29
+ result *= base
30
+ return result
31
+
32
+ log (power_v1 (4 , 3 )) # 64
33
+
34
+ # With recursion
35
+ def power (base , exponent ):
36
+ if exponent == 0 :
37
+ return 1
38
+ else :
39
+ return base * power (base , exponent - 1 )
40
+
41
+ log (power (4 , 3 )) # 64
42
+
43
+ # This is rather close to the way mathematicians define exponentiation and
44
+ # arguably describes the concept more clearly than the looping variant.
45
+ # The function calls itself multiple times with ever smaller exponents to achieve the
46
+ # repeated multiplication.
47
+
48
+ # But this implementation has one problem: in typical Python implementations,
49
+ # it’s about three times slower than the looping version. Running through
50
+ # a simple loop is generally cheaper than calling a function multiple times.
51
+
52
+ # In the case of the power function, the inelegant (looping) version is still fairly
53
+ # simple and easy to read. It doesn’t make much sense to replace it with the
54
+ # recursive version.
55
+
56
+ # Extra difficulty exercises
57
+
58
+ def factorial (n ):
59
+ if n <= 1 :
60
+ return 1
61
+ return n * factorial (n - 1 )
62
+
63
+ log (factorial (5 )) # 120
64
+
65
+
66
+ # This function returns the number equivalent to the position in the Fibonacci series
67
+ def fibonacci_num (n ):
68
+ if n == 0 :
69
+ return 0
70
+ if n == 1 :
71
+ return 1
72
+ return fibonacci_num (n - 1 ) + fibonacci_num (n - 2 )
73
+
74
+ log (fibonacci_num (17 )) # 1597
75
+
76
+ # Note: The recursive version with memoization is more efficient than the simple recursive one,
77
+ # as it avoids redundant calculations. However, it still uses the call stack, which can be a problem for very large values of n.
78
+
79
+ def fibonacci_num_memo (n , memo = {}):
80
+ if n in memo :
81
+ return memo [n ]
82
+ if n == 0 :
83
+ return 0
84
+ if n == 1 :
85
+ return 1
86
+ memo [n ] = fibonacci_num_memo (n - 1 , memo ) + fibonacci_num_memo (n - 2 , memo )
87
+ return memo [n ]
88
+
89
+ log (fibonacci_num_memo (17 )) # 1597
90
+
91
+ # The iterative approach is generally more efficient in terms of time and space, as it does not use the call stack of recursion.
92
+ """ The iterative approach not handle very large Fibonacci numbers properly due to the limitations of standard integer representation in some programming languages. However, Python's integers can grow as large as the memory allows, so it should work fine for large Fibonacci numbers like fibonacci(4222). """
93
+
94
+ def iterative_fibonacci (n ):
95
+ if n == 0 :
96
+ return 0
97
+ if n == 1 :
98
+ return 1
99
+
100
+ a , b = 0 , 1
101
+ resultado = 0
102
+
103
+ for i in range (2 , n + 1 ):
104
+ resultado = a + b
105
+ a = b
106
+ b = resultado
107
+ return resultado
108
+
109
+ log (iterative_fibonacci (4222 )) # This will likely result in a very large number
110
+ ''' 991589988362642070289381809859238899810818978690066481567009961084370343355020445771885410736432350985748230736466733366235493773173353807008180411573721923522628193615012792654580349124839525370327127087212639668504243599805635642440051280951077467227974758307254927414086395913327066620720820654856388551207498973370655978255046381155991312335751278534594089041280672977552114511923101524007980516923288134966032329067540128365146684772558653549788584628220581142887000982711896691538088856557710641299562290047382724565369870585638339456142817193642656279468367921367028940944988116809057276755968908731893570902338692496954534233789481260096044188777018433397442568357873891235554198879570974119614520991455054319986189584806128290103014082993662230000784648446189143070226650569527550697283718937846526095749543627404591780914731497810266886509088704777805009571566121451309311 '''
111
+ log (iterative_fibonacci (453 )) # 20985341020594289480596202471862246559405946478745659997715004840583924030397583511583383173698
112
+
113
+ # Simulating a window load event (not applicable in standard Python, but for demonstration)
114
+ def on_load ():
115
+ body_style = {
116
+ 'background' : '#000' ,
117
+ 'text-align' : 'center'
118
+ }
119
+
120
+ title = {
121
+ 'text' : 'Retosparaprogramadores #6.' ,
122
+ 'font-size' : '3.5vmax' ,
123
+ 'color' : '#fff' ,
124
+ 'line-height' : '100vh'
125
+ }
126
+
127
+ # Simulating a delay (not applicable in standard Python, but for demonstration)
128
+ import time
129
+ time .sleep (2 )
130
+
131
+ log ("Title:" , title ['text' ])
132
+
133
+ # Call the simulated load function
134
+ on_load ()
0 commit comments