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

Categories