Skip to content

Commit

Permalink
2024/24 wip
Browse files Browse the repository at this point in the history
  • Loading branch information
encse committed Dec 24, 2024
1 parent 179666b commit e772f7a
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 47 deletions.
21 changes: 21 additions & 0 deletions 2024/Day24/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## --- Day 24: Crossed Wires ---
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.

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>).

_Visit the website for the full story and [full puzzle](https://adventofcode.com/2024/day/24) description._

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.

A single full adder consists of two half adders:

![half adder](halfadder.png)

Which are chained one after the other like this:

![full adder](adder.png)

I took the images from [build-electronic-circuits.com](https://www.build-electronic-circuits.com/full-adder/).

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
kind of errors which can be corrected by the fixer.
105 changes: 105 additions & 0 deletions 2024/Day24/Solution.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace AdventOfCode.Y2024.Day24;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

record struct Rule(string in1, string in2, string kind, string output);

[ProblemName("Crossed Wires")]
class Solution : Solver {

public object PartOne(string input) {
var gate = Parse(input);
var bits = gate.Keys.Where(k => k.StartsWith("z")).OrderByDescending(x => x).ToArray();
var res = 0L;
foreach (var b in bits) {
res = res * 2 + gate[b]();
}
return res;
}

public object PartTwo(string input) {
var swaps = Fix(ParseRules(input.Split("\n\n")[1]));
return string.Join(",", swaps.OrderBy(x => x));
}

// the rules should define a full adder for two 44 bit numbers
// this fixer is specific to my input.
IEnumerable<string> Fix(List<Rule> rules) {
var cin = Output(rules, "x00", "AND", "y00");
for (var i = 1; i < 45; i++) {
var x = $"x{i:D2}";
var y = $"y{i:D2}";
var z = $"z{i:D2}";

var xor1 = Output(rules, x, "XOR", y);
var and1 = Output(rules, x, "AND", y);

var and2 = Output(rules, cin, "AND", xor1);
var xor2 = Output(rules, cin, "XOR", xor1);

if (xor2 == null && and2 == null) {
return Swap(rules, xor1, and1);
}

var carry = Output(rules, and1, "OR", and2);
if (xor2 != z) {
return Swap(rules,z,xor2);
} else {
cin = carry;
}
}
return [];
}

string Output(IEnumerable<Rule> rules, string x, string gate, string y) =>
rules.SingleOrDefault(rule =>
(rule.in1 == x && rule.kind == gate && rule.in2 == y) ||
(rule.in1 == y && rule.kind == gate && rule.in2 == x)
).output;

IEnumerable<string> Swap(List<Rule> rules, string out1, string out2) {
rules = rules.Select(rule =>
rule.output == out1 ? rule with {output = out2} :
rule.output == out2 ? rule with {output = out1} :
rule
).ToList();

return Fix(rules).Concat([out1, out2]);
}

List<Rule> ParseRules(string input) => input
.Split("\n")
.Select(line => {
var parts = line.Split(" ");
return new Rule(in1: parts[0], in2: parts[2], kind: parts[1], output: parts[4]);
})
.ToList();
Dictionary<string, Gate> Parse(string input) {

var res = new Dictionary<string, Gate>();

var blocks = input.Split("\n\n");

foreach (var line in blocks[0].Split("\n")) {
var parts = line.Split(": ");
res.Add(parts[0], () => int.Parse(parts[1]));
}

foreach (var line in blocks[1].Split("\n")) {
var parts = Regex.Matches(line, "[a-zA-z0-9]+").Select(m => m.Value).ToArray();
Gate gate = (parts[0], parts[1], parts[2]) switch {
(var in1, "AND", var in2) => () => res[in1]() & res[in2](),
(var in1, "OR", var in2) => () => res[in1]() | res[in2](),
(var in1, "XOR", var in2) => () => res[in1]() ^ res[in2](),
_ => throw new Exception(),
};
res.Add(parts[3], gate);
}
return res;
}

delegate int Gate();
}
Binary file added 2024/Day24/adder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 2024/Day24/halfadder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 2024/Day24/input.in
Binary file not shown.
2 changes: 2 additions & 0 deletions 2024/Day24/input.refout
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
61495910098126
css,cwt,gdd,jmv,pqt,z05,z09,z37
79 changes: 48 additions & 31 deletions 2024/SplashScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public void Show() {

var color = Console.ForegroundColor;
Write(0xcc00, false, " ▄█▄ ▄▄█ ▄ ▄ ▄▄▄ ▄▄ ▄█▄ ▄▄▄ ▄█ ▄▄ ▄▄▄ ▄▄█ ▄▄▄\n █▄█ █ █ █ █ █▄█ █ █ █ █ █ █▄ ");
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ $year = 2024\n ");
Write(0xcc00, false, "\n ");
Write(0xcc00, false, " █ █ █ █ █ █▄█\n █ █ █▄█ ▀▄▀ █▄▄ █ █ █▄ █▄█ █ █▄ █▄█ █▄█ █▄▄ int y = 2024;\n ");
Write(0xcc00, false, " \n ");
Write(0x888888, false, " .-----. .------------------. \n ");
Write(0xcccccc, false, ".--'");
Write(0xe3b585, false, "~ ~ ~");
Expand Down Expand Up @@ -49,9 +49,9 @@ public void Show() {
Write(0xcccccc, false, "| 3 ");
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "|");
Write(0x427322, false, "@");
Write(0x427322, false, "#");
Write(0x5eabb4, false, "..");
Write(0x1461f, false, "@");
Write(0x1461f, false, "#");
Write(0xe3b585, false, "'. ~ ");
Write(0xcc00, false, "\" ' ");
Write(0xe3b585, false, "~ ");
Expand All @@ -70,7 +70,8 @@ public void Show() {
Write(0xcccccc, false, "|");
Write(0x427322, false, "_");
Write(0x5eabb4, false, ".~.");
Write(0x4d8b03, false, "_@");
Write(0x7fbd39, false, "_");
Write(0x488813, false, "@");
Write(0xe3b585, false, "'.. ~ ~ ");
Write(0xffff66, true, "*");
Write(0xcccccc, false, "| | ");
Expand All @@ -83,9 +84,9 @@ public void Show() {
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "| ");
Write(0xffffff, false, "||| ");
Write(0x1461f, false, "@");
Write(0x427322, false, "@");
Write(0x7fbd39, false, "@");
Write(0x427322, false, "@");
Write(0x488813, false, "@");
Write(0x4d8b03, false, "@");
Write(0xe3b585, false, "'''...");
Write(0xcccccc, false, "| |");
Expand All @@ -97,13 +98,13 @@ public void Show() {
Write(0xcccccc, false, "| 6 ");
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "|");
Write(0x427322, false, "#");
Write(0xffffff, false, "~~~");
Write(0x488813, false, "@#@");
Write(0x1461f, false, "@");
Write(0x4d8b03, false, "# ");
Write(0xffffff, false, "~~~");
Write(0x7fbd39, false, "@");
Write(0x488813, false, "@ ");
Write(0x488813, false, "#");
Write(0x427322, false, "# @ ");
Write(0x4d8b03, false, "@@");
Write(0x1461f, false, "@ ");
Write(0xcccccc, false, "| |");
Write(0xa5a8af, false, "/\\ ");
Write(0xa25151, false, "''. ");
Expand Down Expand Up @@ -158,9 +159,9 @@ public void Show() {
Write(0xcccccc, false, "| |");
Write(0xa5a8af, false, "/\\ ");
Write(0xa25151, false, "..' ");
Write(0xcccccc, false, "| | ");
Write(0xffffff, false, ". ");
Write(0xb5ed, false, ". ");
Write(0xcccccc, false, "| |");
Write(0xb5ed, false, ". ");
Write(0xffffff, false, ". ");
Write(0xcccccc, false, "| 11 ");
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "| ");
Expand All @@ -171,26 +172,27 @@ public void Show() {
Write(0xffff66, true, ":");
Write(0x333333, false, "::");
Write(0xcccccc, false, "| | ");
Write(0xffffff, false, ". ");
Write(0xa2db, false, ". . ");
Write(0xffffff, false, ". ");
Write(0xa2db, false, "'");
Write(0xcccccc, false, "| 12 ");
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "|");
Write(0xffffff, false, "'. - -");
Write(0xcccccc, false, "| | ");
Write(0x333333, false, "::");
Write(0xcccccc, false, "| | ");
Write(0x333333, false, ". ::");
Write(0x9900, true, ":");
Write(0x333333, false, "::");
Write(0xcccccc, false, "| | ");
Write(0xcccccc, false, "| |");
Write(0x91cc, false, ". ");
Write(0xffffff, false, ".' ");
Write(0xcccccc, false, "| 13 ");
Write(0xffff66, false, "**\n ");
Write(0xcccccc, false, "|");
Write(0xcc00, false, "...");
Write(0xffffff, false, "'..''");
Write(0xcccccc, false, "| |");
Write(0xffffff, true, ". ");
Write(0x333333, false, ".:");
Write(0xffffff, true, ". ");
Write(0x333333, false, ":");
Write(0x9900, true, ":::");
Write(0x333333, false, ":");
Write(0xcccccc, false, "| |");
Expand Down Expand Up @@ -231,8 +233,7 @@ public void Show() {
Write(0x5555bb, false, "~ ");
Write(0xcc00, false, ":");
Write(0xcccccc, false, "| |");
Write(0x666666, false, " '. ");
Write(0x333333, false, ". ");
Write(0x666666, false, " '. ");
Write(0xcccccc, false, "| |");
Write(0x666666, false, "┬o┤ten├─");
Write(0xcccccc, false, "| 17 ");
Expand All @@ -241,7 +242,8 @@ public void Show() {
Write(0xcc00, false, "'..' .'");
Write(0xcccccc, false, "| |");
Write(0x666666, false, " '");
Write(0x456efe, true, "o ");
Write(0x456efe, true, "o");
Write(0x333333, false, ". .");
Write(0xcccccc, false, "| |");
Write(0x666666, false, "┘");
Write(0xffff66, true, "*");
Expand All @@ -252,9 +254,7 @@ public void Show() {
Write(0x5555bb, false, "~ ");
Write(0xcc00, false, "..' ");
Write(0xcccccc, false, "| |");
Write(0x666666, false, ":");
Write(0x333333, false, ".");
Write(0x666666, false, " '. ");
Write(0x666666, false, ": '. ");
Write(0xcccccc, false, "| |");
Write(0x666666, false, "─┘├┬┬┬┴─");
Write(0xcccccc, false, "| 19 ");
Expand Down Expand Up @@ -295,7 +295,9 @@ public void Show() {
Write(0xff0000, false, ".---_ ");
Write(0x66ff, false, "'------'_ ");
Write(0xaaaaaa, false, ".~' ");
Write(0xcccccc, false, "| | |");
Write(0xcccccc, false, "| | ");
Write(0x333333, false, ".");
Write(0xcccccc, false, "|");
Write(0xff0000, false, "\\|");
Write(0x9900ff, false, "\\ / \\ /");
Write(0x333399, false, "~ ");
Expand Down Expand Up @@ -328,8 +330,23 @@ public void Show() {
Write(0xff9900, true, "o");
Write(0xcccccc, false, "| 23 ");
Write(0xffff66, false, "**\n ");
Write(0x333333, false, "| | | | ");
Write(0x666666, false, "24\n 25\n \n");
Write(0xcccccc, false, "|");
Write(0x880000, false, "/ | ");
Write(0xff0000, false, "\\ ");
Write(0xffff66, true, "*");
Write(0x66ff, false, "| |/");
Write(0xaaaaaa, false, "/ ");
Write(0xe6410b, false, "/ ");
Write(0xaaaaaa, false, "\\ ");
Write(0xcccccc, false, "| | ");
Write(0x9b715b, false, "----@ ");
Write(0xaaaaaa, false, "_");
Write(0xd0b376, false, "|%%%=%%|");
Write(0xaaaaaa, false, "_ ");
Write(0xcccccc, false, "| 24 ");
Write(0xffff66, false, "**\n ");
Write(0x333333, false, "| | '-. .-' ");
Write(0x666666, false, "25\n \n");

Console.ForegroundColor = color;
Console.WriteLine();
Expand Down
Loading

0 comments on commit e772f7a

Please sign in to comment.