Skip to content

Instantly share code, notes, and snippets.

@vadella
Created July 4, 2018 12:03
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 vadella/775b975bf351f1d8629d660e820eea8b to your computer and use it in GitHub Desktop.
Save vadella/775b975bf351f1d8629d660e820eea8b to your computer and use it in GitHub Desktop.
My hanoi implementation
from enum import IntEnum
from itertools import repeat
from PIL import Image
BUFFER_PEG = 10
LINE_WIDTH = 1
BUFFER_STEP = 5
class Color(IntEnum):
BLACK = 0
WHITE = 1
def hanoi_gen(disks, source, helper, target, state):
if disks:
yield from hanoi_gen(disks - 1, source, target, helper, state)
target.append(source.pop())
yield (
tuple(state['source']),
tuple(state['target']),
tuple(state['helper']),
)
yield from hanoi_gen(disks - 1, helper, source, target, state)
def solve_tower(disks):
source = list(range(disks, 0, -1))
target = list()
helper = list()
yield tuple(source), tuple(target), tuple(helper)
state = dict(
source=source,
target=target,
helper=helper
)
yield from hanoi_gen(disks, source, helper, target, state)
def whitespace(width, image_width):
return repeat(Color.WHITE, width * image_width)
def line(width, image_width):
return repeat(Color.BLACK, width * image_width)
def pad_disk(disk_width, num_disks):
blank_width = num_disks - disk_width
yield from repeat(Color.WHITE, blank_width)
yield from repeat(Color.BLACK, disk_width * 2)
yield from repeat(Color.WHITE, blank_width)
def buffer_peg():
return repeat(Color.WHITE, BUFFER_PEG)
def format_row(disks, num_disks):
yield from buffer_peg()
for disk_width in disks:
yield from pad_disk(disk_width, num_disks)
yield from buffer_peg()
def pad_left_reverse(peg, size, fillvalue=0):
yield from repeat(fillvalue, size - len(peg))
yield from reversed(peg)
def format_step(step, num_disks):
pegs = map(
lambda peg: pad_left_reverse(peg, num_disks, fillvalue=0),
step
)
for row in zip(*pegs):
yield from format_row(row, num_disks)
def format_steps(steps, image_width, num_disks):
for step in steps:
yield from whitespace(BUFFER_STEP, image_width)
yield from format_step(step, num_disks)
yield from whitespace(BUFFER_STEP, image_width)
yield from line(LINE_WIDTH, image_width)
if __name__ == '__main__':
num_disks = 5
steps = solve_tower(num_disks)
image_width = num_disks * 2 * 3 + 4 * BUFFER_PEG
data = list(format_steps(steps, image_width, num_disks))
with Image.new('1', (image_width, len(data) // image_width)) as image:
image.putdata(data)
name = 'my_hanoi.png'
image.save(name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment