I build a Tower of Hanoi solver which print the solution as an image
It works as expected but generating the image is relatively slow compared to the time to calculate the answer.
Here is the code:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
from PIL import Image
def hanoi(disks, source, helper, target, steps):
if disks > 0:
hanoi(disks - 1, source, target, helper, steps)
target.append(source.pop())
steps.append([SOURCE[:], HELPER[:], TARGET[:]])
hanoi(disks - 1, helper, source, target, steps)
def save_image(name):
print('\nSaving image {}.png'.format(name))
data = []
peg = args.disks * 2
cells = peg * 3 + 40 # 40 is to put some spaces between pegs and the border
for step in steps:
for _ in range(5): # White space
data.append([1 for _ in range(cells)])
src = step[0]
hlp = step[1]
trg = step[2]
size = max(len(src), len(hlp), len(trg))
for _ in range(size - len(src)):
src.append(0)
for _ in range(size - len(hlp)):
hlp.append(0)
for _ in range(size - len(trg)):
trg.append(0)
src.reverse()
hlp.reverse()
trg.reverse()
for s, h, t in zip(src, hlp, trg):
blanksrc = peg - 2 * s
blankhlp = peg - 2 * h
blanktrg = peg - 2 * t
row = [1 for _ in range(10)]
row += [1 for _ in range(blanksrc // 2)]
row += [0 for _ in range(s * 2)]
row += [1 for _ in range(blanksrc // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blankhlp // 2)]
row += [0 for _ in range(h * 2)]
row += [1 for _ in range(blankhlp // 2)]
row += [1 for _ in range(10)]
row += [1 for _ in range(blanktrg // 2)]
row += [0 for _ in range(t * 2)]
row += [1 for _ in range(blanktrg // 2)]
row += [1 for _ in range(10)]
data.append(row)
for _ in range(5): # White space
data.append([1 for _ in range(cells)])
data.append([0 for _ in range(cells)]) # Black line to separate steps
da = [bit for row in data for bit in row]
image = Image.new('1', (cells, len(data)))
image.putdata(da)
image.save('{}.png'.format(name))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--disks', type=int, default=4,
help='Number of disks, default 4')
parser.add_argument('-f', '--filename', help='Filename', required=True)
args = parser.parse_args()
if not args.disks > 0:
raise ValueError('There must be at least one disk')
SOURCE = list(reversed(range(1, args.disks + 1)))
TARGET = []
HELPER = []
steps = [[SOURCE[:], HELPER[:], TARGET[:]]]
hanoi(args.disks, SOURCE, HELPER, TARGET, steps)
save_image(args.filename)
As I add more disks in the problem, compared to the computation of the answer, the time taken to generate the image is longer and longer.
How can I make it faster and why it is so slow?