Skip to content

Commit e772f7a

Browse files
committed
2024/24 wip
1 parent 179666b commit e772f7a

File tree

8 files changed

+192
-47
lines changed

8 files changed

+192
-47
lines changed

2024/Day24/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## --- Day 24: Crossed Wires ---
2+
You and The Historians arrive at the edge of a [large grove](/2022/day/23) somewhere in the jungle. After the last incident, the Elves installed a small device that monitors the fruit. While The Historians search the grove, one of them asks if you can take a look at the monitoring device; apparently, it's been malfunctioning recently.
3+
4+
The device seems to be trying to produce a number through some boolean logic gates. Each gate has two inputs and one output. The gates all operate on values that are either <em>true</em> (<code>1</code>) or <em>false</em> (<code>0</code>).
5+
6+
_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/24) description._
7+
8+
The first half of the problem was a familiar logic circuit evaluator, we have done this before. I really liked the second part, although I don't have a super generic solution for it. I generated a graph from my input using Graphviz, then realized that the circuit tries to implement a full adder.
9+
10+
A single full adder consists of two half adders:
11+
12+
![half adder](halfadder.png)
13+
14+
Which are chained one after the other like this:
15+
16+
![full adder](adder.png)
17+
18+
I took the images from [build-electronic-circuits.com](https://www.build-electronic-circuits.com/full-adder/).
19+
20+
I implemented this logic in my 'fix' method. I start with the output x01 and y01 and try to identify the gates for the individual steps. Where I found an error, I manually checked my input to figure out what went wrong. I had just two different
21+
kind of errors which can be corrected by the fixer.

2024/Day24/Solution.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
namespace AdventOfCode.Y2024.Day24;
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text.RegularExpressions;
7+
8+
record struct Rule(string in1, string in2, string kind, string output);
9+
10+
[ProblemName("Crossed Wires")]
11+
class Solution : Solver {
12+
13+
public object PartOne(string input) {
14+
var gate = Parse(input);
15+
var bits = gate.Keys.Where(k => k.StartsWith("z")).OrderByDescending(x => x).ToArray();
16+
var res = 0L;
17+
foreach (var b in bits) {
18+
res = res * 2 + gate[b]();
19+
}
20+
return res;
21+
}
22+
23+
public object PartTwo(string input) {
24+
var swaps = Fix(ParseRules(input.Split("\n\n")[1]));
25+
return string.Join(",", swaps.OrderBy(x => x));
26+
}
27+
28+
// the rules should define a full adder for two 44 bit numbers
29+
// this fixer is specific to my input.
30+
IEnumerable<string> Fix(List<Rule> rules) {
31+
var cin = Output(rules, "x00", "AND", "y00");
32+
for (var i = 1; i < 45; i++) {
33+
var x = $"x{i:D2}";
34+
var y = $"y{i:D2}";
35+
var z = $"z{i:D2}";
36+
37+
var xor1 = Output(rules, x, "XOR", y);
38+
var and1 = Output(rules, x, "AND", y);
39+
40+
var and2 = Output(rules, cin, "AND", xor1);
41+
var xor2 = Output(rules, cin, "XOR", xor1);
42+
43+
if (xor2 == null && and2 == null) {
44+
return Swap(rules, xor1, and1);
45+
}
46+
47+
var carry = Output(rules, and1, "OR", and2);
48+
if (xor2 != z) {
49+
return Swap(rules,z,xor2);
50+
} else {
51+
cin = carry;
52+
}
53+
}
54+
return [];
55+
}
56+
57+
string Output(IEnumerable<Rule> rules, string x, string gate, string y) =>
58+
rules.SingleOrDefault(rule =>
59+
(rule.in1 == x && rule.kind == gate && rule.in2 == y) ||
60+
(rule.in1 == y && rule.kind == gate && rule.in2 == x)
61+
).output;
62+
63+
IEnumerable<string> Swap(List<Rule> rules, string out1, string out2) {
64+
rules = rules.Select(rule =>
65+
rule.output == out1 ? rule with {output = out2} :
66+
rule.output == out2 ? rule with {output = out1} :
67+
rule
68+
).ToList();
69+
70+
return Fix(rules).Concat([out1, out2]);
71+
}
72+
73+
List<Rule> ParseRules(string input) => input
74+
.Split("\n")
75+
.Select(line => {
76+
var parts = line.Split(" ");
77+
return new Rule(in1: parts[0], in2: parts[2], kind: parts[1], output: parts[4]);
78+
})
79+
.ToList();
80+
Dictionary<string, Gate> Parse(string input) {
81+
82+
var res = new Dictionary<string, Gate>();
83+
84+
var blocks = input.Split("\n\n");
85+
86+
foreach (var line in blocks[0].Split("\n")) {
87+
var parts = line.Split(": ");
88+
res.Add(parts[0], () => int.Parse(parts[1]));
89+
}
90+
91+
foreach (var line in blocks[1].Split("\n")) {
92+
var parts = Regex.Matches(line, "[a-zA-z0-9]+").Select(m => m.Value).ToArray();
93+
Gate gate = (parts[0], parts[1], parts[2]) switch {
94+
(var in1, "AND", var in2) => () => res[in1]() & res[in2](),
95+
(var in1, "OR", var in2) => () => res[in1]() | res[in2](),
96+
(var in1, "XOR", var in2) => () => res[in1]() ^ res[in2](),
97+
_ => throw new Exception(),
98+
};
99+
res.Add(parts[3], gate);
100+
}
101+
return res;
102+
}
103+
104+
delegate int Gate();
105+
}

2024/Day24/adder.png

8.39 KB
Loading

2024/Day24/halfadder.png

6.78 KB
Loading

2024/Day24/input.in

4.71 KB
Binary file not shown.

2024/Day24/input.refout

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
61495910098126
2+
css,cwt,gdd,jmv,pqt,z05,z09,z37

2024/SplashScreen.cs

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ public void Show() {
88

99
var color = Console.ForegroundColor;
1010
Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ ");
11-
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2024\n ");
12-
Write(0xcc00, false, "\n ");
11+
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ int y = 2024;\n ");
12+
Write(0xcc00, false, " \n ");
1313
Write(0x888888, false, " .-----. .------------------. \n ");
1414
Write(0xcccccc, false, ".--'");
1515
Write(0xe3b585, false, "~ ~ ~");
@@ -49,9 +49,9 @@ public void Show() {
4949
Write(0xcccccc, false, "| 3 ");
5050
Write(0xffff66, false, "**\n ");
5151
Write(0xcccccc, false, "|");
52-
Write(0x427322, false, "@");
52+
Write(0x427322, false, "#");
5353
Write(0x5eabb4, false, "..");
54-
Write(0x1461f, false, "@");
54+
Write(0x1461f, false, "#");
5555
Write(0xe3b585, false, "'. ~ ");
5656
Write(0xcc00, false, "\" ' ");
5757
Write(0xe3b585, false, "~ ");
@@ -70,7 +70,8 @@ public void Show() {
7070
Write(0xcccccc, false, "|");
7171
Write(0x427322, false, "_");
7272
Write(0x5eabb4, false, ".~.");
73-
Write(0x4d8b03, false, "_@");
73+
Write(0x7fbd39, false, "_");
74+
Write(0x488813, false, "@");
7475
Write(0xe3b585, false, "'.. ~ ~ ");
7576
Write(0xffff66, true, "*");
7677
Write(0xcccccc, false, "| | ");
@@ -83,9 +84,9 @@ public void Show() {
8384
Write(0xffff66, false, "**\n ");
8485
Write(0xcccccc, false, "| ");
8586
Write(0xffffff, false, "||| ");
86-
Write(0x1461f, false, "@");
87-
Write(0x427322, false, "@");
8887
Write(0x7fbd39, false, "@");
88+
Write(0x427322, false, "@");
89+
Write(0x488813, false, "@");
8990
Write(0x4d8b03, false, "@");
9091
Write(0xe3b585, false, "'''...");
9192
Write(0xcccccc, false, "| |");
@@ -97,13 +98,13 @@ public void Show() {
9798
Write(0xcccccc, false, "| 6 ");
9899
Write(0xffff66, false, "**\n ");
99100
Write(0xcccccc, false, "|");
100-
Write(0x427322, false, "#");
101-
Write(0xffffff, false, "~~~");
102-
Write(0x488813, false, "@#@");
103101
Write(0x1461f, false, "@");
104-
Write(0x4d8b03, false, "# ");
102+
Write(0xffffff, false, "~~~");
105103
Write(0x7fbd39, false, "@");
106-
Write(0x488813, false, "@ ");
104+
Write(0x488813, false, "#");
105+
Write(0x427322, false, "# @ ");
106+
Write(0x4d8b03, false, "@@");
107+
Write(0x1461f, false, "@ ");
107108
Write(0xcccccc, false, "| |");
108109
Write(0xa5a8af, false, "/\\ ");
109110
Write(0xa25151, false, "''. ");
@@ -158,9 +159,9 @@ public void Show() {
158159
Write(0xcccccc, false, "| |");
159160
Write(0xa5a8af, false, "/\\ ");
160161
Write(0xa25151, false, "..' ");
161-
Write(0xcccccc, false, "| | ");
162-
Write(0xffffff, false, ". ");
163-
Write(0xb5ed, false, ". ");
162+
Write(0xcccccc, false, "| |");
163+
Write(0xb5ed, false, ". ");
164+
Write(0xffffff, false, ". ");
164165
Write(0xcccccc, false, "| 11 ");
165166
Write(0xffff66, false, "**\n ");
166167
Write(0xcccccc, false, "| ");
@@ -171,26 +172,27 @@ public void Show() {
171172
Write(0xffff66, true, ":");
172173
Write(0x333333, false, "::");
173174
Write(0xcccccc, false, "| | ");
174-
Write(0xffffff, false, ". ");
175-
Write(0xa2db, false, ". . ");
175+
Write(0xffffff, false, ". ");
176+
Write(0xa2db, false, "'");
176177
Write(0xcccccc, false, "| 12 ");
177178
Write(0xffff66, false, "**\n ");
178179
Write(0xcccccc, false, "|");
179180
Write(0xffffff, false, "'. - -");
180-
Write(0xcccccc, false, "| | ");
181-
Write(0x333333, false, "::");
181+
Write(0xcccccc, false, "| | ");
182+
Write(0x333333, false, ". ::");
182183
Write(0x9900, true, ":");
183184
Write(0x333333, false, "::");
184-
Write(0xcccccc, false, "| | ");
185+
Write(0xcccccc, false, "| |");
186+
Write(0x91cc, false, ". ");
185187
Write(0xffffff, false, ".' ");
186188
Write(0xcccccc, false, "| 13 ");
187189
Write(0xffff66, false, "**\n ");
188190
Write(0xcccccc, false, "|");
189191
Write(0xcc00, false, "...");
190192
Write(0xffffff, false, "'..''");
191193
Write(0xcccccc, false, "| |");
192-
Write(0xffffff, true, ". ");
193-
Write(0x333333, false, ".:");
194+
Write(0xffffff, true, ". ");
195+
Write(0x333333, false, ":");
194196
Write(0x9900, true, ":::");
195197
Write(0x333333, false, ":");
196198
Write(0xcccccc, false, "| |");
@@ -231,8 +233,7 @@ public void Show() {
231233
Write(0x5555bb, false, "~ ");
232234
Write(0xcc00, false, ":");
233235
Write(0xcccccc, false, "| |");
234-
Write(0x666666, false, " '. ");
235-
Write(0x333333, false, ". ");
236+
Write(0x666666, false, " '. ");
236237
Write(0xcccccc, false, "| |");
237238
Write(0x666666, false, "┬o┤ten├─");
238239
Write(0xcccccc, false, "| 17 ");
@@ -241,7 +242,8 @@ public void Show() {
241242
Write(0xcc00, false, "'..' .'");
242243
Write(0xcccccc, false, "| |");
243244
Write(0x666666, false, " '");
244-
Write(0x456efe, true, "o ");
245+
Write(0x456efe, true, "o");
246+
Write(0x333333, false, ". .");
245247
Write(0xcccccc, false, "| |");
246248
Write(0x666666, false, "┘");
247249
Write(0xffff66, true, "*");
@@ -252,9 +254,7 @@ public void Show() {
252254
Write(0x5555bb, false, "~ ");
253255
Write(0xcc00, false, "..' ");
254256
Write(0xcccccc, false, "| |");
255-
Write(0x666666, false, ":");
256-
Write(0x333333, false, ".");
257-
Write(0x666666, false, " '. ");
257+
Write(0x666666, false, ": '. ");
258258
Write(0xcccccc, false, "| |");
259259
Write(0x666666, false, "─┘├┬┬┬┴─");
260260
Write(0xcccccc, false, "| 19 ");
@@ -295,7 +295,9 @@ public void Show() {
295295
Write(0xff0000, false, ".---_ ");
296296
Write(0x66ff, false, "'------'_ ");
297297
Write(0xaaaaaa, false, ".~' ");
298-
Write(0xcccccc, false, "| | |");
298+
Write(0xcccccc, false, "| | ");
299+
Write(0x333333, false, ".");
300+
Write(0xcccccc, false, "|");
299301
Write(0xff0000, false, "\\|");
300302
Write(0x9900ff, false, "\\ / \\ /");
301303
Write(0x333399, false, "~ ");
@@ -328,8 +330,23 @@ public void Show() {
328330
Write(0xff9900, true, "o");
329331
Write(0xcccccc, false, "| 23 ");
330332
Write(0xffff66, false, "**\n ");
331-
Write(0x333333, false, "| | | | ");
332-
Write(0x666666, false, "24\n 25\n \n");
333+
Write(0xcccccc, false, "|");
334+
Write(0x880000, false, "/ | ");
335+
Write(0xff0000, false, "\\ ");
336+
Write(0xffff66, true, "*");
337+
Write(0x66ff, false, "| |/");
338+
Write(0xaaaaaa, false, "/ ");
339+
Write(0xe6410b, false, "/ ");
340+
Write(0xaaaaaa, false, "\\ ");
341+
Write(0xcccccc, false, "| | ");
342+
Write(0x9b715b, false, "----@ ");
343+
Write(0xaaaaaa, false, "_");
344+
Write(0xd0b376, false, "|%%%=%%|");
345+
Write(0xaaaaaa, false, "_ ");
346+
Write(0xcccccc, false, "| 24 ");
347+
Write(0xffff66, false, "**\n ");
348+
Write(0x333333, false, "| | '-. .-' ");
349+
Write(0x666666, false, "25\n \n");
333350

334351
Console.ForegroundColor = color;
335352
Console.WriteLine();

0 commit comments

Comments
 (0)