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)
Related
I was trying to get this recursion faster but when I use numbers 50 and 44.4 it takes too long my desired outcome for those numbers is -800555.6302016332
z = int(input())
x = float(input())
def rec(n):
global x
l = {}
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
print(rec(z))
You are reinitializing your dictionary l = {} each time you recurse. Making l a global var should fix your problem:
l = {}
def rec(n):
global x
global l
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
You could also use functools.lru_cache which does memoization for you:
import functools
#functools.lru_cache
def rec(n):
global x
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
I would also suggest avoiding the use of global variables:
import functools
def rec(n, x):
#functools.lru_cache
def recurse(n):
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*recurse(n-1) + ((-1)**n)*((n+1)/(n-1)) * recurse(n-2) + ((n-1)/(2*x))*recurse(n-3))
return recurse(n)
def main():
n = int(input())
x = float(input())
print(rec(n, x))
if __name__ == "__main__":
main()
I've made a hexadecimal converter to practice recursion/recursive thinking. I, however, The recurssion doesn't appear to be happening as the functions seems to just output the result of 9 as of current.The code is as follows:
import math
curr=0
def convert(x):
L=len(x)
L-=1
sol=0
if L == 0:
return 0
else:
if x[curr]==["A","a"]:
v=10
elif x[curr]==["B","b"]:
v=11
elif x[curr]==["C","c"]:
v=12
elif x[curr]==["D","d"]:
v=13
elif x[curr]==["E","e"]:
v=14
elif x[curr]==["F","f"]:
v=15
else:
v=int(x[curr])
sol+=((v)*(16**(L-1)))
return sol + convert(x[curr+1])
def main():
print(convert('98A'))
main()
You were setting L = len(x) everytime you call the function. Here is one solution:
import math
def convert(x, L):
c = len(x) - 1
sol=0
if L > c:
return 0
else:
if (x[L]=="A" or x[L]=="a"):
v=10
elif (x[L]=="B" or x[L]=="b"):
v=11
elif (x[L]=="C" or x[L]=="c"):
v=12
elif (x[L]=="D" or x[L]=="d"):
v=13
elif (x[L]=="E" or x[L]=="e"):
v=14
elif (x[L]=="F" or x[L]=="f"):
v=15
else:
v=int(x[L])
sol+=((v)*(16**(c - L)))
print(sol)
return sol + convert(x, L + 1)
def main():
print(convert('98A', 0))
main()
You can use something like this:
class HexMap:
# mapping char to int
d = { hex(n)[2:]:n for n in range(16)}
def convert(x):
s = 0
# use reverse string and sum up - no need for recursion
for i,c in enumerate(x.lower()[::-1]):
s += HexMap.d[c]*16**i
return s
def main():
print(convert('98A'))
main()
Output:
2442
Recursive version:
# class HexMap: see above
def convert(x):
def convert(x,fak):
if not x:
return 0
else:
return HexMap.d[x[-1]]*16**fak + convert(x[:-1],fak+1)
return convert(x.lower(),0)
def main():
print(convert('98A'))
main()
Same output.
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]))
MyFunctions file file -
def factList(p,n1):
counter = 1
while counter <= n1:
if n1 % counter == 0:
p.append(counter)
counter = counter + 1
def isPrime(lst1,nbr):
factList(lst1, nbr)
if len(lst1) == 2:
return True
else:
return False
def nextPrime(nbr1):
cnt1 = 1
while cnt1 == 1:
nbr1 == nbr1 + 1
if isPrime(lst2,nbr1):
cnt1 = 0
Filetester file -
nbr1 = 13
nextPrime(nbr1)
print nbr1
My isPrime function already works I'm tring to use my isPrime function for my nextPrime function, when I run this I get
">>>
13
" (when using 13)
">>> " (When using 14)
I am supposed to get 17 not 13. And if I change it to a composite number in function tester it gets back in a infinite loop. Please only use simple functions (the ones I have used in my code).
This is NOT the right way to do this, but this is the closest adaptation of your code that I could do:
def list_factors_pythonic(number):
"""For a given number, return a list of factors."""
factors = []
for x in range(1, number + 1):
if number % x == 0:
factors.append(x)
return factors
def list_factors(number):
"""Alternate list_factors implementation."""
factors = []
counter = 1
while counter <= number:
if number % counter == 0:
factors.append(counter)
return factors
def is_prime(number):
"""Return true if the number is a prime, else false."""
return len(list_factors(number)) == 2
def next_prime(number):
"""Return the next prime."""
next_number = number + 1
while not is_prime(next_number):
next_number += 1
return next_number
This would be helpful:
def nextPrime(number):
for i in range(2,number):
if number%i == 0:
return False
sqr=i*i
if sqr>number:
break
return True
number = int(input("Enter the num: ")) + 1
while(True):
res=nextPrime(number)
if res:
print("The next number number is: ",number)
break
number += 1
I don't know python but if it's anything like C then you are not assigning anything to your variables, merely testing for equality.
while cnt1 == 1:
nbr1 == nbr1 + 1
if isPrime(lst2,nbr1):
cnt1 == cnt1 + 1
Should become
while cnt1 == 1:
nbr1 = nbr1 + 1 << changed here
if isPrime(lst2,nbr1):
cnt1 = cnt1 + 1 << and here
Well this code help you
n=int(input())
p=n+1
while(p>n):
c=0
for i in range(2,p):
if(p%i==0):
break
else:c+=1
if(c>=p-2):
print(p)
break
p+=1
this code optimized for finding sudden next prime number of a given number.it takes about 6.750761032104492 seconds
def k(x):
return pow(2,x-1,x)==1
n=int(input())+1
while(1):
if k(n)==True:
print(n)
break
n=n+1