Skip to content

Instantly share code, notes, and snippets.

@zacharysyoung
Last active June 30, 2019 04:57
Show Gist options
  • Save zacharysyoung/ec77ca47c3fc3ffd7751a69358fec6ee to your computer and use it in GitHub Desktop.
Save zacharysyoung/ec77ca47c3fc3ffd7751a69358fec6ee to your computer and use it in GitHub Desktop.
Still playing around with this silly recursive function for permutating a positional notation
def permute(n, chars='01', limit=128, start=0):
appended = 0
counter = 0
def f(s, a):
nonlocal appended
nonlocal counter
if appended == limit:
return a
if len(s) == n:
if counter >= start:
a.append(s)
appended += 1
counter += 1
return a
for char in chars:
a = f(s+char, a)
return a
return f('', [])
# 7-bit values, starting at 16
# >>> permute(7, limit=4, start=16)
# ['0010000', '0010001', '0010010', '0010011']
# Some web colors, starting at "magenta" (:)blue (ff), no green (00), red (ff))
# >>> permute(6, '0123456789abcdef', limit=10, start=16711935)
# ['ff00ff', 'ff0100', 'ff0101', 'ff0102', 'ff0103',
# 'ff0104', 'ff0105', 'ff0106', 'ff0107', 'ff0108']
# And the encoding that started it all, punctuation for mixing into Gmail names:
# >>> puncs = permute(6, '. ', limit=2, start=40)
# >>> puncs
# [' . ...', ' . .. ']
# >>> zips = [list(zip([x for x in 'mytest'], [x for x in punc])) for punc in puncs]
# >>> zips
# [
# [('m', ' '), ('y', '.'), ('t', ' '), ('e', '.'), ('s', '.'), ('t', '.')],
# [('m', ' '), ('y', '.'), ('t', ' '), ('e', '.'), ('s', '.'), ('t', ' ')]
# ]
# >>> [[''.join(y).strip() for y in x] for x in zips]
# [['m', 'y.', 't', 'e.', 's.', 't.'], ['m', 'y.', 't', 'e.', 's.', 't']]
# >>> [''.join([''.join(y).strip() for y in x]) + '@gmail.com' for x in zips]
# ['my.te.s.t.@gmail.com', 'my.te.s.t@gmail.com']
# Hey, still making it better!!
def permute3(n, notation, start=0, count=None, f=None):
if notation is 'hex':
s = '{:0%dx}' % n
base = 16
if notation is 'bin':
s = '{:0%db}' % n
base = 2
if notation is 'oct':
s = '{:0%do}' % n
base = 8
space_size = base**n
if count:
end = start+count
else:
end = space_size
assert end <= space_size, \
'Start + count (%d) exceeds size of the encoded space (%d**%d = %d)' % (
end, base, n, space_size)
if not f:
f = s.format
return [f(i) for i in range(start, end)]
# Web colors
# >>> permute3(6, 'hex', start=16711935, limit=10)
# ['ff00ff', 'ff0100', 'ff0101', 'ff0102', 'ff0103', 'ff0104', 'ff0105', 'ff0106', 'ff0107', 'ff0108']
# 7-bit values, starting at 16
# >>> permute3(7, 'bin', start=16, limit=10)
# ['0010000', '0010001', '0010010', '0010011', '0010100', '0010101', '0010110', '0010111', '0011000', '0011001']
# Same as above, but with a custom func to effect the 'punctuation encoding'; have to ensure the padding value in `{:07b}`
# matches the `n` param in `permute3(7...`
# >>> punc_func = lambda x: '{:07b}'.format(x).replace('0',' ').replace('1','.')
# >>> punc_func(31)
# ' .....'
# >>> punc_func(63)
# '......'
# >>> permute3(7, 'bin', start=16, limit=10, f=punc_func)
# [' . ', ' . .', ' . . ', ' . ..', ' . . ', ' . . .', ' . .. ', ' . ...', ' .. ', ' .. .']
# ['0010000', '0010001', '0010010', '0010011', '0010100', '0010101', '0010110', '0010111', '0011000', '0011001']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment