1
+ import functools
2
+
3
+ codeValues = {}
4
+ sequences = {}
5
+
6
+ def runSequence (code ):
7
+ sequence = sequences [code ]
8
+
9
+ match sequence [1 ]:
10
+ case 'AND' :
11
+ codeValues [code ] = getValue (sequence [0 ]) and getValue (sequence [2 ])
12
+ case 'OR' :
13
+ codeValues [code ] = getValue (sequence [0 ]) or getValue (sequence [2 ])
14
+ case 'XOR' :
15
+ codeValues [code ] = getValue (sequence [0 ]) ^ getValue (sequence [2 ])
16
+
17
+ return codeValues [code ]
18
+
19
+ @functools .cache
20
+ def getValue (code ):
21
+ if code in codeValues :
22
+ return codeValues [code ]
23
+
24
+ return runSequence (code )
25
+
26
+ with open ('2024/24/input.txt' ) as f :
27
+ for line in f :
28
+ line = line .strip ()
29
+
30
+ if '->' in line :
31
+ split = line .split (' -> ' )
32
+ result = split [1 ]
33
+ sequence = tuple (split [0 ].split (' ' ))
34
+ sequences [result ] = sequence
35
+
36
+ elif ':' in line :
37
+ split = line .split (': ' )
38
+ code = split [0 ]
39
+ value = int (split [1 ])
40
+ codeValues [code ] = value
41
+
42
+
43
+ # Rather than brute force a solution, I've noticed on paper that there's a consistent pattern:
44
+ # zXX are always made up of a XOR b - except for maybe the last one (my z45 is OR but seems okay)
45
+ # All XORs should have either xXX or yXX as input, or zXX as output like above
46
+ # All ANDs should not lead into XORs
47
+ # All ORs should be the output of AND, except for x00/y00
48
+ # Appears to be a full adder, not sure if that's necessarily true, just looks it on paper
49
+
50
+ # Find the gates that don't fulfull the criteria above
51
+ badGates = []
52
+ for code in sequences :
53
+ gate1 , operation , gate2 = sequences [code ]
54
+
55
+ if operation == 'XOR' and all (prefix not in 'xyz' for prefix in (code [0 ], gate1 [0 ], gate2 [0 ])):
56
+ badGates .append (code )
57
+ if code [0 ] == 'z' :
58
+ if operation != 'XOR' :
59
+ badGates .append (code )
60
+ if operation == 'XOR' :
61
+ if 'x00' not in (gate1 , gate2 ):
62
+ if not (gate1 [0 ] in ['x' , 'y' ] and gate2 [0 ] in ['x' , 'y' ]):
63
+ gate1Operation = sequences [gate1 ][1 ]
64
+ gate2Operation = sequences [gate2 ][1 ]
65
+
66
+ # if gate1Operation == 'AND':
67
+ # badGates.append(gate1)
68
+ if gate2Operation == 'AND' :
69
+ badGates .append (gate2 )
70
+ if operation == 'OR' :
71
+ if 'x00' not in (gate1 , gate2 ):
72
+ gate1Operation = sequences [gate1 ][1 ]
73
+ gate2Operation = sequences [gate2 ][1 ]
74
+
75
+ if gate1Operation == 'XOR' :
76
+ badGates .append (gate1 )
77
+ elif gate2Operation == 'XOR' :
78
+ badGates .append (gate2 )
79
+
80
+ print (',' .join (sorted (dict .fromkeys (badGates ))[:- 1 ])) #drop zXX's most significant bit
0 commit comments