This file contains 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
def permute(*args) | |
# initialize the register for each array | |
# with [array itself, offset, its size] | |
memory = [] | |
perm_count = 1 | |
args.each do |array| | |
size = array.size | |
memory << [array, 0, size-1] | |
# get the number of all combinations | |
perm_count *= size | |
end | |
# remember the memory size | |
msize = memory.size | |
result = [] | |
# for every possible permutation | |
perm_count.times do |i| | |
# prepare empty array and bumped flag | |
permutation = [] | |
bumped = false | |
# iterate over subsets | |
msize.times do |j| | |
# get element with a registered offset | |
permutation.push(memory[j][0][memory[j][1]]) | |
# if no offset was bumped yet, bump one | |
unless bumped | |
# the current one | |
if memory[j][1] < memory[j][2] | |
memory[j][1] += 1 | |
bumped = true | |
else | |
# or any next possible one that will not overflow yet | |
# and set the current offset to 0 | |
memory[j][1] = 0 | |
bump_next(memory, j) | |
bumped = true | |
end | |
end | |
end | |
# save the permutation to the results array | |
result << permutation.join | |
end | |
result | |
end | |
# finiding the one that can be bumped | |
def bump_next(memory, j) | |
n = j+1 | |
unless memory[n].nil? | |
unless full?(memory[n]) | |
memory[n][1] += 1 | |
else | |
memory[n][1] = 0 | |
bump_next(memory, n) | |
end | |
end | |
end | |
# check if the offset doesn't overflow | |
def full?(array) | |
array[1]==array[2] | |
end |
There is still a recursive call moved to bump_next method. I'm trying to get rid of that one and make it fully iterative.
That was much fun doing it, as it has some tricky parts. Probably faster algorithm for that already exists, but I couldn't find any. Lots of fun.
No comments:
Post a Comment