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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy