#define Day24 #if Day24 using System.Diagnostics; using AoC2021; var varPos = "wxyz"; var allOperations = File.ReadAllLines("day24/input") .Select(l => l.Split(" ")) .Select(parts => parts.Length == 2 ? new Operation(Enum.Parse(parts[0]), varPos.IndexOf(parts[1][0]), "do not use") : new Operation(Enum.Parse(parts[0]), varPos.IndexOf(parts[1][0]), parts[2]) ) .ToList(); var operationSections = new List>(); var curOperations = new List(); foreach (var op in allOperations) { if (op.op != Op.inp) { curOperations.Add(op); continue; } if (curOperations.Count == 0) { curOperations.Add(op); continue; } operationSections.Add(curOperations); curOperations = new List() { op }; } operationSections.Add(curOperations); operationSections.Reverse(); var starting = new ZW(0, "0"); var prev = new HashSet() {starting}; var sw = new Stopwatch(); sw.Start(); int countSections = 0; long maxZ = 0; foreach (var section in operationSections) { sw.Stop(); Console.WriteLine(sw.Elapsed); Console.WriteLine($"prev count: {prev.Count}"); sw.Restart(); Console.WriteLine($"countSections: {countSections++}"); var validZWMax = prev.GroupBy(x => x.z).ToDictionary(g => g.Key, g => g.MaxBy(x => long.Parse(x.w))); var validZWMin = prev.GroupBy(x => x.z).ToDictionary(g => g.Key, g => g.MinBy(x => long.Parse(x.w))); maxZ = Math.Max(maxZ, validZWMax.Keys.Max()); Console.WriteLine($"maxZ: {maxZ}"); Console.WriteLine($"cur maxZ: {validZWMax.Keys.Max()}"); var next = new HashSet(); if (section.Equals(operationSections.Last())) { // z has to be 0 in the last part for (int w = 1; w <= 9; w++) { var resultZ = CheckMonad(w.ToString(), 0, section); if (validZWMax.Keys.Contains(resultZ)) { next.Add(new ZW(0, w + validZWMax[resultZ].w)); next.Add(new ZW(0, w + validZWMin[resultZ].w)); } } prev = next; continue; } for (int initialZ = 0; initialZ < 10000000; initialZ++) { for (int w = 1; w <= 9; w++) { var resultZ = CheckMonad(w.ToString(), initialZ, section); if (validZWMax.Keys.Contains(resultZ)) { next.Add(new ZW(initialZ, w + validZWMax[resultZ].w)); next.Add(new ZW(initialZ, w + validZWMin[resultZ].w)); } } } prev = next; if (prev.Count == 0) { Console.WriteLine("something went wrong!"); } } sw.Stop(); Console.WriteLine(sw.Elapsed); Console.WriteLine($"maxZ: {maxZ}"); Console.WriteLine($"prev count: {prev.Count}"); prev.ToList().ForEach(Console.WriteLine); // for (int z = 0; z < 100000; z++) { // for (int j = 1; j <= 9; j++) { // var result = CheckMonad(j.ToString(), z, allOperations); // if (result >= 0 && result <= 6) { // Console.WriteLine($"z: {z}, w: {j}, res: {result}"); // } // } // } // for (int z = 0; z < 100000; z++) { // for (int j = 1; j <= 9; j++) { // for (int k = 1; k <= 9; k++) { // var result = CheckMonad(j.ToString() + k.ToString(), 0, allOperations); // if (result >= 0 && result <= 6) { // Console.WriteLine($"z: 0, w: {j}{k}, res: {result}"); // } // } // } // } // var result = CheckMonad("2"); // Console.WriteLine(result); // Console.WriteLine(CheckMonad("13579246899999")); // long count = 0; // for (long i = 99999999999999; i >= 11111111111111; i--) { // string iToCheck = i.ToString(); // if (iToCheck.Contains('0')) { // continue; // } // if (count % 100 == 0) { // Console.WriteLine(count); // } // if (CheckMonad(iToCheck)) { // Console.WriteLine(iToCheck); // // break; // } // count++; // } long CheckMonad(string toCheck, int initialZ, List operations) { int monadPos = 0; var variables = new List() {0,0,0,initialZ};// Enumerable.Repeat(0L, 4).ToList(); foreach (var op in operations) { // varPos.ForEachIndex((c, i) => Console.Write($"{c}: {variables[i]}, ")); // Console.WriteLine(); if (op.op == Op.inp) { ReadInput(op, toCheck, variables, ref monadPos); } else { Calc(op, variables); } } // varPos.ForEachIndex((c, i) => Console.Write($"{c}: {variables[i]}, ")); // Console.WriteLine(); // return variables[varPos.IndexOf('z')] == 0; return variables[varPos.IndexOf('z')]; } void ReadInput(Operation op, string toCheck, List variables, ref int monadPos) { variables[op.aPos] = long.Parse(toCheck[monadPos].ToString()); monadPos++; } void Calc(Operation op, List variables) { long b; if (op.b.Length == 1 && varPos.Contains(op.b[0])) { b = variables[varPos.IndexOf(op.b[0])]; } else { b = long.Parse(op.b); } variables[op.aPos] = op.op switch { Op.add => variables[op.aPos] + b, Op.mul => variables[op.aPos] * b, Op.div => variables[op.aPos] / b, Op.mod => variables[op.aPos] % b, Op.eql => variables[op.aPos] == b ? 1 : 0, _ => throw new ArgumentException() }; } enum Op{ inp, add, mul, div, mod, eql } record Operation(Op op, int aPos, string b); record ZW(long z, string w); #endif