Advertisement
Guest User

Untitled

a guest
Dec 24th, 2024
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.84 KB | None | 0 0
  1. import re
  2. import numpy as np
  3. import networkx as nx
  4. from tqdm import tqdm
  5. import matplotlib.pyplot as plt
  6. from z3 import Solver, Bool, Xor, sat, If, Sum, Implies, Not, Or, And
  7. DAY=24
  8.  
  9.  
  10. # This solution never worked finished to run
  11. # The idea is to add a layer after every output, that allow to swap the "original" output with another "original" output
  12. # the inputs, always use the "non-original" version after a potential swap
  13. # the swap are decided by z3 solver, that will try allow only 4 swaps
  14.  
  15. with open(f'2024/day {DAY}/input.txt', 'r') as file:
  16. data = file.read()
  17.  
  18. inputs, rules = data.split("\n\n")
  19. inputs = [[i.split(": ")[0], int(i.split(": ")[1])] for i in inputs.split("\n")]
  20. print(inputs)
  21.  
  22. pattern = r'(\w+)\s+(XOR|OR|AND)\s+(\w+)\s+->\s+(\w+)'
  23. rules = re.findall(pattern, rules)
  24. print(rules)
  25.  
  26. x = 0
  27. y = 0
  28. for i,inp in enumerate(inputs):
  29. if inp[0].startswith("x"):
  30. x += 2**int(inp[0][1:]) * inp[1]
  31. print(x)
  32. for i,inp in enumerate(inputs):
  33. if inp[0].startswith("y"):
  34. y += 2**int(inp[0][1:]) * inp[1]
  35. print(y)
  36.  
  37. z = x + y
  38. print(z)
  39. z_str = bin(z)[2:]
  40. print(z_str)
  41.  
  42.  
  43. solver = Solver()
  44. variables = {}
  45. for i in inputs:
  46. variables[i[0]] = Bool(i[0])
  47. solver.add(variables[i[0]] == bool(i[1]))
  48.  
  49. possible_outputs= []
  50.  
  51. # Declare variables
  52. for r in rules:
  53. variables[r[0]] = Bool(r[0])
  54. variables[r[2]] = Bool(r[2])
  55. variables[r[3]] = Bool(r[3])
  56. possible_outputs.append(r[3])
  57. variables[r[3]+"_original"] = Bool(r[3]+"_original")
  58. # the "original" version of the node is the node before any wire swapping
  59.  
  60. # Add logic constraints
  61. for i,rule in enumerate(rules):
  62. if rule[1] == "XOR":
  63. rule_logic = variables[rule[3]+"_original"] == Xor(variables[rule[0]], variables[rule[2]])
  64. elif rule[1] == "OR":
  65. rule_logic = rule_logic = variables[rule[3]+"_original"] == Or(variables[rule[0]], variables[rule[2]])
  66. elif rule[1] == "AND":
  67. rule_logic = rule_logic = variables[rule[3]+"_original"] == And(variables[rule[0]], variables[rule[2]])
  68. solver.add(rule_logic)
  69.  
  70. pairs = []
  71. # declare swap flags
  72. for i in range(len(possible_outputs)):
  73. for j in range(i+1, len(possible_outputs)):
  74. pairs.append((possible_outputs[i], possible_outputs[j]))
  75. swap_flags = [Bool(f'swap_{i}_{j}') for i, j in pairs]
  76.  
  77. # force 4 swaps
  78. solver.add(Sum([If(flag, 1, 0) for flag in swap_flags]) == 4)
  79.  
  80. # if we swap i,j we force node_a == node_b_original and node_b == node_a_original
  81. for i, (a, b) in enumerate(pairs):
  82. solver.add(Implies(swap_flags[i], And(variables[a] == variables[b+"_original"],
  83. variables[b] == variables[a+"_original"])))
  84.  
  85. # node_i == node_i_original if ALL swap flags that contain i are false
  86. for var in possible_outputs:
  87. candidates = [swap_flags[i] for i in range(len(pairs)) if var in pairs[i]]
  88. all_candidates_false = And([Not(c) for c in candidates])
  89. solver.add(Implies(all_candidates_false, variables[var] == variables[var+"_original"]))
  90.  
  91.  
  92. z_str = z_str[::-1]
  93. for z_bit in range(len(z_str)):
  94. solver.add(variables[f"z{z_bit:02d}"] == Bool(z_str[z_bit]))
  95. print(solver)
  96.  
  97.  
  98. if solver.check() == sat:
  99. print("sat")
  100. else:
  101. print("unsat")
  102. exit()
  103.  
  104.  
  105. model = solver.model()
  106. print(model)
  107.  
  108. solution_dict = {}
  109.  
  110. for a in variables:
  111. if a.startswith("z") and not a.endswith("_original"):
  112. solution_dict[a] = If(model[variables[a]], 1, 0)
  113.  
  114. print(solution_dict)
  115.  
  116. solution_dict = dict(sorted(solution_dict.items(), key=lambda x: x[0]))
  117. print(solution_dict)
  118. answer = 0
  119. for i, a in enumerate(solution_dict):
  120. value = model.eval(solution_dict[a])
  121. answer += 2**i * int(value.as_long())
  122. print(answer)
  123.  
  124. for i, a in enumerate(swap_flags):
  125. if model[a] == True:
  126. print(swap_flags[i])
  127.  
  128. #submit(answer, part="b", day=DAY, year=2024, session=session_id)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement