#pragma warning disable CS8600 //OH MY GOD SHUT UP #pragma warning disable CS8602 #pragma warning disable CS8604 class Program { static void Main() { var input = File.ReadAllLines(@"../../../../Input.in"); var thing = Snail.Run(input); Console.WriteLine("The magnitude after addition is " + thing.Item1.ToString()); Console.WriteLine("The largest magnitude obtainable with an addition pair is " + thing.Item2.ToString()); } } public class Snail { public Snail(int val, int level) { Value = val; Level = level; } public int Value { get; set; } public int Level { get; init; } public static (long, long) Run(string[] input) { IEnumerable<Snail> Parse(string line) { int level = 0; foreach (var c in line) { level += c == '[' ? 1 : c == ']' ? -1 : 0; if (char.IsDigit(c)) yield return new Snail(int.Parse(c.ToString()), level); } } LinkedListNode<Snail> Collapse(LinkedList<Snail> num, LinkedListNode<Snail> node, int val) { var newNode = new LinkedListNode<Snail>(new Snail(val, node.Value.Level - 1)); num.AddBefore(node, newNode); num.Remove(node.Next); num.Remove(node); return newNode; } LinkedList<Snail> Reduce(LinkedList<Snail> num) { Snail bob; do { bob = num.FirstOrDefault(n => n.Level > 4); if (bob != null) { var node = num.Find(bob); if (node.Previous != null) node.Previous.Value.Value += node.Value.Value; if (node.Next.Next != null) node.Next.Next.Value.Value += node.Next.Value.Value; node = Collapse(num, node, 0); continue; } bob = num.FirstOrDefault(n => n.Value > 9); if (bob != null) { var node = num.Find(bob); num.AddBefore(node, new Snail(node.Value.Value / 2, node.Value.Level + 1)); num.AddBefore(node, new Snail(node.Value.Value - (node.Value.Value / 2), node.Value.Level + 1)); num.Remove(node); } } while (bob != null); return num; } LinkedList<Snail> Add(LinkedList<Snail> num, LinkedList<Snail> next) => Reduce(new LinkedList<Snail>(num.Union(next).Select(s => new Snail(s.Value, s.Level + 1)))); long Magnitude(LinkedList<Snail> num) { while (num.Count > 1) { var level = num.Max(n => n.Level); for (var node = num.First; node != null && node.Next != null; node = node.Next) if (node.Value.Level == node.Next.Value.Level && node.Value.Level == level) node = Collapse(num, node, node.Value.Value * 3 + node.Next.Value.Value * 2); } return num.First.Value.Value; } var nums = input.Select(line => new LinkedList<Snail>(Parse(line))).ToList(); var sum = nums.Skip(1).Aggregate(nums.First(), (acc, next) => Add(acc, next)); var sums = from a in nums from b in nums where a != b select Magnitude(Add(a, b)); return (Magnitude(sum), sums.Max()); } }