Skip to content

Instantly share code, notes, and snippets.

@orbyfied
Last active March 3, 2022 13:27
Show Gist options
  • Save orbyfied/5adb2b292a424d81e498874a1bca5190 to your computer and use it in GitHub Desktop.
Save orbyfied/5adb2b292a424d81e498874a1bca5190 to your computer and use it in GitHub Desktop.
Generates all possible variations of a word or sentence without duplicate elements.
#
# By orbyfied, (C) 2022 L
#
from abc import abstractmethod
import time
import math
# utility class for building strings
class StringBuffer:
@abstractmethod
def __init__(self):
pass
@abstractmethod
def __init__(self, str):
pass
def __str__(self):
return self.get()
@abstractmethod
def get(self):
pass
@abstractmethod
def append(self, toAppend):
pass
@abstractmethod
def delete(self, start, end):
pass
@abstractmethod
def trim(self, start, end):
pass
@abstractmethod
def clone(self):
pass
@abstractmethod
def close(self):
pass
# implementation of string buffer using
# string concatenation, inefficient, will be
# improved and deprecated soon. exports strings
class ConcatStringBuffer(StringBuffer):
def __init__(self):
self.str = ""
def __init__(self, str):
self.str = str
def get(self):
return self.str
def append(self, toAppend):
self.str += str(toAppend)
return self
def delete(self, start, end):
self.str = self.str[0:start] + self.str[end:]
return self
def trim(self, start, end):
self.str = self.str[start:end]
return self
def clone(self):
return ConcatStringBuffer(self.str)
def close(self):
pass
def chars_to_string(chars):
str = ''
for c in chars:
str += c
return str
# uses an internal character array to store
# the string. exports the character arrays as
# possibilities instead of strings.
class BufferedStringBuffer(StringBuffer):
def __init__(self):
self.chars = []
def __init__(self, str):
if str is list:
self.chars = str
else:
self.chars = list(str)
def get(self):
return self.chars
def append(self, toAppend):
for c in toAppend:
self.chars.append(c)
return self
def clone(self):
return BufferedStringBuffer(self.chars)
# TODO: make more efficient string builder
# get word
word = input("input: ")
# output information
output = ""
count = 0
# utility functions
# copies an array, uses references to the original objects
def copy_array(arr):
new_arr = []
for e in arr:
new_arr.append(e)
return new_arr
# gets the given string as a char array
def get_string_as_chars(str):
chars = []
for c in str:
chars.append(c)
# return chars
return list(str)
# gets the words in a given sentence with a space behind them
def get_words_in_sentence(str):
words = []
for word in str.split(' '):
words.append(word + " ")
return words
# magic function(s)
def get_shuffeled_variations(input):
# parse input
if len(input) == 0: # check if we have input
return [], 0
chars = None
if ' ' in input and not input[0] == '"': # sentence
chars = get_words_in_sentence(input)
else:
# if input follows { "..." } then { ... } will be extracted,
# instead of parsing it as a sentence for if you want to get_shuffele
# an input with spaces per character
if input[0] == '"' and input[len(input)-1] == '"':
input = input[1:len(input)-1]
chars = get_string_as_chars(input)
# initialize values
buffer = ConcatStringBuffer("")
depth = len(chars) - 1
used = ''
possibilities = []
# start recursion chair which will eventually
# generate all possibilities and return the result(s)
next_char(buffer, depth, chars, used, possibilities)
return possibilities, len(possibilities)
def next_char(buffer : StringBuffer, depth, chars, used, possibilities):
# clones the char array for local use and remove used char
charsClone = copy_array(chars)
try:
charsClone.remove(used)
except ValueError:
pass
# clone buffer for local use
usedBuffer = buffer.clone()
# iterate over possible characters
for c in charsClone:
# append to buffer
usedBuffer.append(c)
if depth != 0: # if depth isnt 0, continue
# DEBUG: print("depth: " + str(depth) + ", chars: " + str(charsClone))
next_char(usedBuffer, depth - 1, charsClone, c, possibilities)
else: # else add it to the possibilities
possibilities.append(usedBuffer.get())
# reset buffer
usedBuffer = buffer.clone()
# close buffer
usedBuffer.close()
# actually do the magic
print("> generating possibilities")
t1 = time.time()
possibilities, count = get_shuffeled_variations(word);
t2 = time.time()
# format output nicely
print("> formatting output")
i = 0
for possibility in possibilities:
string = None
if type(possibility) != str:
string = chars_to_string(possibility)
else:
string = str(possibility)
output += "result: " + str(i) + " | " + string + "\n"
i += 1
# print output
print(output[:len(output)-1])
print("result-count: " + str(count))
print("time-taken-to-generate: " + f'{((t2 - t1) * 1000):.2f}' + "ms")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment