21_fractalart.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/env python3
  2. import sys
  3. from itertools import islice
  4. def parse(f):
  5. def vflip(pat):
  6. return '/'.join(pat.split('/')[::-1])
  7. def hflip(pat):
  8. return '/'.join(l[::-1] for l in pat.split('/'))
  9. def rotate(pat):
  10. return '/'.join(''.join(l[::-1]) for l in zip(*pat.split('/')))
  11. rules = {}
  12. for line in f:
  13. pat, rep = line.rstrip().split(' => ')
  14. for pat in (pat, vflip(pat), hflip(pat)):
  15. rules[pat] = rep
  16. for i in range(3):
  17. pat = rotate(pat)
  18. rules[pat] = rep
  19. return rules
  20. def sqsplit(grid, w, sqsize):
  21. for y in range(0, w, sqsize):
  22. for x in range(0, w, sqsize):
  23. i = y * w + x
  24. yield '/'.join(grid[i + n * w:i + n * w + sqsize]
  25. for n in range(sqsize))
  26. def sqjoin(squares, w, sqsize, rules):
  27. squares = iter(squares)
  28. grid = ''
  29. for y in range(0, w, sqsize):
  30. row = islice(squares, w // sqsize)
  31. grid += ''.join(i for l in zip(*[sq.split('/') for sq in row]) for i in l)
  32. return grid
  33. def grow(grid, w, rules):
  34. sqsize = 2 + (w % 2)
  35. wnew = w + w // sqsize
  36. squares = sqsplit(grid, w, sqsize)
  37. transformed = (rules[sq] for sq in squares)
  38. return sqjoin(transformed, wnew, sqsize + 1, rules), wnew
  39. w = 3
  40. grid = '.#...####'
  41. rules = parse(sys.stdin)
  42. for i in range(5):
  43. grid, w = grow(grid, w, rules)
  44. print(grid.count('#'))
  45. for i in range(13):
  46. grid, w = grow(grid, w, rules)
  47. print(grid.count('#'))