Day 13: Claw Contraption
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
C#
Thank goodness for high school algebra!
using System.Diagnostics; using Common; namespace Day13; static class Program { static void Main() { var start = Stopwatch.GetTimestamp(); var sampleInput = Input.ParseInput("sample.txt"); var programInput = Input.ParseInput("input.txt"); Console.WriteLine($"Part 1 sample: {Part1(sampleInput)}"); Console.WriteLine($"Part 1 input: {Part1(programInput)}"); Console.WriteLine($"Part 2 sample: {Part2(sampleInput)}"); Console.WriteLine($"Part 2 input: {Part2(programInput)}"); Console.WriteLine($"That took about {Stopwatch.GetElapsedTime(start)}"); } static object Part1(Input i) => i.Machines .Select(m => CalculateCoins(m, 100)) .Where(c => c > 0) .Sum(); static object Part2(Input i) => i.Machines .Select(m => m with { Prize = new XYValues( m.Prize.X + 10000000000000, m.Prize.Y + 10000000000000) }) .Select(m => CalculateCoins(m, long.MaxValue)) .Where(c => c > 0) .Sum(); static long CalculateCoins(Machine m, long limit) { var bBottom = (m.A.X * m.B.Y) - (m.A.Y * m.B.X); if (bBottom == 0) return -1; var bTop = (m.Prize.Y * m.A.X) - (m.Prize.X * m.A.Y); var b = bTop / bBottom; if ((b <= 0) || (b > limit)) return -1; var a = (m.Prize.X - (b * m.B.X)) / m.A.X; if ((a <= 0) || (a > limit)) return -1; var calcPrizeX = (a * m.A.X) + (b * m.B.X); var calcPrizeY = (a * m.A.Y) + (b * m.B.Y); if ((m.Prize.X != calcPrizeX) || (m.Prize.Y != calcPrizeY)) return -1; return (3 * a) + b; } } public record struct Machine(XYValues A, XYValues B, XYValues Prize); public record struct XYValues(long X, long Y); public class Input { private Input() { } public List<Machine> Machines { get; init; } public static Input ParseInput(string file) { var machines = new List<Machine>(); var lines = File.ReadAllLines(file); for(int l=0; l<lines.Length; l+=4) { machines.Add(new Machine( ParseXYValues(lines[l + 0]), ParseXYValues(lines[l + 1]), ParseXYValues(lines[l + 2]))); } return new Input() { Machines = machines, }; } private static readonly char[] XYDelimiters = ['X', 'Y', '=', '+', ',', ' ']; private static XYValues ParseXYValues(string s) { var parts = s .Substring(s.IndexOf(':') + 1) .SplitAndTrim(XYDelimiters) .Select(long.Parse) .ToArray(); return new XYValues(parts[0], parts[1]); } }