I need to repeat a function "x" amount of times by recursion. I can do that, but the output needs to carry over for each one.
num is the amount of times to be called
def incr(n):
print(n+1)
return n+1
def foo(fn, num):
def op(n):
fn(n)
print(num)
if(num > 0):
foo(fn, num-1)
return op
f = foo(incr, 3)
f(5)
Right now I get 6. The intended result is 6,7,8
Here is one way to do it:
def incr(n):
print(n+1)
return n+1
def foo(fn, num):
def op(n):
if num > 0:
n = fn(n)
foo(fn, num-1)(n)
return op
f = foo(incr, 3)
f(5)
A recursive function should call itself, see https://www.geeksforgeeks.org/recursive-functions/ for more.
I also added a parameter that keeps track of the end result.
def incr(n, num):
if (n != num):
print(n + 1)
return incr(n + 1, num)
def foo(fn, num):
def op(n):
fn(n, n + num)
return op
f = foo(incr, 3)
f(5)
Related
I get the values but it also prints 'None' for non prime values
class Prime:
def __init__(self, n1, n2):
self.n1 = n1
self.n2 = n2
def __iter__(self):
return self
def __next__(self):
num = self.n1
self.n1 += 1
for x in range(2, num):
if num % x == 0:
break
else:
return num
z = Prime(30, 200)
for k in z:
print(k)
results:
None
31
None
None
None
None
None
37
None
None
None
41
None
43
If a break is encounted in a for/else loop in Python, the else block is never executed. Hence, None is returned by default. That is almost certainly the root cause of your error.
Your function should probably look like this:
def __next__(self):
num = self.n1
self.n1 += 1
for x in range(2, num):
if num % x == 0:
break
return num
(Although now that I look at it, that for loop should probably be a while loop, I am not sure your logic is correct here)
for/else reference
I'm trying to write a function that would recursively hash a key for n times, alternating between sha224 and sha256. Each iteration would be hash_256(hash_224)--a hash256 for the hash224 of the key--so that it would yield n * (hash_256(hash_224)). However, I'm new to coding and can't figure out how to write a recursive function with these parameters.
import hashlib
def shasum(key, n):
key = str(key).encode('utf-8')
hash_a = hashlib.sha224(key).hexdigest().encode('utf-8'))
hash_b = hashlib.sha256(hash_a).hexdigest()
if n == 0 or 1:
return hash_b #one iteration of 256(224)
else:
return n-1
return hash_b #stuck here
Edited: now it behaves like a number generator. What's wrong?
import hashlib
n = 0
def sha480(seed):
hashed_224 = str(hashlib.sha224(seed)).encode('utf-8')
hashed_256 = hashlib.sha256(hashed_224).hexdigest()
hashed_480 = str(hashed_256)
print("hash: " + hashed_480)
def repeater(key, n):
if n == 0:
return key
seed = str(key).encode('utf-8')
while n > 0:
return sha480(repeater(seed, n-1))
repeater('what', 2)
You have no recursive calls at all. You could change it to:
def hash_a(key):
return hashlib.sha224(key).hexdigest().encode('utf-8')
def hash_b(key):
return hashlib.sha256(key).hexdigest()
def shasum(key, n):
if n == 0: # base case: 0 iterations -> return key itself
return key
key = str(key).encode('utf-8')
return hash_b(hash_a(shasum(key, n - 1))) # recursve call
A side note: n == 0 or 1 is equivalent to (n == 0) or 1 which is always true. For that pattern, use n == 0 or n == 1 or shorter n in (0, 1)
Your code is nearly correct. just some minor issues fixed as below
import hashlib
def shasum(key, n):
print ("n: " + str(n))
key = str(key).encode('utf-8')
hash_a = hashlib.sha224(key).hexdigest().encode('utf-8')
print ("hash_a: " + str(hash_a))
hash_b = hashlib.sha256(hash_a).hexdigest()
print ("hash_b: " + str(hash_b))
if n == 0:
return hash_b #one iteration of 256(224)
else:
return shasum(hash_b, n-1)
I keep getting a type error for this. I am experimenting with decorative functions. Any help is appreciated
def primer(func):
def primes(n):
print (n)
return None
#primer
def find_prime(n):
while True:
count = 2
if (count == n):
z = ("PRIME")
return z
elif (n % count == 0):
z = n / count
return z
else:
count += 1
continue
prime = find_prime()
prime(10)
def primer(func):
def primes(n):
print(n)
#return None: dont know why this is here, you could do without it
return primes
#The nontype error is occuring because your code is returning none
#so to fix that all you have to do is return the inner function
#primer
def find_prime(n):
while True:
count = 2
if (count == n):
z = ("PRIME")
return z
elif (n % count == 0):
z = n / count
return z
else:
count += 1
continue
prime = find_prime
# if you want to turn a function into a variable you have to make sure it's
# callable, which means no parantheses around it
prime(15) # then you can call it
I am trying to find a efficient solution for the 3n + 1 problem on uvaonlinejudge. The code I have uses memoization using a dictionary. Can anyone suggest an improvement(s) that will help with the execution time of this code? At the moment I am getting a 'Time limit Exceeded' error when I submit the code. If anyone has a working solution to the problem please share it with me. PLEASE DON'T mark this post as DUPLICATE. I have already seen this post and others on stackoverflow but they don't answer the question posted here. My code is as below:
import sys
def recCycleLength(n,cycLenDict):
if n==1:
return 1
if n not in cycLenDict:
if n%2==0:
cycLen = recCycleLength(n//2, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
cycLen = recCycleLength(3*n+1, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
return cycLenDict[n]
def maxCycle(a, b):
i = a
mydict = {}
maxLength = 1
while i <= b:
m = recCycleLength(i, mydict)
if m > maxLength:
maxLength = m
i = i + 1
return maxLength
for line in sys.stdin:
curr_line=line.split()
num1 = int(curr_line[0])
num2 = int(curr_line[1])
if num1>num2:
num1, num2 = num2, num1
m = maxCycle(num1, num2)
print("{} {} {}".format(num1, num2, m))
I found the problem in your code. Actually, you are not saving cycLenDict generated on the previous interval for next one. And this is why your code is so "slow" because it will generate all possible endings over and over again. Just move it in global scope or make something like this:
import sys
def rec(n, cache):
if n in cache:
return cache[n]
if n % 2 == 0:
cycle = rec(n//2, cache)
else:
cycle = rec(3*n+1, cache)
cache[n] = cycle + 1
return cache[n]
def cycle(a, b, cache):
return max(rec(i, cache) for i in range(a, b+1))
if __name__ == '__main__':
cache = {1: 1}
for line in sys.stdin:
a, b = map(int, line.split())
a, b = min(a, b), max(a, b)
m = cycle(a, b, cache)
print("{} {} {}".format(a, b, m))
The code seems to do the right thing to execute maxCycle optimally by caching all calculated results in mydict.
However, the input to the application consists of many pairs of values to be processed and maxCycle will reset mydict = {} and calculate everything from scratch.
I suggest remembering the results globally instead. A simple modification of the original code would be:
cycLenDict = {} # global dictionary
def recCycleLength(n): # no cycLenDict argument
if n==1:
return 1
if n not in cycLenDict:
# ...
def maxCycle(a, b):
# ...
while i <= b:
m = recCycleLength(i) # no myDict argument
To make everything a little bit nicer looking (without any difference performance-wise, compared to the solution above), make a decorator which remembers the results, so that the remainder of the code does not have to take care of that:
def memoize(func):
"""decorate any function which takes positional arguments to cache its results"""
func.results = {} # results are stored globally as the funtion's attribute
def memoized(*a): # memoized version of func
if a not in func.results: # if not cached
func.results[a] = func(*a) # save to cache
return func.results[a] # return from cache
return memoized
#memoize # with this, recCycleLength is called only once for every n value
def recCycleLength(n):
if n==1:
return 1
elif n%2==0:
return recCycleLength(n//2) + 1
else:
return recCycleLength(3*n+1) + 1
def maxCycle(a, b):
return max(recCycleLength(i) for i in range(a, b+1))
import sys
def cycle(current, count=1):
if current == 1:
return count
if current % 2 == 0:
return cycle(current / 2, count + 1)
return cycle(current * 3 + 1, count + 1)
def max_cycles(lower, upper):
max = 0
for current in range(lower, upper):
result = cycle(current, 1)
if result > max:
max = result
return max
def main(i, j):
if i > j:
(i, j) = (j, i)
print (i, j, max_cycles(i, j))
if __name__ == "__main__":
if len(sys.argv) < 3:
print 'usage: python filename argv1 argv2'
print 'exiting'
exit(0)
main(int(sys.argv[1]), int(sys.argv[2]))
def test_countdown(self):
from_3 = '3\n2\n1\nBlastoff!'
self.assertEqual(countdown(3), from_3)
from_0 = 'Blastoff!'
self.assertEqual(countdown(0), from_0)
#THIS IS THE TEST
def countdown(n):
while n>0:
print(n)
n=n-1
print("Blastoff!")
#This is my code for the function
It is not passing the test because on the back end it is coming out as 'none' > for countdown(3) instead of '3\n2\n1\nBlastoff!'
You're printing, not concatenating:
def countdown(n):
return '\n'.join(map(str, range(n, 0, -1))) + '\nBlastoff!'
Or as Lalaland suggested below:
def countdown(n):
result = ''
while n > 0:
result += str(n) + '\n'
n = n - 1 # decrement
result = result + '\nBlastoff!'
return result # not printing