Advertisement
Guest User

19.py /r/adventofcode

a guest
Dec 19th, 2015
2,599
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.57 KB | None | 0 0
  1. #TODO: AUTOMATIC CNF CONVERTER
  2. input = """Al => ThF
  3. Al => ThZaaa
  4. Zaaa => RnZaab
  5. Zaab => FAr
  6. Al => ThZaa
  7. Zaa => RnZab
  8. Zab => FAr
  9. B => BCa
  10. B => TiB
  11. B => TiZba
  12. Zba => RnZbb
  13. Zbb => FAr
  14. Ca => CaCa
  15. Ca => PB
  16. Ca => PZca
  17. Zca => RnZcb
  18. Zcb => FAr
  19. Ca => SiZcc
  20. Zcc => RnZcd
  21. Zcd => FZce
  22. Zce => YZcf
  23. Zcf => FAr
  24. Ca => SiZcg
  25. Zcg => RnZch
  26. Zch => MgAr
  27. Ca => SiTh
  28. F => CaF
  29. F => PMg
  30. F => SiAl
  31. H => CZha
  32. Zha => RnZhb
  33. Zhb => AlAr
  34. H => CZhc
  35. Zhc => RnZhd
  36. Zhd => FZhe
  37. Zhe => YZhf
  38. Zhf => FZhg
  39. Zhg => YZhh
  40. Zhh => FAr
  41. H => CZhi
  42. Zhi => RnZhj
  43. Zhj => FZhk
  44. Zhk => YZhl
  45. Zhl => MgAr
  46. H => CZhm
  47. Zhm => RnZhn
  48. Zhn => MgZho
  49. Zho => YZhp
  50. Zhp => FAr
  51. H => HCa
  52. H => NZhq
  53. Zhq => RnZhr
  54. Zhr => FZhs
  55. Zhs => YZht
  56. Zht => FAr
  57. H => NZhu
  58. Zhu => RnZhv
  59. Zhv => MgAr
  60. H => NTh
  61. H => OB
  62. H => OZhw
  63. Zhw => RnZhx
  64. Zhx => FAr
  65. Mg => BF
  66. Mg => TiMg
  67. N => CZna
  68. Zna => RnZnb
  69. Znb => FAr
  70. N => HSi
  71. O => CZoa
  72. Zoa => RnZob
  73. Zob => FZoc
  74. Zoc => YZod
  75. Zod => FAr
  76. O => CZoe
  77. Zoe => RnZof
  78. Zof => MgAr
  79. O => HP
  80. O => NZog
  81. Zog => RnZoh
  82. Zoh => FAr
  83. O => OTi
  84. P => CaP
  85. P => PTi
  86. P => SiZpa
  87. Zpa => RnZpb
  88. Zpb => FAr
  89. Si => CaSi
  90. Th => ThCa
  91. Ti => BP
  92. Ti => TiTi
  93. e => HF
  94. e => NAl
  95. e => OMg
  96. """
  97.  
  98. def getatom(s, i):
  99.     if s == 'e':
  100.         return 'e'
  101.     if s[i].upper() != s[i]:
  102.         return None
  103.     for x in xrange(i+1, len(s)):
  104.         if s[x].upper() == s[x]:
  105.             return s[i:x]
  106.     return s[i:]
  107.  
  108. molecule = "CRnCaCaCaSiRnBPTiMgArSiRnSiRnMgArSiRnCaFArTiTiBSiThFYCaFArCaCaSiThCaPBSiThSiThCaCaPTiRnPBSiThRnFArArCaCaSiThCaSiThSiRnMgArCaPTiBPRnFArSiThCaSiRnFArBCaSiRnCaPRnFArPMgYCaFArCaPTiTiTiBPBSiThCaPTiBPBSiRnFArBPBSiRnCaFArBPRnSiRnFArRnSiRnBFArCaFArCaCaCaSiThSiThCaCaPBPTiTiRnFArCaPTiBSiAlArPBCaCaCaCaCaSiRnMgArCaSiThFArThCaSiThCaSiRnCaFYCaSiRnFYFArFArCaSiRnFYFArCaSiRnBPMgArSiThPRnFArCaSiRnFArTiRnSiRnFYFArCaSiRnBFArCaSiRnTiMgArSiThCaSiThCaFArPRnFArSiRnFArTiTiTiTiBCaCaSiRnCaCaFYFArSiThCaPTiBPTiBCaSiThSiRnMgArCaF"
  109.  
  110. #input = """e => H
  111. #e => O
  112. #H => HO
  113. #H => OH
  114. #O => HH"""
  115. #molecule = "HOHOHO"
  116.  
  117. import itertools #https://docs.python.org/2/library/itertools.html#recipes
  118. import collections #https://docs.python.org/2/library/collections.html
  119. import re #https://docs.python.org/2/library/re.html
  120. import json #https://docs.python.org/2/library/json.html
  121.  
  122. calibrate = set()
  123. rules = collections.defaultdict(list)
  124. revrules = collections.defaultdict(list)
  125.  
  126. pattern = r"(.+) => (.+)"
  127. for src,repl in map(lambda y: (int(x) if x.isdigit() else x for x in y), re.findall(pattern, input)): #input.splitlines()
  128.     rules[src] += [repl]
  129.     revrules[repl] += [src]
  130.     for start in re.finditer(src, molecule):
  131.         start = start.start()
  132.         calibrate.add(molecule[:start] + repl + molecule[start+len(src):])
  133.  
  134. print "Part One:",len(calibrate)
  135.  
  136. """FAILED PART 2 BFS
  137. queue = collections.defaultdict(set)
  138. queue[0] = set(["e"])
  139. steps = 0
  140. while True:
  141.     if len(queue[steps]) == 0:
  142.         steps += 1
  143.         print steps, len(queue[steps])
  144.     current = queue[steps].pop()
  145.     for i in xrange(len(current)):
  146.         for rule in rules[getatom(current, i)]:
  147.             n = current[:i] + rule + current[i+len(getatom(current,i)):]
  148.             if "".join(n) == molecule:
  149.                 print "Part Two:", steps+1
  150.             queue[steps+1].add(n)
  151. """
  152.  
  153. cyk = collections.defaultdict(lambda: collections.defaultdict(list))
  154. for i,a in enumerate(re.findall("[A-Z][a-z]*", molecule)):
  155.     cyk[0][i] = [a]
  156.     insize = i
  157. backref = collections.defaultdict(lambda: collections.defaultdict(list))
  158. for y in xrange(1, insize+1):
  159.     for x in xrange(insize-y+1):
  160.         for i in xrange(0,y):
  161.             need = [t[0]+t[1] for t in itertools.product(cyk[i][x], cyk[y-i-1][x+i+1])]
  162.             for n in need:
  163.                 for blah in revrules.get("".join(n), []):
  164.                     if blah not in cyk[y][x]:
  165.                         cyk[y][x].append(blah)
  166.                         backref[y][x].append(((x,i),(x+i+1,y-i-1),n))
  167.  
  168. out = str(cyk[insize-1][0]) + "\n\n"
  169. for y in xrange(0,insize+1):
  170.     for x in xrange(insize-y+1):
  171.         out += str(x) +","+ str(y+x) + " "
  172.         for i in cyk[y][x]:
  173.             out += i + ","
  174.         out += " "
  175.         for i in backref[y][x]:
  176.             out += "("
  177.             for asd in i[0:2]:
  178.                 out += "(" + str(asd[0]) + "," + str(asd[0]+asd[1]) + "),"
  179.             out += i[2] + ")"
  180.         out += "\t"
  181.     out += "\n"
  182. out += "\n"
  183. def recur(x,y): #TODO: IS THIS WRONG IF THE FIRST EXPANSION FOUND IS NONOPTIMAL? (probably not because CNF)
  184.     global cyk,backref,out
  185.     if y == 0:
  186.         out += "at bottom: " + cyk[y][x][0] + "\n"
  187.         return
  188.     l,r,n = backref[y][x][0]
  189.     out += cyk[y][x][0] + " -> " + n + " (" + str(x) + "," + str(y) + ": " + repr(l) + "," + repr(r) + ")\n"
  190.     recur(*l)
  191.     recur(*r)
  192. recur(0,insize)
  193. with open("19_out.txt","w") as f:
  194.     f.write(out)
  195. print "Part Two:",len(re.findall("^[^Z].* ->", out, re.MULTILINE)) #TODO: CAN JUST KEEP A COUNTER IN RECUR
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement