Scrambling numbers - python
I am trying to program an algorithm that scrambles and "unscrambles" integer numbers.
I need two functions forward and backward
backward(number): return a "random" number between 0 and 9, the same input number always returns the same output
forward(number): return the input to backward that returns number
I managed to solve the problem like this:
from random import randint
class Scrambler:
def __init__(self):
self.mapping = [i for i in range(10)]
# scramble mapping
for i in range(1000):
r1 = randint(0, len(self.mapping) - 1)
r2 = randint(0, len(self.mapping) - 1)
temp = self.mapping[r1]
self.mapping[r1] = self.mapping[r2]
self.mapping[r2] = temp
def backward(self, num):
return self.mapping[num]
def forward(self, num):
return self.mapping.index(num)
if __name__ == '__main__':
s = Scrambler()
print(s.mapping)
for i in range(len(s.mapping)):
print(i, s.forward(i), s.backward(i), s.forward(s.backward(i)), s.backward(s.forward(i)))
Is there a way to do this without using the mapping list?
Can i calculate the return value of the functions forward and backward?
The "randomness" of the numbers does not need to be perfect.
I think your current solution is better than coming up with a function each time. It is a good solution.
Here is a generic solution for a generic key. You'd make your version using the Cipher.random_range method I've stuck on.
import random
class Cipher:
def __init__(self, key):
"""
key is a dict of unique values (i.e. bijection)
"""
if len(set(key.values())) != len(key):
raise ValueError('key values are not unique')
self._encoder = key.copy()
self._decoder = {v: k for k, v in key.items()}
#classmethod
def random_range(cls, max):
lst = list(range(max))
random.shuffle(lst)
return cls(dict(enumerate(lst)))
def encode(self, num):
return self._encoder[num]
def decode(self, num):
return self._decoder[num]
Related
i don't know it is dynamic programming
i am beginner who learning algorithm in korea college. it is assignment that solving the problem by using dynamic programming without recursive programming, using only python. the problem is whether the result is printed out 'a' by some operation or not when you input 5 alphabet of string that composed only 'a','b','c' I made it, but I'm not sure it's dynamic programming i really appreciate your favor if you give me a advice Issue. a b c a b b a b c b a c a c c There is an arithmetic table consisting of three elements, {a, b, and c} and the row, column, and corresponding intersecting values of the table give you a value such as {aa = b, ab = b, ac=a}. Based on these values, print out whether or not the result can be derived for any string (' possible' or 'impossible'), and, if possible, write the calculation sequence using a dynamic programming technique to indicate the sequence through the bracket. example input : bbbba. Result: possible, (b(bb)(bb)a)) In the example above the table are computed by referring to the first round brackets and Analysis, (bb) is (b). Then (b(b)) becomes (b) , and (b)a becomes c, indicating that the final requirement of bc=a is met. - The language must use the Python. - dynamic programming algorithms are techniques allowed for (dont' use a recursion x). - Output the first value obtained in many cases - Set the length of the string, which is the input value, to 5. def rule(x,y): if((x=='a' and y=='c') or (x=='b' and y=='c') or (x=='c' and y=='a')): return 'a' if((x=='a' and y=='a') or (x=='a' and y=='b') or (x=='b' and y=='b')): return 'b' if((x=='b' and y=='a') or (x=='c' and y=='b') or (x=='c' and y=='c')): return 'c' def rule2(x,y,z): return rule(rule(x,y),z) def rule3(x,y,z): return rule(x,rule(y,z)) def rule4(w,x,y,z): return rule(rule(w,x),rule(y,z)) def rule5(w,x,y,z): return rule(rule2(w,x,y),z) def rule6(w,x,y,z): return rule(rule3(w,x,y),z) def rule7(w,x,y,z): return rule(w,rule2(x,y,z)) def rule8(w,x,y,z): return rule(w,rule3(x,y,z)) def rule9(v,w,x,y,z): global k k='((('+v+w+')'+x+')'+y+z+')' return rule(rule2(v,w,x),rule(y,z)) def rule10(v,w,x,y,z): global k k='(('+v+'('+w+x+'))('+y+z+'))' return rule(rule3(v,w,x),rule(y,z)) def rule11(v,w,x,y,z): global k k='(('+v+w+')(('+x+y+')'+z+'))' return rule(rule(v,w),rule2(x,y,z)) def rule12(v,w,x,y,z): global k k='(('+v+w+')('+x+'('+y+z+')))' return rule(rule(v,w),rule3(x,y,z)) def rule13(v,w,x,y,z): global k k='((('+v+w+')('+x+y+'))'+z+')' return rule(rule4(v,w,x,y),z) def rule14(v,w,x,y,z): global k k='(((('+v+w+')'+x+')'+y+')'+z+')' return rule(rule5(v,w,x,y),z) def rule15(v,w,x,y,z): global k k='((('+v+'('+w+x+')'+y+')'+z+'))' return rule(rule6(v,w,x,y),z) def rule16(v,w,x,y,z): global k k='('+v+'('+w+'(('+x+y+')'+z+')))' return rule(rule7(v,w,x,y),z) def rule17(v,w,x,y,z): global k k='('+v+'('+w+'('+x+'('+y+z+'))))' return rule(rule8(v,w,x,y),z) def rule18(v,w,x,y,z): global k k='('+v+'(('+w+x+')('+y+z+')))' return rule(v,rule4(w,x,y,z)) def rule19(v,w,x,y,z): global k k='(('+v+'(('+w+x+')'+y+')'+z+'))' return rule(v,rule5(w,x,y,z)) def rule20(v,w,x,y,z): global k k='('+v+'(('+w+'('+x+y+'))'+z+'))' return rule(v,rule6(w,x,y,z)) def rule21(v,w,x,y,z): k='('+v+'('+w+'(('+x+y+')'+'))'+z+')' return rule(v,rule7(w,x,y,z)) def rule22(v,w,x,y,z): global k k='('+v+'('+w+'('+x+'('+y+z+'))))' return rule(v,rule8(w,x,y,z)) def rule23(v,w,x,y,z): global k k='((('+v+w+')'+x+')'+'('+y+z+'))' return rule2(rule(v,w),x,rule(y,z)) def rule24(v,w,x,y,z): global k k='(('+v+w+')('+x+'('+y+z+')))' return rule3(rule(v,w),x,rule(y,z)) print(" input:",end='') str=input() str=list(str) x=[rule9,rule10,rule11,rule12,rule13,rule14,rule15,rule16,rule17,rule18,rule19, rule20,rule21,rule22,rule23,rule24] for i in range(0,16): y=x[i](str[0],str[1],str[2],str[3],str[4]) if(y=='a'): print("possible,",end=' ') print(k) break if(y!='a' and i==15): print("impossible")
Of course there can be better way to solve the problem you approached and probably you will learn that once you will see other people assignment solutions, but about recursive/dynamic question you had, your code execution in memory is not recursive. It is definitely a linear dynamic programming what you have created up there. Just to be sure, you could also test it via this implementation of a recursive test: https://stackoverflow.com/a/36663046/3564632 So overall you might try with this example just to test it out: from bdb import Bdb import sys class RecursionDetected(Exception): pass class RecursionDetector(Bdb): def do_clear(self, arg): pass def __init__(self, *args): Bdb.__init__(self, *args) self.stack = set() def user_call(self, frame, argument_list): code = frame.f_code if code in self.stack: raise RecursionDetected self.stack.add(code) def user_return(self, frame, return_value): self.stack.remove(frame.f_code) def test_recursion(func): detector = RecursionDetector() detector.set_trace() try: func() except RecursionDetected: return True else: return False finally: sys.settrace(None) def rule(x,y): if((x=='a' and y=='c') or (x=='b' and y=='c') or (x=='c' and y=='a')): return 'a' if((x=='a' and y=='a') or (x=='a' and y=='b') or (x=='b' and y=='b')): return 'b' if((x=='b' and y=='a') or (x=='c' and y=='b') or (x=='c' and y=='c')): return 'c' def rule2(x,y,z): return rule(rule(x,y),z) def rule3(x,y,z): return rule(x,rule(y,z)) def rule4(w,x,y,z): return rule(rule(w,x),rule(y,z)) def rule5(w,x,y,z): return rule(rule2(w,x,y),z) def rule6(w,x,y,z): return rule(rule3(w,x,y),z) def rule7(w,x,y,z): return rule(w,rule2(x,y,z)) def rule8(w,x,y,z): return rule(w,rule3(x,y,z)) def rule9(v,w,x,y,z): global k k='((('+v+w+')'+x+')'+y+z+')' return rule(rule2(v,w,x),rule(y,z)) def rule10(v,w,x,y,z): global k k='(('+v+'('+w+x+'))('+y+z+'))' return rule(rule3(v,w,x),rule(y,z)) def rule11(v,w,x,y,z): global k k='(('+v+w+')(('+x+y+')'+z+'))' return rule(rule(v,w),rule2(x,y,z)) def rule12(v,w,x,y,z): global k k='(('+v+w+')('+x+'('+y+z+')))' return rule(rule(v,w),rule3(x,y,z)) def rule13(v,w,x,y,z): global k k='((('+v+w+')('+x+y+'))'+z+')' return rule(rule4(v,w,x,y),z) def rule14(v,w,x,y,z): global k k='(((('+v+w+')'+x+')'+y+')'+z+')' return rule(rule5(v,w,x,y),z) def rule15(v,w,x,y,z): global k k='((('+v+'('+w+x+')'+y+')'+z+'))' return rule(rule6(v,w,x,y),z) def rule16(v,w,x,y,z): global k k='('+v+'('+w+'(('+x+y+')'+z+')))' return rule(rule7(v,w,x,y),z) def rule17(v,w,x,y,z): global k k='('+v+'('+w+'('+x+'('+y+z+'))))' return rule(rule8(v,w,x,y),z) def rule18(v,w,x,y,z): global k k='('+v+'(('+w+x+')('+y+z+')))' return rule(v,rule4(w,x,y,z)) def rule19(v,w,x,y,z): global k k='(('+v+'(('+w+x+')'+y+')'+z+'))' return rule(v,rule5(w,x,y,z)) def rule20(v,w,x,y,z): global k k='('+v+'(('+w+'('+x+y+'))'+z+'))' return rule(v,rule6(w,x,y,z)) def rule21(v,w,x,y,z): k='('+v+'('+w+'(('+x+y+')'+'))'+z+')' return rule(v,rule7(w,x,y,z)) def rule22(v,w,x,y,z): global k k='('+v+'('+w+'('+x+'('+y+z+'))))' return rule(v,rule8(w,x,y,z)) def rule23(v,w,x,y,z): global k k='((('+v+w+')'+x+')'+'('+y+z+'))' return rule2(rule(v,w),x,rule(y,z)) def rule24(v,w,x,y,z): global k k='(('+v+w+')('+x+'('+y+z+')))' return rule3(rule(v,w),x,rule(y,z)) print(" input:",end='') str=input() str=list(str) x=[rule9,rule10,rule11,rule12,rule13,rule14,rule15,rule16,rule17,rule18,rule19, rule20,rule21,rule22,rule23,rule24] for i in range(0,16): assert not test_recursion(lambda: x[i](str[0],str[1],str[2],str[3],str[4])) y = x[i](str[0],str[1],str[2],str[3],str[4]) if(y=='a'): print("possible,",end=' ') print(k) break if(y!='a' and i==15): print("impossible")
How to "Auto Generate" String in Sequence from "0-9 A-Z"
I am trying to auto generate string from 0-9 and A-z. 00001-99999 A0001-A9999 B0001-B9999 Z9999-AA999 AB001-ZZ999 AAA01-..... And in sequence
just make a recursive call to a function. list=[] for i in range(10): list.append(str(i)) for i in range(26): list.append(chr(ord('a')+i)) def all(pre,n): li=[] if n==1: for x in list: for p in pre: li.append(x+p) return li else: for x in list: for p in pre: li.append(x+p) return all(li,n-1) print(all([''],2)) Recursor may take a lot of time for large numbers, so you can also make your own number system to increment. class NumSys: def __init__(self): self.val=[0,0,0,0,0] def next(self): self.val[4]+=1 for i in range(5): if self.val[4-i]>35: if i==4: return None else: self.val[4-i-1]+=1 self.val[4-i]-=35 def __str__(self): stri='' for i in range(5): x=self.val[i] if x<10: stri+=str(x) else: stri+=chr(ord('a')+x-10) return stri n=NumSys() for i in range(100): print (str(n)) n.next()
How to replace an integer with a different class when it is assigned
I have a class called newInteger, and a variable called num, but I would like num to be a newInteger() instead of an int(). Code below. class newInteger(int): def __init__(self, value): self.value = value num = 10 I want the line num = 10 to act as if it is num = newInteger(10). Thanks to anyone who can help me with this.
You can run a small thread parallel to your main program that replaces all created integers to newInteger: import threading import time class newInteger(int): def __init__(self, value): self.value = value def __str__(self): return "newInteger " + str(self.value) def replace_int(): while True: g = list(globals().items()) for n, v in g: if type(v) == int: globals()[n] = newInteger(v) threading.Thread(target=replace_int, daemon=True).start() num = 10 time.sleep(1) print(num) But this is unpythonic and will be realy hard to debug. You should just use a explicit conversion like #johnashu proposed
I am not sure if this is what you mean but if youassign the class to a variabl. then it will be an instance of that class.. example: class newInteger(int): def __init__(self, value): self.value = value num = 10 if num == 10: num = newInteger(10) prints: hello
Python genetic algorithm is slow
I made a genetic algorithm that writes the target phrase, but i'm feeling that it takes too long on each iteration, so I'd like to know if you have any idea on how to speed it up. Thanks from random import randint, random from time import time def rescale(X,A,B,C,D,force_float=False): retval = ((float(X - A) / (B - A)) * (D - C)) + C if not force_float and all(map(lambda x: type(x) == int, [X,A,B,C,D])): return int(round(retval)) return retval Here i create a list of random characters that form the phrase class DNA: def __init__(self,num): self.genes=[] for i in range(num): self.genes.append((chr(randint(32,126)))) Transform the genes in a string def getPhrase(self): return(''.join(self.genes)) Calculating the fitness(similarity to the target) def fitness(self,target): score=0 for i in range(len(self.genes)): if (self.genes[i] == target[i]): score+=1 return score*score/(len(target)*len(target)) Mixing two genes (getting some character from one and some from another) def crossover(self,partner): child = DNA(len(self.genes)) midpoint = randint(0,len(self.genes)) for i in range(len(self.genes)): if (i > midpoint): child.genes[i] = self.genes[i] else: child.genes[i] = partner.genes[i] return child Mutating a gene(adding some random characters) def mutate(self,mutationRate): for i in range(len(self.genes)): if (random() < mutationRate): self.genes[i] = chr(randint(32,126)) A list of DNA objects class Population: def __init__(self,target,mutationRate,num): self.population=[] for i in range(num): self.population.append(DNA(len(target))) self.mutationRate=mutationRate self.calcFitness(target) self.generations=0 Making a list with the fitness of each gene def calcFitness(self,target): self.fitness=[] for i in range(len(self.population)): self.fitness.append(self.population[i].fitness(target)) Making a list to the crossover function, with entries proportional to the fitness def naturalSelection(self): global index, x self.matingPool=[] self.maxFitness = 0 for i in range(len(self.population)): if (self.fitness[i] > self.maxFitness): self.maxFitness = self.fitness[i] index=i print(DNA.getPhrase(population.population[index]),' generation: ',self.generations) if (DNA.getPhrase(population.population[index]))==target: x=False for i in range(len(self.population)): fitness = rescale(self.fitness[i],0,float(self.maxFitness),0,1) n = (fitness * 100) for j in range(int(n)): self.matingPool.append(population.population[i]) Updating the population def generate(self): for i in range(len(self.population)): a = randint(0,len(self.matingPool)-1) b = randint(0,len(self.matingPool)-1) partnerA = self.matingPool[a] partnerB = self.matingPool[b] child = partnerA.crossover(partnerB) child.mutate(self.mutationRate) population.population[i] = child self.generations+=1 start=time() target= input("Target: ") population = Population(target, 0.05,300) x=True while x==True: population.naturalSelection() population.generate() population.calcFitness(target) end=time() print(end-start)
Python - Accesing a list from another class method
I have a little problem with two different classes and two methods from the same class. I have a class B which is using both methods from class a which seems to work fine. The problem however is that the first method from class a (insert) changes a list which the second method (lookup) from this class should use. It is using the global list which is still initiated with only zeroes. So I have no idea how to tell the method to use the HashMap from the insert method :/ I Hope somebody can help, thank you! """ PUBLIC MEMBERS Insert the given key (given as a string) with the given value (given as an integer). If the hash table already contains an entry for the given key, update the value of this entry with the given value. """ class Map: global m m = 10000 global HashMap HashMap = [] for i in range(m): HashMap.append(0) #classmethod def insert(self, key, value): """ >>> Map.insert("hi", 9) [4,53] """ self.key = key self.value = value asci = 0 for i in key: asci += ord(i) hashindex = (asci%m)*2 print(hashindex) print(HashMap[hashindex]) if HashMap[hashindex] == key: HashMap[hashindex + 1] = value else: while HashMap[hashindex] != 0: hashindex = ((asci+1)%m)*2 HashMap[hashindex] = key HashMap[hashindex+1] = value """ Check if there exists an entry with the given key in the hash table. If such an entry exists, return its associated integer value. Otherwise return -1. """ #classmethod def lookup(self, key): self.key = key ascilookup = 0 for i in key: ascilookup += ord(i) indexlookup = (ascilookup%m)*2 for j in HashMap: if HashMap[j]==key: return HashMap[j + 1] elif HashMap[j]==0: return "-1" else: j =((j+1)%m)*2 if __name__ == "__main__": import doctest doctest.testmod()
This is a far simpler implementation of a map in python: class Map: HashMap = {} def __init__(self,leng): for i in range(leng): self.HashMap[str(i)]=0 def insert(self, key, value): self.HashMap[key]=value def lookup(self, key): for each in self.HashMap.iterkeys(): if each == key: return self.HashMap[each] return None EDIT without using a dictionary, using two lists is easier: class Map: keys = [] values = [] def __init__(self,leng): for i in range(leng): self.keys.append(str(i)) self.values.append(0) #classmethod def insert(self, key, value): self.keys.append(key) self.values.append(value) #classmethod def lookup(self, key): for x in range(0, len(self.keys)): if self.keys[x] == key: return self.values[x] return None