Skip to content

Instantly share code, notes, and snippets.

@XertroV
Created May 23, 2015 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XertroV/5814c1d683dac2c54b6b to your computer and use it in GitHub Desktop.
Save XertroV/5814c1d683dac2c54b6b to your computer and use it in GitHub Desktop.
Randomly shuffle things with minimal bits (written in pyos/dg)
#!/usr/bin/env python3 -m dg
import '/hashlib'
import '/time'
Counter = subclass object where
__init__ = self ->
self.c = 0
None
increment = self ->
self.c += 1
get = self ->
self.c
bitCounter = Counter!
Node = subclass object where
__init__ = self children: None pointer: None ->
self.children = children
self.pointer = pointer
children is not None and pointer is not None => raise $ Exception "Both children and pointer cannot be set simultaneously"
None
setChildren = self children -> self.setCandP children None
setPointer = self pointer -> self.setCandP None pointer
setCandP = self children pointer ->
self.children = children
self.pointer = pointer
splitAndIntegrate = self pointer currPointerSecond: False ->
if currPointerSecond == True => self.children = (Node pointer: pointer, Node pointer: self.pointer)
otherwise => self.children = (Node pointer: self.pointer, Node pointer: pointer)
self.pointer = None
isEmpty = self -> self.children is None and self.pointer is None
hasPointer = self -> not $ self.pointer is None
hasChildren = self -> not $ self.children is None
flatten = self -> if
self.isEmpty! => []
self.hasPointer! => [self.pointer]
otherwise => (fst self.children).flatten! + (snd self.children).flatten!
hashFunction = plaintext -> hashlib.sha256 plaintext |>.digest!
insertCardRandomly = rootNode card bitGenerator ->
if rootNode.isEmpty! => rootNode.setPointer card
rootNode.hasPointer! => rootNode.splitAndIntegrate card currPointerSecond: (next bitGenerator == 0)
otherwise => insertCardRandomly (rootNode.children !! (next bitGenerator)) card bitGenerator
rootNode
bytesToBits = s_bytes -> for b in s_bytes => for i in range(8) =>
yield $ (b >> i) & 1
bitCounter.increment!
yieldBitsForever = seed -> while True =>
yield from $ bytesToBits seed
seed = (hashFunction seed)
NUM_CANDS = 150
cryptoSeed = hashFunction (time.time!.hex!.encode!)
bitGenerator = yieldBitsForever cryptoSeed
candidates = range NUM_CANDS
makeShuffledTree = -> foldl (rootNode card -> insertCardRandomly rootNode card bitGenerator) Node! candidates
trials = 500
for i in (range trials) => makeShuffledTree!
print "Done using" (bitCounter.get! / trials) "bits per trial;" NUM_CANDS "candidates per trial;" ((bitCounter.get! / trials) / NUM_CANDS) "bits per candidate"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment