diff --git a/AdventOfCode/Problems/AOC2024/Day11/PlutonianPebbles.cs b/AdventOfCode/Problems/AOC2024/Day11/PlutonianPebbles.cs index 249a876..4969765 100644 --- a/AdventOfCode/Problems/AOC2024/Day11/PlutonianPebbles.cs +++ b/AdventOfCode/Problems/AOC2024/Day11/PlutonianPebbles.cs @@ -1,25 +1,94 @@ -using System; +using Superpower.Model; + +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; + namespace AdventOfCode.Problems.AOC2024.Day11; -//[ProblemInfo(2024, 11, "Plutonian Pebbles")] -internal class PlutonianPebbles : Problem + +[ProblemInfo(2024, 11, "Plutonian Pebbles")] +public class PlutonianPebbles : Problem { + private List _data = []; + public override void CalculatePart1() { - throw new NotImplementedException(); + Part1 = Run(25); } public override void CalculatePart2() { - throw new NotImplementedException(); + //Runs into max array length limit + Part2 = Run(75); + } + + public long Run(long count) + { + var a = _data.ToList(); + var b = new List(a.Count); + for (long i = 0; i < count; i++) + { + foreach (var stone in a) + ProcessStone(stone, b); + + (a, b) = (b, a); + b.Clear(); + } + return a.Count; + } + + public static void ProcessStone(long stone, List data) + { + if (stone == 0) + { + data.Add(1); + return; + } + if (FastSplit(stone, out var left, out var right)) + { + data.Add(left); + data.Add(right); + return; + } + data.Add(stone * 2024); + } + + private static IEnumerable Split(long stone, int len) + { + var v = stone.ToString(); + return [long.Parse(v[..(len / 2)]), long.Parse(v[(len / 2)..])]; + } + + private static bool FastSplit(long stone, out long left, out long right) + { + var len = stone.DigitCount(); + if (len % 2 != 0) + { + left = 0; + right = 0; + return false; + } + var l = QuickMath.FastPow10(len / 2); + var a = stone / l; + + (left, right) = (a, stone - (a * l)); + return true; + + } + + private static bool IsEvenDigits(long value, out int len) + { + var v = len = value.ToString().Length; + return v % 2 == 0; } public override void LoadInput() { - throw new NotImplementedException(); + _data = ReadInputText("input.txt").Split(' ').Select(long.Parse).ToList(); } -} +} \ No newline at end of file diff --git a/AdventOfCode/Utils/QuickMath.cs b/AdventOfCode/Utils/QuickMath.cs new file mode 100644 index 0000000..12a8c67 --- /dev/null +++ b/AdventOfCode/Utils/QuickMath.cs @@ -0,0 +1,37 @@ +namespace AdventOfCode.Utils; + +public static class QuickMath +{ + private static readonly long[] pow10Long = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000]; + private static readonly int[] pow10int = [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000]; + + public static long FastPow10(long exp) + { + return pow10Long[exp]; + } + + public static int FastPow10(int exp) + { + return pow10int[exp]; + } + + private static readonly long[] longCorrectionTable= [9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, 9999999999, 99999999999, 999999999999, 9999999999999, 99999999999999, 999999999999999, 9999999999999999, 99999999999999999, 999999999999999999]; + private static readonly int[] intCorrectionTable = [9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999]; + public static long DigitCount(this long value) + { + var l2 = 63 - long.LeadingZeroCount(value | 1); + var ans = ((9 * l2) >> 5); + if (value > longCorrectionTable[ans]) + ans += 1; + return ans + 1; + } + + public static int DigitCount(this int value) + { + var l2 = 31 - int.LeadingZeroCount(value | 1); + var ans = ((9 * l2) >> 5); + if (value > intCorrectionTable[ans]) + ans += 1; + return ans + 1; + } +} \ No newline at end of file