part2.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import argparse
  2. import functools
  3. from typing import NamedTuple, List, Dict, Set, Tuple, Optional
  4. from collections import Counter, defaultdict
  5. import sys
  6. from functools import lru_cache
  7. parser = argparse.ArgumentParser()
  8. parser.add_argument("ifile", type=argparse.FileType('r'))
  9. args = parser.parse_args()
  10. pair_rules: Dict[str, str] = dict()
  11. template = args.ifile.readline().strip()
  12. args.ifile.readline() # skip blank line
  13. for line in args.ifile.readlines():
  14. chunks = line.strip().split(" ")
  15. pair_rules[chunks[0]] = chunks[2]
  16. def polymerize(template: str):
  17. global pair_rules
  18. constructed = "" + template[0]
  19. prev = template[0]
  20. for index in range(1, len(template)):
  21. constructed += pair_rules.get(prev + template[index], "")
  22. prev = template[index]
  23. constructed += template[index]
  24. return constructed
  25. @lru_cache(2048)
  26. def polyCount(template: str, steps: int):
  27. polymer = polymerize(template)
  28. if steps == 1:
  29. return Counter(polymer)
  30. stuff = [polyCount(polymer[index] + polymer[index + 1], steps - 1) for index in range(0, len(polymer) - 1)]
  31. return functools.reduce(lambda acc, val: acc + val, stuff) - Counter(polymer[1:-1])
  32. counts = polyCount(template, 40).most_common()
  33. print(counts[0][1] - counts[-1][1])