Created
November 12, 2021 15:42
-
-
Save omnituensaeternum/6d393ecb88039c67cb363a8d18c23542 to your computer and use it in GitHub Desktop.
Generates strings from chars incrementally
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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