Skip to content

Instantly share code, notes, and snippets.

@omnituensaeternum
Created November 12, 2021 15:42
Show Gist options
  • Save omnituensaeternum/6d393ecb88039c67cb363a8d18c23542 to your computer and use it in GitHub Desktop.
Save omnituensaeternum/6d393ecb88039c67cb363a8d18c23542 to your computer and use it in GitHub Desktop.
Generates strings from chars incrementally
import string, random
# Credit to dunnousername#8672
# return all unique strings from charset y of length l.
# y must be entirely unique chars.
def g(y, l):
if l == 1:
# we're just looking for single-char sequences
# just yield each char in the charset
yield from y
elif l > 1:
# for each char in the charset
for c in y:
# for each unique string of length (l-1)
for d in g(y, l - 1):
# yield the char concat a smaller unique string (recursive)
yield c + d
else:
pass # should never be called, throw some error here
# actually solve the problem
# x is the number of strings, y is the charset
# l is the starting length
# y must be entirely unique chars
def f(x, y, l=1):
# if we don't actually need any more strings
if x <= 0:
# don't return any, obviously
return []
# we need more strings!
else:
# number of possible strings of length l in charset y
z = len(y)**l
# if there aren't enough to achieve x unique strings
if x > z:
# use all unique strings of this length,
# then recursively call ourselves with larger lengths until we get enough
return f(z, y, l=l) + f(x - z, y, l=(l+1))
# elif we have two few strings
elif x < z:
# this just calls the next block (else) in a new call of the function
a = f(z, y, l=l)
# shuffle it
random.shuffle(a)
# choose x random strings from the set of unique strings
return a[:x]
# else, the number of unique strings of length l is exactly x
else:
# return all of them
return list(g(y, l))
chars = string.digits
chars = "lI"
print(f(10, chars, 1))
#['l', 'I', 'll', 'lI', 'Il', 'II', 'lII', 'lll', 'IlI', 'IIl']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment