1
0
www.mikescher.com/www/statics/aoc/2018/21_solution-1.linq

98 lines
6.5 KiB
Plaintext
Raw Permalink Normal View History

2019-11-02 20:19:34 +01:00
<Query Kind="Program" />
class Command { public String Name; public (string, Action<long[], Command>) Op; public int[] Args; public int Dst => Args[2]; public int Arg1 => Args[0]; public int Arg2 => Args[1]; }
(string, Action<long[], Command>)[] Operations = new(string, Action<long[], Command>)[]
{
("addr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] + reg[cmd.Arg2]; } ),
("addi", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] + cmd.Arg2; } ),
("mulr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] * reg[cmd.Arg2]; } ),
("muli", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] * cmd.Arg2; } ),
("banr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] & reg[cmd.Arg2]; } ),
("bani", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] & cmd.Arg2; } ),
("borr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] | reg[cmd.Arg2]; } ),
("bori", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] | cmd.Arg2; } ),
("setr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1]; } ),
("seti", (reg, cmd) => { reg[cmd.Dst] = cmd.Arg1; } ),
("gtir", (reg, cmd) => { reg[cmd.Dst] = cmd.Arg1 > reg[cmd.Arg2] ? 1:0; } ),
("gtri", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] > cmd.Arg2 ? 1:0; } ),
("gtrr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] > reg[cmd.Arg2] ? 1:0; } ),
("eqir", (reg, cmd) => { reg[cmd.Dst] = cmd.Arg1 == reg[cmd.Arg2] ? 1:0; } ),
("eqri", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] == cmd.Arg2 ? 1:0; } ),
("eqrr", (reg, cmd) => { reg[cmd.Dst] = reg[cmd.Arg1] == reg[cmd.Arg2] ? 1:0; } ),
};
void Main()
{
(var commands, var ipidx) = Load(File.ReadAllLines(Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), @"21_input.txt")));
long[] data = new long[6];
data[0]=2;
for (int gen=0;;gen++)
{
if (data[ipidx] < 0 || data[ipidx] >= commands.Count) { break; }
var ip=data[ipidx];
var cmd = commands[(int)ip];
if (ip == 28) { data[4].Dump(); return; } // this is if ([4] == [0]) EXIT
cmd.Op.Item2(data, cmd);
data[ipidx]++;
//$"{ip:00}:{cmd.Op.Item1} [{string.Join(" ", data.Take(6).Select(i => $"{i,-10}"))}]".Dump();
}
data[0].Dump();
}
(List<Command>, int) Load(string[] input)
{
return
(
input
.Skip(1)
.Where(i => !string.IsNullOrWhiteSpace(i))
.Select(i => new Command { Name = i.Split(' ')[0], Op=Operations.Single(o => o.Item1.ToLower() == i.Split(' ')[0].ToLower()), Args = i.Split(' ').Skip(1).Select(int.Parse).ToArray() })
.ToList(),
int.Parse(input[0].Split(' ')[1])
);
}
/*
#ip 1
00: seti 123 0 4 [4] = 123 [4] = 123 [4] = 123
01: bani 4 456 4 [4] = [4] & 456 1: [4] &= 456 [4] &= 456
02: eqri 4 72 4 [4] = [4] == 72 if ([4]<>72) JMP 1 if ([4]<>72) ERROR
03: addr 4 1 1 IP = IP + [4]
04: seti 0 0 1 IP = 0
05: seti 0 2 4 [4] = 0 [4] = 0 [4] = 0 for([4] = 0;;)
06: bori 4 65536 3 [3] = [4] | 65536 6: [3] = [4] | 65536 6: [3] = [4] | 65536 [3] = [4] | 65536
07: seti 10552971 1 4 [4] = 10552971 [4] = 10552971 [4] = 10552971 [4] = 10552971
08: bani 3 255 5 [5] = [3] & 255 8: [5] = [3] & 255 8: [5] = [3] & 255 for(;;)
09: addr 4 5 4 [4] = [4] + [5] [4] += [5] [4] += [5] [5] = [3] & 255
10: bani 4 16777215 4 [4] = [4] & 16777215 [4] &= 16777215 [4] &= 16777215 [4] += [5]
11: muli 4 65899 4 [4] = [4] * 65899 [4] *= 65899 [4] *= 65899 [4] &= 16777215
12: bani 4 16777215 4 [4] = [4] & 16777215 [4] &= 16777215 [4] &= 16777215 [4] *= 65899
13: gtir 256 3 5 [5] = 256 > [3] if (256 > [3]) JMP 28 if (256 > [3] && [4] == [0]) EXIT [4] &= 16777215
14: addr 5 1 1 IP = IP + [5] if (256 > [3]) JMP 6 if (256 > [3] && [4] == [0]) EXIT
15: addi 1 1 1 IP = IP + 1 if (256 > [3]) BREAK
16: seti 27 7 1 IP = 27
17: seti 0 1 5 [5] = 0 [5] = 0 [5] = 0
18: addi 5 1 2 [2] = [5] + 1 18: [2] = [5] + 1 18: [2] = [5] + 1 for([5]=0;;)
19: muli 2 256 2 [2] = [2] * 256 [2] *= 256 [2] *= 256 [2] = ([5] + 1) * 256
20: gtrr 2 3 2 [2] = [2] > [3] if ([2] > [3]) JMP 26 if ([2] > [3]) [3] = [5]; JMP 8
21: addr 2 1 1 IP = IP + [2] else [5]++ JMP 18 if ([2] > [3]) [3] = [5]; BREAK
22: addi 1 1 1 IP = IP + 1 else [5]++ CONTINUE
23: seti 25 0 1 IP = 25
24: addi 5 1 5 [5] = [5] + 1 [5]++
25: seti 17 2 1 IP = 17 JMP 18
26: setr 5 7 3 [3] = [5] 26: [3] = [5]
27: seti 7 8 1 IP = 7 JMP 8
28: eqrr 4 0 5 [5] = [4] == [0] 28: if ([4] == [0]) EXIT
29: addr 5 1 1 IP = IP + [5] else JMP 6
30: seti 5 0 1 IP = 5
*/