From 9286bf011284339d5a6cd2effe5704c55ba6cf7f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 24 Dec 2024 10:23:58 +0000 Subject: [PATCH] Update docs on Tue Dec 24 10:23:58 UTC 2024 --- 2024/24/index.html | 98 ++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/2024/24/index.html b/2024/24/index.html index cabc6a4d..912bf36a 100644 --- a/2024/24/index.html +++ b/2024/24/index.html @@ -297,49 +297,64 @@

Crossed Wires

using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Circuit = System.Collections.Generic.Dictionary<string, Gate>; -record struct Rule(string in1, string in2, string kind, string output); +record struct Gate(string in1, string kind, string in2); [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 (inputs, circuit) = Parse(input); + + var outputs = from label in circuit.Keys where label.StartsWith("z") select label; + var res = 0L; - foreach (var b in bits) { - res = res * 2 + gate[b](); + foreach (var label in outputs.OrderByDescending(label=>label)) { + res = res * 2 + Evaluate(label, circuit, inputs); } return res; } + int Evaluate(string label, Circuit circuit, Dictionary<string, int> inputs) { + if (inputs.TryGetValue(label, out var res)) { + return res; + } else { + return circuit[label] switch { + Gate(var in1, "AND", var in2) => Evaluate(in1, circuit, inputs) & Evaluate(in2, circuit, inputs), + Gate(var in1, "OR", var in2) => Evaluate(in1, circuit, inputs) | Evaluate(in2, circuit, inputs), + Gate(var in1, "XOR", var in2) => Evaluate(in1, circuit, inputs) ^ Evaluate(in2, circuit, inputs), + _ => throw new Exception(circuit[label].ToString()), + }; + } + } + public object PartTwo(string input) { - var swaps = Fix(ParseRules(input.Split("\n\n")[1])); - return string.Join(",", swaps.OrderBy(x => x)); + var circuit = Parse(input).circuit; + return string.Join(",", Fix(circuit).OrderBy(label => label)); } - // the rules should define a full adder for two 44 bit numbers + // the circuit 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"); + IEnumerable<string> Fix(Circuit circuit) { + var cin = Output(circuit, "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); + var xor1 = Output(circuit, x, "XOR", y); + var and1 = Output(circuit, x, "AND", y); + var xor2 = Output(circuit, cin, "XOR", xor1); + var and2 = Output(circuit, cin, "AND", xor1); if (xor2 == null && and2 == null) { - return Swap(rules, xor1, and1); + return SwapAndFix(circuit, xor1, and1); } - var carry = Output(rules, and1, "OR", and2); + var carry = Output(circuit, and1, "OR", and2); if (xor2 != z) { - return Swap(rules,z,xor2); + return SwapAndFix(circuit, z, xor2); } else { cin = carry; } @@ -347,54 +362,35 @@

Crossed Wires

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]); + IEnumerable<string> SwapAndFix(Circuit circuit, string out1, string out2) { + (circuit[out1], circuit[out2]) = (circuit[out2], circuit[out1]); + return Fix(circuit).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) { + string Output(Circuit circuit, string x, string kind, string y) => + circuit.SingleOrDefault(pair => + (pair.Value.in1 == x && pair.Value.kind == kind && pair.Value.in2 == y) || + (pair.Value.in1 == y && pair.Value.kind == kind && pair.Value.in2 == x) + ).Key; - var res = new Dictionary<string, Gate>(); + (Dictionary<string, int> inputs, Circuit circuit) Parse(string input) { + var inputs = new Dictionary<string, int>(); + var circuit = new Circuit(); 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])); + inputs.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); + circuit.Add(parts[3], new Gate(in1: parts[0], kind: parts[1], in2: parts[2])); } - return res; + return (inputs, circuit); } - delegate int Gate(); }

Please ☆ my repo if you like it!