diff --git a/aoc2024/src/day24/python/solution.py b/aoc2024/src/day24/python/solution.py
index a411399..510173b 100644
--- a/aoc2024/src/day24/python/solution.py
+++ b/aoc2024/src/day24/python/solution.py
@@ -13,12 +13,14 @@
# limitations under the License.
from typing import Sequence
from collections import defaultdict, deque
+from itertools import product
+import graphviz
type GateOp = tuple[str, str, str]
def _parse_input(input: Sequence[str]) -> tuple[
- dict[str, list[str | GateOp]], dict[str | GateOp, int], dict[str, GateOp]]:
+ dict[str | GateOp, list[str | GateOp]], dict[str | GateOp, int], dict[str, GateOp]]:
graph = defaultdict(list) # Adjacency list.
initial_values = dict() # Wires with initial values.
ends = dict() # Reverse map with gate output as keys and gate inputs as values.
@@ -77,10 +79,9 @@ def _wires_to_integer(wire_values: dict[str | GateOp, int], wire_prefix: str) ->
return int(''.join([str(value) for _, value in sorted(result, reverse=True)]), 2)
-def get_output(input: Sequence[str]) -> int:
- graph, wire_values, ends = _parse_input(input)
- print(f'x={_wires_to_integer(wire_values, wire_prefix='x')}')
- print(f'y={_wires_to_integer(wire_values, wire_prefix='y')}')
+def _calculate(graph: dict[str | GateOp, list[str | GateOp]],
+ wire_values: dict[str | GateOp, int],
+ ends: dict[str, GateOp]) -> None:
for task in _topological_sort(graph):
if type(task) is tuple: # Is a logic gate.
wire1, gate, wire2 = task
@@ -92,4 +93,48 @@ def get_output(input: Sequence[str]) -> int:
wire_values[task] = wire_values[wire1] ^ wire_values[wire2]
elif task in ends:
wire_values[task] = wire_values[ends.get(task)]
+
+
+def get_output(input: Sequence[str]) -> int:
+ graph, wire_values, ends = _parse_input(input)
+ _calculate(graph=graph, wire_values=wire_values, ends=ends)
return _wires_to_integer(wire_values=wire_values, wire_prefix='z')
+
+
+def _swap(a: str, b: str, graph: dict[str | GateOp, list[str | GateOp]], ends: dict[str, GateOp]) -> None:
+ for adj_list in graph.values():
+ if len(adj_list) == 1 and adj_list[0] == a:
+ adj_list[0] = ''
+ for adj_list in graph.values():
+ if len(adj_list) == 1 and adj_list[0] == b:
+ adj_list[0] = a
+ for adj_list in graph.values():
+ if len(adj_list) == 1 and adj_list[0] == '':
+ adj_list[0] = b
+ tmp = ends[a]
+ ends[a] = ends[b]
+ ends[b] = tmp
+
+
+def _print_graphviz(graph: dict[str | GateOp, list[str | GateOp]]) -> None:
+ """Prints graph as Graphviz DOT."""
+ dot = graphviz.Digraph()
+ for key, values in graph.items():
+ for value in values:
+ dot.edge(str(key), str(value))
+ print(dot.source)
+
+
+def find_wrong_output_wires(input: Sequence[str], swaps: tuple[tuple[str, str], ...], operation: str = '&') -> str:
+ graph, wire_values, ends = _parse_input(input)
+ # _print_graphviz(graph)
+ x = _wires_to_integer(wire_values, wire_prefix='x')
+ y = _wires_to_integer(wire_values, wire_prefix='y')
+ for swap in swaps:
+ _swap(a=swap[0], b=swap[1], graph=graph, ends=ends)
+ _calculate(graph=graph, wire_values=wire_values, ends=ends)
+ z = _wires_to_integer(wire_values=wire_values, wire_prefix='z')
+ expected = eval(f'{x} {operation} {y}')
+ if expected == z:
+ return ','.join(sorted(([wire for swap in swaps for wire in swap])))
+ raise ValueError('Could not find wrong wires!')
diff --git a/aoc2024/test/day24/python/example3.dot b/aoc2024/test/day24/python/example3.dot
new file mode 100644
index 0000000..4bd94b1
--- /dev/null
+++ b/aoc2024/test/day24/python/example3.dot
@@ -0,0 +1,20 @@
+digraph {
+ "('x00', 'AND', 'y00')" -> z05
+ x00 -> "('x00', 'AND', 'y00')"
+ y00 -> "('x00', 'AND', 'y00')"
+ "('x01', 'AND', 'y01')" -> z02
+ x01 -> "('x01', 'AND', 'y01')"
+ y01 -> "('x01', 'AND', 'y01')"
+ "('x02', 'AND', 'y02')" -> z01
+ x02 -> "('x02', 'AND', 'y02')"
+ y02 -> "('x02', 'AND', 'y02')"
+ "('x03', 'AND', 'y03')" -> z03
+ x03 -> "('x03', 'AND', 'y03')"
+ y03 -> "('x03', 'AND', 'y03')"
+ "('x04', 'AND', 'y04')" -> z04
+ x04 -> "('x04', 'AND', 'y04')"
+ y04 -> "('x04', 'AND', 'y04')"
+ "('x05', 'AND', 'y05')" -> z00
+ x05 -> "('x05', 'AND', 'y05')"
+ y05 -> "('x05', 'AND', 'y05')"
+}
\ No newline at end of file
diff --git a/aoc2024/test/day24/python/example3.svg b/aoc2024/test/day24/python/example3.svg
new file mode 100644
index 0000000..b947296
--- /dev/null
+++ b/aoc2024/test/day24/python/example3.svg
@@ -0,0 +1,264 @@
+
+
+
+
+
diff --git a/aoc2024/test/day24/python/example3.txt b/aoc2024/test/day24/python/example3.txt
new file mode 100644
index 0000000..0129ce4
--- /dev/null
+++ b/aoc2024/test/day24/python/example3.txt
@@ -0,0 +1,19 @@
+x00: 0
+x01: 1
+x02: 0
+x03: 1
+x04: 0
+x05: 1
+y00: 0
+y01: 0
+y02: 1
+y03: 1
+y04: 0
+y05: 1
+
+x00 AND y00 -> z05
+x01 AND y01 -> z02
+x02 AND y02 -> z01
+x03 AND y03 -> z03
+x04 AND y04 -> z04
+x05 AND y05 -> z00
\ No newline at end of file
diff --git a/aoc2024/test/day24/python/input.dot b/aoc2024/test/day24/python/input.dot
new file mode 100644
index 0000000..80c3092
--- /dev/null
+++ b/aoc2024/test/day24/python/input.dot
@@ -0,0 +1,668 @@
+digraph {
+ "('y33', 'AND', 'x33')" -> bfn
+ y33 -> "('y33', 'AND', 'x33')"
+ y33 -> "('y33', 'XOR', 'x33')"
+ x33 -> "('y33', 'AND', 'x33')"
+ x33 -> "('y33', 'XOR', 'x33')"
+ "('y32', 'XOR', 'x32')" -> rck
+ y32 -> "('y32', 'XOR', 'x32')"
+ y32 -> "('y32', 'AND', 'x32')"
+ x32 -> "('y32', 'XOR', 'x32')"
+ x32 -> "('y32', 'AND', 'x32')"
+ "('x30', 'AND', 'y30')" -> gns
+ x30 -> "('x30', 'AND', 'y30')"
+ x30 -> "('y30', 'XOR', 'x30')"
+ y30 -> "('x30', 'AND', 'y30')"
+ y30 -> "('y30', 'XOR', 'x30')"
+ "('y36', 'XOR', 'x36')" -> hbh
+ y36 -> "('y36', 'XOR', 'x36')"
+ y36 -> "('y36', 'AND', 'x36')"
+ x36 -> "('y36', 'XOR', 'x36')"
+ x36 -> "('y36', 'AND', 'x36')"
+ "('cng', 'XOR', 'mwt')" -> z42
+ cng -> "('cng', 'XOR', 'mwt')"
+ cng -> "('mwt', 'AND', 'cng')"
+ mwt -> "('cng', 'XOR', 'mwt')"
+ mwt -> "('mwt', 'AND', 'cng')"
+ "('bsw', 'OR', 'bfp')" -> pwp
+ bsw -> "('bsw', 'OR', 'bfp')"
+ bfp -> "('bsw', 'OR', 'bfp')"
+ "('x00', 'XOR', 'y00')" -> z00
+ x00 -> "('x00', 'XOR', 'y00')"
+ x00 -> "('y00', 'AND', 'x00')"
+ y00 -> "('x00', 'XOR', 'y00')"
+ y00 -> "('y00', 'AND', 'x00')"
+ "('y26', 'XOR', 'x26')" -> wkb
+ y26 -> "('y26', 'XOR', 'x26')"
+ y26 -> "('y26', 'AND', 'x26')"
+ x26 -> "('y26', 'XOR', 'x26')"
+ x26 -> "('y26', 'AND', 'x26')"
+ "('x31', 'AND', 'y31')" -> hjq
+ x31 -> "('x31', 'AND', 'y31')"
+ x31 -> "('x31', 'XOR', 'y31')"
+ y31 -> "('x31', 'AND', 'y31')"
+ y31 -> "('x31', 'XOR', 'y31')"
+ "('jhg', 'AND', 'gfd')" -> bbr
+ jhg -> "('jhg', 'AND', 'gfd')"
+ jhg -> "('jhg', 'XOR', 'gfd')"
+ gfd -> "('jhg', 'AND', 'gfd')"
+ gfd -> "('jhg', 'XOR', 'gfd')"
+ "('y43', 'XOR', 'x43')" -> fhk
+ y43 -> "('y43', 'XOR', 'x43')"
+ y43 -> "('y43', 'AND', 'x43')"
+ x43 -> "('y43', 'XOR', 'x43')"
+ x43 -> "('y43', 'AND', 'x43')"
+ "('mrg', 'OR', 'hjq')" -> ftq
+ mrg -> "('mrg', 'OR', 'hjq')"
+ hjq -> "('mrg', 'OR', 'hjq')"
+ "('jks', 'OR', 'cwn')" -> qvq
+ jks -> "('jks', 'OR', 'cwn')"
+ cwn -> "('jks', 'OR', 'cwn')"
+ "('wrc', 'XOR', 'hbw')" -> z17
+ wrc -> "('wrc', 'XOR', 'hbw')"
+ wrc -> "('hbw', 'AND', 'wrc')"
+ hbw -> "('wrc', 'XOR', 'hbw')"
+ hbw -> "('hbw', 'AND', 'wrc')"
+ "('skh', 'XOR', 'rkt')" -> z15
+ skh -> "('skh', 'XOR', 'rkt')"
+ skh -> "('rkt', 'AND', 'skh')"
+ rkt -> "('skh', 'XOR', 'rkt')"
+ rkt -> "('rkt', 'AND', 'skh')"
+ "('x27', 'AND', 'y27')" -> kbf
+ x27 -> "('x27', 'AND', 'y27')"
+ x27 -> "('y27', 'XOR', 'x27')"
+ y27 -> "('x27', 'AND', 'y27')"
+ y27 -> "('y27', 'XOR', 'x27')"
+ "('jgg', 'OR', 'cmm')" -> qpm
+ jgg -> "('jgg', 'OR', 'cmm')"
+ cmm -> "('jgg', 'OR', 'cmm')"
+ "('y17', 'XOR', 'x17')" -> hbw
+ y17 -> "('y17', 'XOR', 'x17')"
+ y17 -> "('x17', 'AND', 'y17')"
+ x17 -> "('y17', 'XOR', 'x17')"
+ x17 -> "('x17', 'AND', 'y17')"
+ "('khf', 'AND', 'djt')" -> khs
+ khf -> "('khf', 'AND', 'djt')"
+ khf -> "('djt', 'XOR', 'khf')"
+ djt -> "('khf', 'AND', 'djt')"
+ djt -> "('djt', 'XOR', 'khf')"
+ "('qqw', 'XOR', 'gkc')" -> wpd
+ qqw -> "('qqw', 'XOR', 'gkc')"
+ qqw -> "('gkc', 'AND', 'qqw')"
+ gkc -> "('qqw', 'XOR', 'gkc')"
+ gkc -> "('gkc', 'AND', 'qqw')"
+ "('rms', 'XOR', 'sgf')" -> z31
+ rms -> "('rms', 'XOR', 'sgf')"
+ rms -> "('sgf', 'AND', 'rms')"
+ sgf -> "('rms', 'XOR', 'sgf')"
+ sgf -> "('sgf', 'AND', 'rms')"
+ "('gww', 'XOR', 'jmf')" -> z24
+ gww -> "('gww', 'XOR', 'jmf')"
+ gww -> "('jmf', 'AND', 'gww')"
+ jmf -> "('gww', 'XOR', 'jmf')"
+ jmf -> "('jmf', 'AND', 'gww')"
+ "('x01', 'XOR', 'y01')" -> kjs
+ x01 -> "('x01', 'XOR', 'y01')"
+ x01 -> "('x01', 'AND', 'y01')"
+ y01 -> "('x01', 'XOR', 'y01')"
+ y01 -> "('x01', 'AND', 'y01')"
+ "('pwp', 'AND', 'nnn')" -> dwg
+ pwp -> "('pwp', 'AND', 'nnn')"
+ pwp -> "('pwp', 'XOR', 'nnn')"
+ nnn -> "('pwp', 'AND', 'nnn')"
+ nnn -> "('pwp', 'XOR', 'nnn')"
+ "('tjq', 'OR', 'hhj')" -> cmb
+ tjq -> "('tjq', 'OR', 'hhj')"
+ hhj -> "('tjq', 'OR', 'hhj')"
+ "('x05', 'XOR', 'y05')" -> fds
+ x05 -> "('x05', 'XOR', 'y05')"
+ x05 -> "('y05', 'AND', 'x05')"
+ y05 -> "('x05', 'XOR', 'y05')"
+ y05 -> "('y05', 'AND', 'x05')"
+ "('x07', 'AND', 'y07')" -> jbw
+ x07 -> "('x07', 'AND', 'y07')"
+ x07 -> "('x07', 'XOR', 'y07')"
+ y07 -> "('x07', 'AND', 'y07')"
+ y07 -> "('x07', 'XOR', 'y07')"
+ "('y32', 'AND', 'x32')" -> wnt
+ "('x14', 'XOR', 'y14')" -> cgg
+ x14 -> "('x14', 'XOR', 'y14')"
+ x14 -> "('x14', 'AND', 'y14')"
+ y14 -> "('x14', 'XOR', 'y14')"
+ y14 -> "('x14', 'AND', 'y14')"
+ "('rhf', 'AND', 'cgg')" -> smd
+ rhf -> "('rhf', 'AND', 'cgg')"
+ rhf -> "('cgg', 'XOR', 'rhf')"
+ cgg -> "('rhf', 'AND', 'cgg')"
+ cgg -> "('cgg', 'XOR', 'rhf')"
+ "('djt', 'XOR', 'khf')" -> z35
+ "('tcq', 'OR', 'rjb')" -> pfc
+ tcq -> "('tcq', 'OR', 'rjb')"
+ rjb -> "('tcq', 'OR', 'rjb')"
+ "('qtv', 'OR', 'khs')" -> rfq
+ qtv -> "('qtv', 'OR', 'khs')"
+ khs -> "('qtv', 'OR', 'khs')"
+ "('y41', 'XOR', 'x41')" -> jhg
+ y41 -> "('y41', 'XOR', 'x41')"
+ y41 -> "('x41', 'AND', 'y41')"
+ x41 -> "('y41', 'XOR', 'x41')"
+ x41 -> "('x41', 'AND', 'y41')"
+ "('jbw', 'OR', 'trv')" -> tmg
+ jbw -> "('jbw', 'OR', 'trv')"
+ trv -> "('jbw', 'OR', 'trv')"
+ "('y21', 'XOR', 'x21')" -> csw
+ y21 -> "('y21', 'XOR', 'x21')"
+ y21 -> "('y21', 'AND', 'x21')"
+ x21 -> "('y21', 'XOR', 'x21')"
+ x21 -> "('y21', 'AND', 'x21')"
+ "('jkm', 'XOR', 'dmp')" -> z13
+ jkm -> "('jkm', 'XOR', 'dmp')"
+ jkm -> "('dmp', 'AND', 'jkm')"
+ dmp -> "('jkm', 'XOR', 'dmp')"
+ dmp -> "('dmp', 'AND', 'jkm')"
+ "('rkh', 'OR', 'cqg')" -> jkr
+ rkh -> "('rkh', 'OR', 'cqg')"
+ cqg -> "('rkh', 'OR', 'cqg')"
+ "('y20', 'XOR', 'x20')" -> bvw
+ y20 -> "('y20', 'XOR', 'x20')"
+ y20 -> "('y20', 'AND', 'x20')"
+ x20 -> "('y20', 'XOR', 'x20')"
+ x20 -> "('y20', 'AND', 'x20')"
+ "('pwb', 'OR', 'jdc')" -> smt
+ pwb -> "('pwb', 'OR', 'jdc')"
+ jdc -> "('pwb', 'OR', 'jdc')"
+ "('x13', 'AND', 'y13')" -> rbg
+ x13 -> "('x13', 'AND', 'y13')"
+ x13 -> "('x13', 'XOR', 'y13')"
+ y13 -> "('x13', 'AND', 'y13')"
+ y13 -> "('x13', 'XOR', 'y13')"
+ "('wvt', 'XOR', 'sbt')" -> z03
+ wvt -> "('wvt', 'XOR', 'sbt')"
+ wvt -> "('wvt', 'AND', 'sbt')"
+ sbt -> "('wvt', 'XOR', 'sbt')"
+ sbt -> "('wvt', 'AND', 'sbt')"
+ "('jhg', 'XOR', 'gfd')" -> z41
+ "('x01', 'AND', 'y01')" -> fqg
+ "('wfc', 'XOR', 'cmp')" -> mdd
+ wfc -> "('wfc', 'XOR', 'cmp')"
+ wfc -> "('cmp', 'AND', 'wfc')"
+ cmp -> "('wfc', 'XOR', 'cmp')"
+ cmp -> "('cmp', 'AND', 'wfc')"
+ "('cgg', 'XOR', 'rhf')" -> z14
+ "('wkb', 'XOR', 'jkr')" -> z26
+ wkb -> "('wkb', 'XOR', 'jkr')"
+ wkb -> "('wkb', 'AND', 'jkr')"
+ jkr -> "('wkb', 'XOR', 'jkr')"
+ jkr -> "('wkb', 'AND', 'jkr')"
+ "('y36', 'AND', 'x36')" -> jdc
+ "('x08', 'AND', 'y08')" -> gdd
+ x08 -> "('x08', 'AND', 'y08')"
+ x08 -> "('y08', 'XOR', 'x08')"
+ y08 -> "('x08', 'AND', 'y08')"
+ y08 -> "('y08', 'XOR', 'x08')"
+ "('fds', 'AND', 'whf')" -> vvs
+ fds -> "('fds', 'AND', 'whf')"
+ fds -> "('whf', 'XOR', 'fds')"
+ whf -> "('fds', 'AND', 'whf')"
+ whf -> "('whf', 'XOR', 'fds')"
+ "('y19', 'AND', 'x19')" -> z19
+ y19 -> "('y19', 'AND', 'x19')"
+ y19 -> "('x19', 'XOR', 'y19')"
+ x19 -> "('y19', 'AND', 'x19')"
+ x19 -> "('x19', 'XOR', 'y19')"
+ "('x31', 'XOR', 'y31')" -> rms
+ "('nss', 'AND', 'jmv')" -> vtd
+ nss -> "('nss', 'AND', 'jmv')"
+ nss -> "('jmv', 'XOR', 'nss')"
+ jmv -> "('nss', 'AND', 'jmv')"
+ jmv -> "('jmv', 'XOR', 'nss')"
+ "('pwp', 'XOR', 'nnn')" -> z30
+ "('x23', 'XOR', 'y23')" -> mcp
+ x23 -> "('x23', 'XOR', 'y23')"
+ x23 -> "('y23', 'AND', 'x23')"
+ y23 -> "('x23', 'XOR', 'y23')"
+ y23 -> "('y23', 'AND', 'x23')"
+ "('jvf', 'XOR', 'jth')" -> z04
+ jvf -> "('jvf', 'XOR', 'jth')"
+ jvf -> "('jth', 'AND', 'jvf')"
+ jth -> "('jvf', 'XOR', 'jth')"
+ jth -> "('jth', 'AND', 'jvf')"
+ "('y38', 'AND', 'x38')" -> jhv
+ y38 -> "('y38', 'AND', 'x38')"
+ y38 -> "('x38', 'XOR', 'y38')"
+ x38 -> "('y38', 'AND', 'x38')"
+ x38 -> "('x38', 'XOR', 'y38')"
+ "('kjs', 'AND', 'hjp')" -> wkq
+ kjs -> "('kjs', 'AND', 'hjp')"
+ kjs -> "('hjp', 'XOR', 'kjs')"
+ hjp -> "('kjs', 'AND', 'hjp')"
+ hjp -> "('hjp', 'XOR', 'kjs')"
+ "('sqj', 'AND', 'wts')" -> qdn
+ sqj -> "('sqj', 'AND', 'wts')"
+ sqj -> "('sqj', 'XOR', 'wts')"
+ wts -> "('sqj', 'AND', 'wts')"
+ wts -> "('sqj', 'XOR', 'wts')"
+ "('y16', 'XOR', 'x16')" -> rvn
+ y16 -> "('y16', 'XOR', 'x16')"
+ y16 -> "('x16', 'AND', 'y16')"
+ x16 -> "('y16', 'XOR', 'x16')"
+ x16 -> "('x16', 'AND', 'y16')"
+ "('kbf', 'OR', 'mqr')" -> msf
+ kbf -> "('kbf', 'OR', 'mqr')"
+ mqr -> "('kbf', 'OR', 'mqr')"
+ "('y25', 'XOR', 'x25')" -> prp
+ y25 -> "('y25', 'XOR', 'x25')"
+ y25 -> "('y25', 'AND', 'x25')"
+ x25 -> "('y25', 'XOR', 'x25')"
+ x25 -> "('y25', 'AND', 'x25')"
+ "('y26', 'AND', 'x26')" -> tjq
+ "('cgv', 'OR', 'gmf')" -> mkf
+ cgv -> "('cgv', 'OR', 'gmf')"
+ gmf -> "('cgv', 'OR', 'gmf')"
+ "('y12', 'XOR', 'x12')" -> htn
+ y12 -> "('y12', 'XOR', 'x12')"
+ y12 -> "('x12', 'AND', 'y12')"
+ x12 -> "('y12', 'XOR', 'x12')"
+ x12 -> "('x12', 'AND', 'y12')"
+ "('kdd', 'AND', 'msf')" -> dpr
+ kdd -> "('kdd', 'AND', 'msf')"
+ kdd -> "('msf', 'XOR', 'kdd')"
+ msf -> "('kdd', 'AND', 'msf')"
+ msf -> "('msf', 'XOR', 'kdd')"
+ "('vtd', 'OR', 'bnw')" -> khf
+ vtd -> "('vtd', 'OR', 'bnw')"
+ bnw -> "('vtd', 'OR', 'bnw')"
+ "('smd', 'OR', 'ttv')" -> rkt
+ smd -> "('smd', 'OR', 'ttv')"
+ ttv -> "('smd', 'OR', 'ttv')"
+ "('fnc', 'OR', 'mmk')" -> jmf
+ fnc -> "('fnc', 'OR', 'mmk')"
+ mmk -> "('fnc', 'OR', 'mmk')"
+ "('ppk', 'OR', 'hwb')" -> jbd
+ ppk -> "('ppk', 'OR', 'hwb')"
+ hwb -> "('ppk', 'OR', 'hwb')"
+ "('jbd', 'AND', 'nns')" -> nnq
+ jbd -> "('jbd', 'AND', 'nns')"
+ jbd -> "('nns', 'XOR', 'jbd')"
+ nns -> "('jbd', 'AND', 'nns')"
+ nns -> "('nns', 'XOR', 'jbd')"
+ "('mcp', 'XOR', 'mkf')" -> z23
+ mcp -> "('mcp', 'XOR', 'mkf')"
+ mcp -> "('mcp', 'AND', 'mkf')"
+ mkf -> "('mcp', 'XOR', 'mkf')"
+ mkf -> "('mcp', 'AND', 'mkf')"
+ "('kbb', 'AND', 'wpb')" -> jmp
+ kbb -> "('kbb', 'AND', 'wpb')"
+ kbb -> "('wpb', 'XOR', 'kbb')"
+ wpb -> "('kbb', 'AND', 'wpb')"
+ wpb -> "('wpb', 'XOR', 'kbb')"
+ "('pbb', 'OR', 'mdd')" -> hvn
+ pbb -> "('pbb', 'OR', 'mdd')"
+ mdd -> "('pbb', 'OR', 'mdd')"
+ "('dts', 'XOR', 'wmq')" -> z33
+ dts -> "('dts', 'XOR', 'wmq')"
+ dts -> "('dts', 'AND', 'wmq')"
+ wmq -> "('dts', 'XOR', 'wmq')"
+ wmq -> "('dts', 'AND', 'wmq')"
+ "('x42', 'AND', 'y42')" -> hnh
+ x42 -> "('x42', 'AND', 'y42')"
+ x42 -> "('y42', 'XOR', 'x42')"
+ y42 -> "('x42', 'AND', 'y42')"
+ y42 -> "('y42', 'XOR', 'x42')"
+ "('rck', 'AND', 'ftq')" -> hfc
+ rck -> "('rck', 'AND', 'ftq')"
+ rck -> "('rck', 'XOR', 'ftq')"
+ ftq -> "('rck', 'AND', 'ftq')"
+ ftq -> "('rck', 'XOR', 'ftq')"
+ "('rfq', 'XOR', 'hbh')" -> z36
+ rfq -> "('rfq', 'XOR', 'hbh')"
+ rfq -> "('rfq', 'AND', 'hbh')"
+ hbh -> "('rfq', 'XOR', 'hbh')"
+ hbh -> "('rfq', 'AND', 'hbh')"
+ "('y05', 'AND', 'x05')" -> hpn
+ "('nns', 'XOR', 'jbd')" -> z40
+ "('x14', 'AND', 'y14')" -> ttv
+ "('jmv', 'XOR', 'nss')" -> z34
+ "('vth', 'OR', 'gdd')" -> wpb
+ vth -> "('vth', 'OR', 'gdd')"
+ gdd -> "('vth', 'OR', 'gdd')"
+ "('y08', 'XOR', 'x08')" -> rjs
+ "('y42', 'XOR', 'x42')" -> cng
+ "('x35', 'AND', 'y35')" -> qtv
+ x35 -> "('x35', 'AND', 'y35')"
+ x35 -> "('x35', 'XOR', 'y35')"
+ y35 -> "('x35', 'AND', 'y35')"
+ y35 -> "('x35', 'XOR', 'y35')"
+ "('y02', 'XOR', 'x02')" -> rvm
+ y02 -> "('y02', 'XOR', 'x02')"
+ y02 -> "('x02', 'AND', 'y02')"
+ x02 -> "('y02', 'XOR', 'x02')"
+ x02 -> "('x02', 'AND', 'y02')"
+ "('mcp', 'AND', 'mkf')" -> mmk
+ "('y28', 'AND', 'x28')" -> rsv
+ y28 -> "('y28', 'AND', 'x28')"
+ y28 -> "('x28', 'XOR', 'y28')"
+ x28 -> "('y28', 'AND', 'x28')"
+ x28 -> "('x28', 'XOR', 'y28')"
+ "('wfm', 'OR', 'mts')" -> wfc
+ wfm -> "('wfm', 'OR', 'mts')"
+ mts -> "('wfm', 'OR', 'mts')"
+ "('wnt', 'OR', 'hfc')" -> dts
+ wnt -> "('wnt', 'OR', 'hfc')"
+ hfc -> "('wnt', 'OR', 'hfc')"
+ "('sgf', 'AND', 'rms')" -> mrg
+ "('bbr', 'OR', 'ncf')" -> mwt
+ bbr -> "('bbr', 'OR', 'ncf')"
+ ncf -> "('bbr', 'OR', 'ncf')"
+ "('wpb', 'XOR', 'kbb')" -> z09
+ "('x06', 'XOR', 'y06')" -> jtg
+ x06 -> "('x06', 'XOR', 'y06')"
+ x06 -> "('x06', 'AND', 'y06')"
+ y06 -> "('x06', 'XOR', 'y06')"
+ y06 -> "('x06', 'AND', 'y06')"
+ "('sbw', 'OR', 'bfn')" -> jmv
+ sbw -> "('sbw', 'OR', 'bfn')"
+ bfn -> "('sbw', 'OR', 'bfn')"
+ "('kmr', 'XOR', 'rmb')" -> z10
+ kmr -> "('kmr', 'XOR', 'rmb')"
+ kmr -> "('rmb', 'AND', 'kmr')"
+ rmb -> "('kmr', 'XOR', 'rmb')"
+ rmb -> "('rmb', 'AND', 'kmr')"
+ "('rvn', 'XOR', 'kbq')" -> z16
+ rvn -> "('rvn', 'XOR', 'kbq')"
+ rvn -> "('kbq', 'AND', 'rvn')"
+ kbq -> "('rvn', 'XOR', 'kbq')"
+ kbq -> "('kbq', 'AND', 'rvn')"
+ "('y09', 'XOR', 'x09')" -> kbb
+ y09 -> "('y09', 'XOR', 'x09')"
+ y09 -> "('y09', 'AND', 'x09')"
+ x09 -> "('y09', 'XOR', 'x09')"
+ x09 -> "('y09', 'AND', 'x09')"
+ "('gsk', 'XOR', 'fhk')" -> z43
+ gsk -> "('gsk', 'XOR', 'fhk')"
+ gsk -> "('gsk', 'AND', 'fhk')"
+ fhk -> "('gsk', 'XOR', 'fhk')"
+ fhk -> "('gsk', 'AND', 'fhk')"
+ "('y23', 'AND', 'x23')" -> fnc
+ "('y29', 'XOR', 'x29')" -> hvc
+ y29 -> "('y29', 'XOR', 'x29')"
+ y29 -> "('y29', 'AND', 'x29')"
+ x29 -> "('y29', 'XOR', 'x29')"
+ x29 -> "('y29', 'AND', 'x29')"
+ "('wwp', 'AND', 'bvr')" -> cgv
+ wwp -> "('wwp', 'AND', 'bvr')"
+ wwp -> "('wwp', 'XOR', 'bvr')"
+ bvr -> "('wwp', 'AND', 'bvr')"
+ bvr -> "('wwp', 'XOR', 'bvr')"
+ "('tnc', 'OR', 'dbj')" -> hks
+ tnc -> "('tnc', 'OR', 'dbj')"
+ dbj -> "('tnc', 'OR', 'dbj')"
+ "('tvf', 'XOR', 'cmb')" -> z27
+ tvf -> "('tvf', 'XOR', 'cmb')"
+ tvf -> "('cmb', 'AND', 'tvf')"
+ cmb -> "('tvf', 'XOR', 'cmb')"
+ cmb -> "('cmb', 'AND', 'tvf')"
+ "('bvw', 'XOR', 'hvn')" -> z20
+ bvw -> "('bvw', 'XOR', 'hvn')"
+ bvw -> "('bvw', 'AND', 'hvn')"
+ hvn -> "('bvw', 'XOR', 'hvn')"
+ hvn -> "('bvw', 'AND', 'hvn')"
+ "('x44', 'XOR', 'y44')" -> jsg
+ x44 -> "('x44', 'XOR', 'y44')"
+ x44 -> "('x44', 'AND', 'y44')"
+ y44 -> "('x44', 'XOR', 'y44')"
+ y44 -> "('x44', 'AND', 'y44')"
+ "('rsv', 'OR', 'dpr')" -> tsk
+ rsv -> "('rsv', 'OR', 'dpr')"
+ dpr -> "('rsv', 'OR', 'dpr')"
+ "('sqj', 'XOR', 'wts')" -> z38
+ "('x40', 'AND', 'y40')" -> bdn
+ x40 -> "('x40', 'AND', 'y40')"
+ x40 -> "('x40', 'XOR', 'y40')"
+ y40 -> "('x40', 'AND', 'y40')"
+ y40 -> "('x40', 'XOR', 'y40')"
+ "('qpc', 'AND', 'qmb')" -> trv
+ qpc -> "('qpc', 'AND', 'qmb')"
+ qpc -> "('qmb', 'XOR', 'qpc')"
+ qmb -> "('qpc', 'AND', 'qmb')"
+ qmb -> "('qmb', 'XOR', 'qpc')"
+ "('qvq', 'XOR', 'hns')" -> z18
+ qvq -> "('qvq', 'XOR', 'hns')"
+ qvq -> "('hns', 'AND', 'qvq')"
+ hns -> "('qvq', 'XOR', 'hns')"
+ hns -> "('hns', 'AND', 'qvq')"
+ "('x41', 'AND', 'y41')" -> ncf
+ "('qdn', 'OR', 'jhv')" -> fkq
+ qdn -> "('qdn', 'OR', 'jhv')"
+ jhv -> "('qdn', 'OR', 'jhv')"
+ "('y27', 'XOR', 'x27')" -> tvf
+ "('rvm', 'XOR', 'vdq')" -> z02
+ rvm -> "('rvm', 'XOR', 'vdq')"
+ rvm -> "('vdq', 'AND', 'rvm')"
+ vdq -> "('rvm', 'XOR', 'vdq')"
+ vdq -> "('vdq', 'AND', 'rvm')"
+ "('whf', 'XOR', 'fds')" -> z05
+ "('tmg', 'AND', 'rjs')" -> vth
+ tmg -> "('tmg', 'AND', 'rjs')"
+ tmg -> "('rjs', 'XOR', 'tmg')"
+ rjs -> "('tmg', 'AND', 'rjs')"
+ rjs -> "('rjs', 'XOR', 'tmg')"
+ "('y34', 'AND', 'x34')" -> bnw
+ y34 -> "('y34', 'AND', 'x34')"
+ y34 -> "('x34', 'XOR', 'y34')"
+ x34 -> "('y34', 'AND', 'x34')"
+ x34 -> "('x34', 'XOR', 'y34')"
+ "('y21', 'AND', 'x21')" -> nrg
+ "('gsk', 'AND', 'fhk')" -> tnc
+ "('x38', 'XOR', 'y38')" -> sqj
+ "('y18', 'AND', 'x18')" -> wfm
+ y18 -> "('y18', 'AND', 'x18')"
+ y18 -> "('x18', 'XOR', 'y18')"
+ x18 -> "('y18', 'AND', 'x18')"
+ x18 -> "('x18', 'XOR', 'y18')"
+ "('hvc', 'AND', 'tsk')" -> bfp
+ hvc -> "('hvc', 'AND', 'tsk')"
+ hvc -> "('tsk', 'XOR', 'hvc')"
+ tsk -> "('hvc', 'AND', 'tsk')"
+ tsk -> "('tsk', 'XOR', 'hvc')"
+ "('jqf', 'OR', 'kjk')" -> kbq
+ jqf -> "('jqf', 'OR', 'kjk')"
+ kjk -> "('jqf', 'OR', 'kjk')"
+ "('dmp', 'AND', 'jkm')" -> qpw
+ "('x19', 'XOR', 'y19')" -> cmp
+ "('y24', 'XOR', 'x24')" -> gww
+ y24 -> "('y24', 'XOR', 'x24')"
+ y24 -> "('y24', 'AND', 'x24')"
+ x24 -> "('y24', 'XOR', 'x24')"
+ x24 -> "('y24', 'AND', 'x24')"
+ "('prp', 'AND', 'pfc')" -> rkh
+ prp -> "('prp', 'AND', 'pfc')"
+ prp -> "('pfc', 'XOR', 'prp')"
+ pfc -> "('prp', 'AND', 'pfc')"
+ pfc -> "('pfc', 'XOR', 'prp')"
+ "('rmb', 'AND', 'kmr')" -> fws
+ "('nnq', 'OR', 'bdn')" -> gfd
+ nnq -> "('nnq', 'OR', 'bdn')"
+ bdn -> "('nnq', 'OR', 'bdn')"
+ "('y39', 'XOR', 'x39')" -> vqf
+ y39 -> "('y39', 'XOR', 'x39')"
+ y39 -> "('y39', 'AND', 'x39')"
+ x39 -> "('y39', 'XOR', 'x39')"
+ x39 -> "('y39', 'AND', 'x39')"
+ "('qpm', 'XOR', 'csw')" -> z21
+ qpm -> "('qpm', 'XOR', 'csw')"
+ qpm -> "('csw', 'AND', 'qpm')"
+ csw -> "('qpm', 'XOR', 'csw')"
+ csw -> "('csw', 'AND', 'qpm')"
+ "('smt', 'XOR', 'wpp')" -> wts
+ smt -> "('smt', 'XOR', 'wpp')"
+ smt -> "('wpp', 'AND', 'smt')"
+ wpp -> "('smt', 'XOR', 'wpp')"
+ wpp -> "('wpp', 'AND', 'smt')"
+ "('x12', 'AND', 'y12')" -> bnn
+ "('x10', 'XOR', 'y10')" -> rmb
+ x10 -> "('x10', 'XOR', 'y10')"
+ x10 -> "('y10', 'AND', 'x10')"
+ y10 -> "('x10', 'XOR', 'y10')"
+ y10 -> "('y10', 'AND', 'x10')"
+ "('y33', 'XOR', 'x33')" -> wmq
+ "('x18', 'XOR', 'y18')" -> hns
+ "('vvs', 'OR', 'hpn')" -> cfn
+ vvs -> "('vvs', 'OR', 'hpn')"
+ hpn -> "('vvs', 'OR', 'hpn')"
+ "('jmf', 'AND', 'gww')" -> rjb
+ "('nrg', 'OR', 'mvs')" -> bvr
+ nrg -> "('nrg', 'OR', 'mvs')"
+ mvs -> "('nrg', 'OR', 'mvs')"
+ "('cmp', 'AND', 'wfc')" -> pbb
+ "('kbq', 'AND', 'rvn')" -> vtm
+ "('gfk', 'OR', 'dpv')" -> jth
+ gfk -> "('gfk', 'OR', 'dpv')"
+ dpv -> "('gfk', 'OR', 'dpv')"
+ "('y25', 'AND', 'x25')" -> cqg
+ "('wvt', 'AND', 'sbt')" -> dpv
+ "('cmb', 'AND', 'tvf')" -> mqr
+ "('hjp', 'XOR', 'kjs')" -> z01
+ "('y00', 'AND', 'x00')" -> hjp
+ "('x35', 'XOR', 'y35')" -> djt
+ "('mwt', 'AND', 'cng')" -> hbm
+ "('y24', 'AND', 'x24')" -> tcq
+ "('tsk', 'XOR', 'hvc')" -> z29
+ "('rkt', 'AND', 'skh')" -> kjk
+ "('jth', 'AND', 'jvf')" -> whn
+ "('x02', 'AND', 'y02')" -> nhp
+ "('hns', 'AND', 'qvq')" -> mts
+ "('y04', 'XOR', 'x04')" -> jvf
+ y04 -> "('y04', 'XOR', 'x04')"
+ y04 -> "('x04', 'AND', 'y04')"
+ x04 -> "('y04', 'XOR', 'x04')"
+ x04 -> "('x04', 'AND', 'y04')"
+ "('pfc', 'XOR', 'prp')" -> z25
+ "('y03', 'XOR', 'x03')" -> sbt
+ y03 -> "('y03', 'XOR', 'x03')"
+ y03 -> "('x03', 'AND', 'y03')"
+ x03 -> "('y03', 'XOR', 'x03')"
+ x03 -> "('x03', 'AND', 'y03')"
+ "('csw', 'AND', 'qpm')" -> mvs
+ "('y29', 'AND', 'x29')" -> bsw
+ "('wkb', 'AND', 'jkr')" -> hhj
+ "('x03', 'AND', 'y03')" -> gfk
+ "('vqf', 'XOR', 'fkq')" -> z39
+ vqf -> "('vqf', 'XOR', 'fkq')"
+ vqf -> "('vqf', 'AND', 'fkq')"
+ fkq -> "('vqf', 'XOR', 'fkq')"
+ fkq -> "('vqf', 'AND', 'fkq')"
+ "('x15', 'XOR', 'y15')" -> jqf
+ x15 -> "('x15', 'XOR', 'y15')"
+ x15 -> "('x15', 'AND', 'y15')"
+ y15 -> "('x15', 'XOR', 'y15')"
+ y15 -> "('x15', 'AND', 'y15')"
+ "('wpd', 'OR', 'dpf')" -> dtq
+ wpd -> "('wpd', 'OR', 'dpf')"
+ dpf -> "('wpd', 'OR', 'dpf')"
+ "('nrv', 'OR', 'jsp')" -> z45
+ nrv -> "('nrv', 'OR', 'jsp')"
+ jsp -> "('nrv', 'OR', 'jsp')"
+ "('jtg', 'AND', 'cfn')" -> qhk
+ jtg -> "('jtg', 'AND', 'cfn')"
+ jtg -> "('jtg', 'XOR', 'cfn')"
+ cfn -> "('jtg', 'AND', 'cfn')"
+ cfn -> "('jtg', 'XOR', 'cfn')"
+ "('rhd', 'OR', 'vtm')" -> wrc
+ rhd -> "('rhd', 'OR', 'vtm')"
+ vtm -> "('rhd', 'OR', 'vtm')"
+ "('y30', 'XOR', 'x30')" -> nnn
+ "('htn', 'AND', 'dtq')" -> gvh
+ htn -> "('htn', 'AND', 'dtq')"
+ htn -> "('htn', 'XOR', 'dtq')"
+ dtq -> "('htn', 'AND', 'dtq')"
+ dtq -> "('htn', 'XOR', 'dtq')"
+ "('y43', 'AND', 'x43')" -> dbj
+ "('x17', 'AND', 'y17')" -> cwn
+ "('htn', 'XOR', 'dtq')" -> z12
+ "('y20', 'AND', 'x20')" -> jgg
+ "('vdq', 'AND', 'rvm')" -> hmk
+ "('jgw', 'OR', 'rhh')" -> z37
+ jgw -> "('jgw', 'OR', 'rhh')"
+ rhh -> "('jgw', 'OR', 'rhh')"
+ "('jsg', 'XOR', 'hks')" -> z44
+ jsg -> "('jsg', 'XOR', 'hks')"
+ jsg -> "('jsg', 'AND', 'hks')"
+ hks -> "('jsg', 'XOR', 'hks')"
+ hks -> "('jsg', 'AND', 'hks')"
+ "('gns', 'OR', 'dwg')" -> sgf
+ gns -> "('gns', 'OR', 'dwg')"
+ dwg -> "('gns', 'OR', 'dwg')"
+ "('fqg', 'OR', 'wkq')" -> vdq
+ fqg -> "('fqg', 'OR', 'wkq')"
+ wkq -> "('fqg', 'OR', 'wkq')"
+ "('vqf', 'AND', 'fkq')" -> hwb
+ "('x04', 'AND', 'y04')" -> gwv
+ "('msf', 'XOR', 'kdd')" -> z28
+ "('rjs', 'XOR', 'tmg')" -> z08
+ "('x16', 'AND', 'y16')" -> rhd
+ "('x06', 'AND', 'y06')" -> hhw
+ "('gkc', 'AND', 'qqw')" -> z11
+ "('x28', 'XOR', 'y28')" -> kdd
+ "('fws', 'OR', 'gvj')" -> qqw
+ fws -> "('fws', 'OR', 'gvj')"
+ gvj -> "('fws', 'OR', 'gvj')"
+ "('y39', 'AND', 'x39')" -> ppk
+ "('rfq', 'AND', 'hbh')" -> pwb
+ "('y11', 'AND', 'x11')" -> dpf
+ y11 -> "('y11', 'AND', 'x11')"
+ y11 -> "('y11', 'XOR', 'x11')"
+ x11 -> "('y11', 'AND', 'x11')"
+ x11 -> "('y11', 'XOR', 'x11')"
+ "('x40', 'XOR', 'y40')" -> nns
+ "('hbm', 'OR', 'hnh')" -> gsk
+ hbm -> "('hbm', 'OR', 'hnh')"
+ hnh -> "('hbm', 'OR', 'hnh')"
+ "('y09', 'AND', 'x09')" -> csb
+ "('y37', 'XOR', 'x37')" -> wpp
+ y37 -> "('y37', 'XOR', 'x37')"
+ y37 -> "('y37', 'AND', 'x37')"
+ x37 -> "('y37', 'XOR', 'x37')"
+ x37 -> "('y37', 'AND', 'x37')"
+ "('hmk', 'OR', 'nhp')" -> wvt
+ hmk -> "('hmk', 'OR', 'nhp')"
+ nhp -> "('hmk', 'OR', 'nhp')"
+ "('x34', 'XOR', 'y34')" -> nss
+ "('rck', 'XOR', 'ftq')" -> z32
+ "('jsg', 'AND', 'hks')" -> nrv
+ "('y37', 'AND', 'x37')" -> rhh
+ "('wpp', 'AND', 'smt')" -> jgw
+ "('y11', 'XOR', 'x11')" -> gkc
+ "('x07', 'XOR', 'y07')" -> qpc
+ "('qpw', 'OR', 'rbg')" -> rhf
+ qpw -> "('qpw', 'OR', 'rbg')"
+ rbg -> "('qpw', 'OR', 'rbg')"
+ "('x15', 'AND', 'y15')" -> skh
+ "('y22', 'XOR', 'x22')" -> wwp
+ y22 -> "('y22', 'XOR', 'x22')"
+ y22 -> "('y22', 'AND', 'x22')"
+ x22 -> "('y22', 'XOR', 'x22')"
+ x22 -> "('y22', 'AND', 'x22')"
+ "('hhw', 'OR', 'qhk')" -> qmb
+ hhw -> "('hhw', 'OR', 'qhk')"
+ qhk -> "('hhw', 'OR', 'qhk')"
+ "('jmp', 'OR', 'csb')" -> kmr
+ jmp -> "('jmp', 'OR', 'csb')"
+ csb -> "('jmp', 'OR', 'csb')"
+ "('hbw', 'AND', 'wrc')" -> jks
+ "('x13', 'XOR', 'y13')" -> dmp
+ "('gwv', 'OR', 'whn')" -> whf
+ gwv -> "('gwv', 'OR', 'whn')"
+ whn -> "('gwv', 'OR', 'whn')"
+ "('dts', 'AND', 'wmq')" -> sbw
+ "('bnn', 'OR', 'gvh')" -> jkm
+ bnn -> "('bnn', 'OR', 'gvh')"
+ gvh -> "('bnn', 'OR', 'gvh')"
+ "('qmb', 'XOR', 'qpc')" -> z07
+ "('bvw', 'AND', 'hvn')" -> cmm
+ "('y10', 'AND', 'x10')" -> gvj
+ "('x44', 'AND', 'y44')" -> jsp
+ "('jtg', 'XOR', 'cfn')" -> z06
+ "('wwp', 'XOR', 'bvr')" -> z22
+ "('y22', 'AND', 'x22')" -> gmf
+}
\ No newline at end of file
diff --git a/aoc2024/test/day24/python/input.svg b/aoc2024/test/day24/python/input.svg
new file mode 100644
index 0000000..fa47f9e
--- /dev/null
+++ b/aoc2024/test/day24/python/input.svg
@@ -0,0 +1,7212 @@
+
+
+
+
+
diff --git a/aoc2024/test/day24/python/test_solution.py b/aoc2024/test/day24/python/test_solution.py
index 06d5b66..2159df1 100644
--- a/aoc2024/test/day24/python/test_solution.py
+++ b/aoc2024/test/day24/python/test_solution.py
@@ -14,7 +14,7 @@
import unittest
from common.python3.AdventOfCodeTestCase import AdventOfCodeTestCase
-from aoc2024.src.day24.python.solution import get_output
+from aoc2024.src.day24.python.solution import get_output, find_wrong_output_wires
class TestSolution(AdventOfCodeTestCase):
@@ -31,6 +31,26 @@ def test_part1_withExample2_success(self):
def test_part1_withPuzzleInput_success(self):
self.assertEqual(36035961805936, get_output(self.input))
+ def test_part2_withExample_success(self):
+ self.assertEqual('z00,z01,z02,z05', find_wrong_output_wires(self.examples[2],
+ swaps=(('z00', 'z05'),
+ ('z01', 'z02'))))
+
+ def test_part2_withPuzzleInput_success(self):
+ # The input is a Ripple Carry Adder!
+ # Output has 44 bits + carry.
+ # https://en.wikipedia.org/wiki/Adder_(electronics)#Ripple-carry_adder
+ # Generated Graphviz DOT and inspected the diagram looking for incorrect connections.
+ # Rules:
+ # 1. Signal z = (x XOR y) XOR Cin.
+ # 2. Cout = (x AND y) OR (Cin AND (x XOR y))
+ self.assertEqual('jqf,mdd,skh,wpd,wts,z11,z19,z37', find_wrong_output_wires(self.input,
+ swaps=(('z11', 'wpd'),
+ ('skh', 'jqf'),
+ ('z19', 'mdd'),
+ ('z37', 'wts')),
+ operation='+'))
+
if __name__ == '__main__':
unittest.main()