Given a target string 'S', the task is to generate random strings of the same length as 'S' until the generated string exactly matches the target. For Example:
Input: hello
Output:
jfus
flsf
sowe
hello
Target matched after 3 iterations
Let's look at the different methods below:
Genetic Algorithm
This approach starts with a random string and slowly evolves it toward the target string. It changes one character at a time and only keeps changes that make the string closer to the target.
import string
import random
chars = string.ascii_letters + string.digits + ' .,!?;:'
target = "geeks"
s = ''.join(random.choice(chars) for _ in range(len(target)))
iterations = 0
while s != target:
print(s)
i = random.randint(0, len(s)-1)
l = list(s)
l[i] = random.choice(chars)
s1 = ''.join(l)
if sum(a == b for a, b in zip(s1, target)) >= sum(a == b for a, b in zip(s, target)):
s = s1
iterations += 1
print(s)
print(f"Target matched after {iterations} iterations")
Output
geDjs
geDjs
geDjs
geD2s
geD2s
geD2s
......
geek
Target matched after 1307 iterations
Explanation:
- s = ''.join(random.choice(chars) for _ in range(len(target))): Generate initial random string.
- i = random.randint(0, len(s)-1): Pick a random index to mutate.
- l[i] = random.choice(chars): Replace that character randomly.
Hill Climbing Approach
This approach starts with a random string and gradually improves it by fixing the correct characters and only changing the incorrect ones. Any change that reduces correctness is discarded, so the string slowly climbs toward the target.
import string
import random
chars = string.ascii_letters + string.digits + ' .,!?;:'
target = "geek"
a = ''.join(random.choice(chars) for _ in range(len(target)))
iterations = 0
while a != target:
print(a)
b = list(a)
for i in range(len(target)):
if b[i] != target[i]:
b[i] = random.choice(chars)
if sum(x == y for x, y in zip(''.join(b), target)) < sum(x == y for x, y in zip(a, target)):
b[i] = a[i]
a = ''.join(b)
iterations += 1
print(a)
print(f"Target matched after {iterations} iterations")
Output
sx18
1EEp
mzhm
8JQN
SeLb
......
geek
Target matched after 113 iterations
Explanation:
- if b[i] != target[i]: b[i] = random.choice(chars): Randomly change characters that don’t match.
- if sum(x==y for x,y in zip(''.join(b), target)) < sum(x==y for x,y in zip(a, target)): b[i] = a[i]: Undo the change if it makes the string less similar to the target
- a = ''.join(b): Update string with valid mutations.
Iterative Character Replacement
In this approach, we start with a random string and repeatedly replace only the incorrect characters with random choices, keeping correct characters unchanged, until the string matches the target.
import string
import random
import time
chars = string.ascii_letters + string.digits + ' .,!?;:'
t = "geek"
s = ''.join(random.choice(chars) for _ in range(len(t)))
done = False
it = 0
while not done:
print(s)
s1 = ''
done = True
for i in range(len(t)):
if s[i] != t[i]:
done = False
s1 += random.choice(chars)
else:
s1 += t[i]
s = s1
it += 1
print(f"Target matched after {it} iterations")
Output
vkZ2
tac4
I56g
zqPR
9XuS
.....
geek
Target matched after 114 iterations
Explanation:
- done = False: Flag to track if the target is reached.
- if s[i] != t[i]: s1 += random.choice(chars); done = False: Replace wrong characters randomly and mark as not done.
Pure Random
In this approach, a completely random string is generated in each iteration until it exactly matches the target string.
import random, string
target = "geek"
chars = string.ascii_letters + string.digits + ' .,!?;:'
s = ''.join(random.choice(chars) for _ in range(len(target)))
iterations = 0
while s != target:
print(s)
s = ''.join(random.choice(chars) for _ in range(len(target)))
iterations += 1
print(s)
print(f"Target matched after {iterations} iterations")
Output
g5ek
gUek
gWek
gXek
gOek
gWek
......
geek
Target matched after 1104 iterations
Explanation:
- s != t: Continue looping until the string matches the target
- s = ''.join(random.choice(chars) for _ in range(len(t))): Generate a completely random string each iteration.