185 lines
5.4 KiB
C#
185 lines
5.4 KiB
C#
// #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<Op>(parts[0]), varPos.IndexOf(parts[1][0]), "do not use")
|
|
: new Operation(Enum.Parse<Op>(parts[0]), varPos.IndexOf(parts[1][0]), parts[2])
|
|
)
|
|
.ToList();
|
|
|
|
var operationSections = new List<List<Operation>>();
|
|
var curOperations = new List<Operation>();
|
|
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<Operation>() { op };
|
|
}
|
|
|
|
operationSections.Add(curOperations);
|
|
operationSections.Reverse();
|
|
|
|
var starting = new ZW(0, "0");
|
|
var prev = new HashSet<ZW>() {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<ZW>();
|
|
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<Operation> operations) {
|
|
int monadPos = 0;
|
|
var variables = new List<long>() {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<long> variables, ref int monadPos) {
|
|
variables[op.aPos] = long.Parse(toCheck[monadPos].ToString());
|
|
monadPos++;
|
|
}
|
|
|
|
void Calc(Operation op, List<long> 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 |