/// <inheritdoc /> public string Part2() { IntCodeVM2 vm = new IntCodeVM2(program); // show prompt vm.ExecuteProgram(); DrawASCIIOutput(vm.GetOutputs()); vm.ClearOutput(); // input program // // @ // ##ABCDEFGHI### // // if D is ground and any of A,B,C aren't then jump (p1) // invert T (now equal to C) // if ((I OR F) AND E) OR H are ground, then jump ASCIIHelper helper = new ASCIIHelper(); helper.AddLine("NOT A T"); helper.AddLine("NOT B J"); helper.AddLine("OR T J"); helper.AddLine("NOT C T"); helper.AddLine("OR T J"); helper.AddLine("AND D J"); helper.AddLine("AND T T"); helper.AddLine("OR I T"); helper.AddLine("OR F T"); helper.AddLine("AND E T"); helper.AddLine("OR H T"); helper.AddLine("AND T J"); helper.AddLine("RUN"); vm.AddInput(helper.Convert()); // output what it showed vm.ResumeProgram(); if (vm.GetLastOutput() > 255) { Console.WriteLine($"\nhull damage taken: {vm.GetLastOutput()}"); } else { DrawASCIIOutput(vm.GetOutputs()); } return(""); }
/// <inheritdoc /> public string Part1() { IntCodeVM2 vm = new IntCodeVM2(program); // show prompt vm.ExecuteProgram(); DrawASCIIOutput(vm.GetOutputs()); vm.ClearOutput(); // input program //J = (NOT A OR NOT B OR NOT C) AND D // // @ // ##ABCD### // // if D is ground and any of A,B,C aren't then jump ASCIIHelper helper = new ASCIIHelper(); helper.AddLine("NOT A T"); helper.AddLine("NOT B J"); helper.AddLine("OR T J"); helper.AddLine("NOT C T"); helper.AddLine("OR T J"); helper.AddLine("AND D J"); helper.AddLine("WALK"); vm.AddInput(helper.Convert()); // output what it showed vm.ResumeProgram(); if (vm.GetLastOutput() > 255) { Console.WriteLine($"\nhull damage taken: {vm.GetLastOutput()}"); } else { DrawASCIIOutput(vm.GetOutputs()); } return(""); }
/// <inheritdoc /> public string Part1() { // create vms and inputs List <IntCodeVM2> vms = new List <IntCodeVM2>(); for (int i = 0; i < 50; i++) { vms.Add(new IntCodeVM2(program)); vms[i].AddInput(i); } while (true) { // run all of them till they stop waiting for input List <Task> tasks = new List <Task>(); foreach (IntCodeVM2 vm in vms) { tasks.Add(Task.Run(() => { vm.ResumeProgram(); })); } Task.WaitAll(tasks.ToArray()); // add input to all of them bool[] addedInput = new bool[50]; for (int i = 0; i < vms.Count; i++) { IntCodeVM2 vm = vms[i]; List <long> packet = vm.GetOutputs(); if (packet.Count > 0) { // go through multiple packets for (int j = 0; j < packet.Count; j += 3) { // actually crashes the program if (packet[j] == 255) { return($"Y value of first packet which was went to 255: {packet[2]}"); } IntCodeVM2 receiver = vms[(int)packet[j]]; receiver.AddInput(packet[j + 1]); receiver.AddInput(packet[j + 2]); // crash showed 22074 addedInput[i] = true; } // clear output for next time vm.ClearOutput(); } } // all of those which didn't receive input get -1 for (int i = 0; i < addedInput.Length; i++) { if (!addedInput[i]) { vms[i].AddInput(-1); } } } }
/// <inheritdoc /> public string Part2() { // create vms and inputs List <IntCodeVM2> vms = new List <IntCodeVM2>(); for (int i = 0; i < 50; i++) { vms.Add(new IntCodeVM2(program)); vms[i].AddInput(i); } List <long> lastNatPacket = new List <long>() { 0, 0, 0 }; List <long> previousYValuesUsed = new List <long>(); bool updatedY = false; while (true) { // run all of them till they stop waiting for input List <Task> tasks = new List <Task>(); foreach (IntCodeVM2 vm in vms) { tasks.Add(Task.Run(() => { vm.ResumeProgram(); })); } Task.WaitAll(tasks.ToArray()); // add input to all of them bool[] addedInput = new bool[50]; for (int i = 0; i < vms.Count; i++) { IntCodeVM2 vm = vms[i]; List <long> packet = vm.GetOutputs(); if (packet.Count > 0) { // go through multiple packets for (int j = 0; j < packet.Count; j += 3) { // actually crashes the program if (packet[j] == 255) { //return $"Y value of first packet which was went to 255: {packet[2]}"; lastNatPacket[1] = packet[j + 1]; lastNatPacket[2] = packet[j + 2]; updatedY = true; } else { IntCodeVM2 receiver = vms[(int)packet[j]]; receiver.AddInput(packet[j + 1]); receiver.AddInput(packet[j + 2]); // crash showed 22074 addedInput[i] = true; } } // clear output for next time vm.ClearOutput(); } } // check if all inputs are empty if (addedInput.All(i => i == false)) { // send last NAT packet to vm 0 vms[0].AddInput(lastNatPacket); // only add used Y after updating Y if (updatedY) { previousYValuesUsed.Add(lastNatPacket[2]); updatedY = false; } // check if this one was sent before if (previousYValuesUsed.Count > 1 && previousYValuesUsed[previousYValuesUsed.Count - 2] == previousYValuesUsed[previousYValuesUsed.Count - 1]) { return($"sent {previousYValuesUsed[previousYValuesUsed.Count - 2]} twice in a row"); } // send -1 to the rest for (int i = 1; i < addedInput.Length; i++) { if (!addedInput[i]) { vms[i].AddInput(-1); } } } // just another round else { // all of those which didn't receive input get -1 for (int i = 0; i < addedInput.Length; i++) { if (!addedInput[i]) { vms[i].AddInput(-1); } } } } }
/// <inheritdoc /> public string Part2() { IntCodeVM2 vm = new IntCodeVM2(longs); vm.SetMemory(0, 2); vm.ExecuteProgram(); List <int> output = vm.GetOutputs().Select(l => (int)l).ToList(); Dictionary <Vector2Int, int> tiles = new Dictionary <Vector2Int, int>(); int finalScore = 0; // draw tiles for (int i = 0; i < output.Count; i += 3) { // get score if (output[i] == -1) { finalScore = output[i + 2]; continue; } // create new tiles tiles.Add(new Vector2Int(output[i], output[i + 1]), output[i + 2]); } // as long as breakable blocks remain while (tiles.Values.Count(t => t == 2) > 0) { // redraw tiles output = vm.GetOutputs().Select(l => (int)l).ToList(); for (int i = 0; i < output.Count; i += 3) { // get score if (output[i] == -1) { finalScore = output[i + 2]; Console.WriteLine($"Current score {finalScore}"); continue; } Vector2Int pos = new Vector2Int(output[i], output[i + 1]); if (tiles.ContainsKey(pos)) { tiles[pos] = output[i + 2]; } else { tiles.Add(pos, output[i + 2]); } } // show screen if (humanInput) { DrawScreen(tiles); // do a move switch (Console.ReadKey().Key) { case ConsoleKey.DownArrow: vm.AddInput(0); break; case ConsoleKey.LeftArrow: vm.AddInput(-1); break; case ConsoleKey.RightArrow: vm.AddInput(+1); break; } } else { // get paddle pos Vector2Int paddle = tiles.Keys.ToList()[tiles.Values.ToList().FindIndex(i => i == 3)]; // get ball pos Vector2Int ball = tiles.Keys.ToList()[tiles.Values.ToList().FindIndex(i => i == 4)]; // determine next move if (ball.X > paddle.X) { vm.AddInput(1); } else if (ball.X < paddle.X) { vm.AddInput(-1); } else { vm.AddInput(0); } } // run again vm.ClearOutput(); vm.ResumeProgram(); } return($"final score {finalScore}"); }
/// <inheritdoc /> public string Part1() { IntCodeVM2 intCodeVM = new IntCodeVM2(program); intCodeVM.AddInput(0); //intCodeVM.ResizeMemory(int.MaxValue >> 4); // positions and colors (1 = white, 0 = black) Dictionary <Vector2Int, int> paintedPanels = new Dictionary <Vector2Int, int>(); paintedPanels.Add(Vector2Int.Zero, 0); // rotation Direction direction = Direction.Up; // keep running till it stops asking for input Vector2Int robotPos = Vector2Int.Zero; while (intCodeVM.ResumeProgram() == IntCodeVM2.HaltCode.WaitingForInput) { // get outputs int newColor = (int)intCodeVM.GetOutputs()[0]; int directionChange = (int)intCodeVM.GetOutputs()[1]; // paint if (paintedPanels.TryGetValue(robotPos, out int color)) { paintedPanels[robotPos] = newColor; } else { paintedPanels.Add(robotPos, newColor); } // rotate if (directionChange == 0) { direction = (direction - 1); // left 90° from up is left if ((int)direction < 0) { direction = Direction.Left; } } else { direction += 1; // right 90° from left is up if ((int)direction > 3) { direction = Direction.Up; } } // move one panel forward switch (direction) { case Direction.Up: robotPos += new Vector2Int(0, -1); break; case Direction.Right: robotPos += new Vector2Int(1, 0); break; case Direction.Down: robotPos += new Vector2Int(0, 1); break; case Direction.Left: robotPos += new Vector2Int(-1, 0); break; default: throw new ArgumentOutOfRangeException(); } // input into VM if (paintedPanels.TryGetValue(robotPos, out color)) { intCodeVM.AddInput(color); } else { intCodeVM.AddInput(0); } // clear output intCodeVM.ClearOutput(); // run again } Console.WriteLine($"Last halt reason {intCodeVM.LastHaltReason.ToString()}"); return($"Touched {paintedPanels.Count} panels"); // ans = 2511 }
/// <inheritdoc /> public string Part2() { IntCodeVM2 intCodeVM = new IntCodeVM2(program); intCodeVM.AddInput(1); // starting from a white panel now // positions and colors (1 = white, 0 = black) Dictionary <Vector2Int, int> paintedPanels = new Dictionary <Vector2Int, int>(); paintedPanels.Add(Vector2Int.Zero, 0); // rotation Direction direction = Direction.Up; // keep running till it stops asking for input Vector2Int robotPos = Vector2Int.Zero; while (intCodeVM.ResumeProgram() == IntCodeVM2.HaltCode.WaitingForInput) { // get outputs int newColor = (int)intCodeVM.GetOutputs()[0]; int directionChange = (int)intCodeVM.GetOutputs()[1]; // paint if (paintedPanels.TryGetValue(robotPos, out int color)) { paintedPanels[robotPos] = newColor; } else { paintedPanels.Add(robotPos, newColor); } // rotate if (directionChange == 0) { direction = (direction - 1); // left 90° from up is left if ((int)direction < 0) { direction = Direction.Left; } } else { direction += 1; // right 90° from left is up if ((int)direction > 3) { direction = Direction.Up; } } // move one panel forward switch (direction) { case Direction.Up: robotPos += new Vector2Int(0, -1); break; case Direction.Right: robotPos += new Vector2Int(1, 0); break; case Direction.Down: robotPos += new Vector2Int(0, 1); break; case Direction.Left: robotPos += new Vector2Int(-1, 0); break; default: throw new ArgumentOutOfRangeException(); } // input into VM if (paintedPanels.TryGetValue(robotPos, out color)) { intCodeVM.AddInput(color); } else { intCodeVM.AddInput(0); } // clear output intCodeVM.ClearOutput(); // run again } Console.WriteLine($"Last halt reason {intCodeVM.LastHaltReason.ToString()}"); Console.WriteLine($"Touched {paintedPanels.Count} panels"); // find highest x and highest y int highestX = paintedPanels.Keys.OrderBy(vec => vec.X).Last().X; int highestY = paintedPanels.Keys.OrderBy(vec => vec.Y).Last().Y; /* * int lowestX = xSorted[0].X; // 0 * int highestX = xSorted[xSorted.Count - 1].X; // 42 * int lowestY = ySorted[0].Y; // 0 * int highestY = ySorted[xSorted.Count - 1].Y; // 18 */ for (int i = 0; i <= highestY; i++) { for (int j = 0; j <= highestX; j++) { int color = 0; if (paintedPanels.TryGetValue(new Vector2Int(j, i), out color)) { } // color if (color == 0) { Console.ForegroundColor = ConsoleColor.White; Console.BackgroundColor = ConsoleColor.Black; } else { Console.ForegroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.White; } Console.Write(" "); } Console.WriteLine(); } return($""); }
/// <inheritdoc /> public string Part1() { // set to true to play the text adventure bool userPlay = false; IntCodeVM2 vm = new IntCodeVM2(program); vm.ExecuteProgram(); if (userPlay) { while (true) { // output foreach (long l in vm.GetOutputs()) { if (l < 255) { Console.Write((char)l); } else { Console.Write(l); } } vm.ClearOutput(); // input string inputLine = Console.ReadLine(); ASCIIHelper helper = new ASCIIHelper(); helper.AddLine(inputLine); vm.AddInput(helper.Convert()); vm.ResumeProgram(); } } else { // list of inputs to get to the end List <string> inputs = new List <string>() { "south", "take food ration", "west", "north", "north", "east", "take astrolabe", "west", "south", "south", "east", "north", "east", "south", "take weather machine", "west", "take ornament", "east", "north", "east", "east", "east", "south" }; ASCIIHelper helper = new ASCIIHelper(); foreach (string input in inputs) { helper.AddLine(input); } vm.AddInput(helper.Convert()); vm.ResumeProgram(); List <long> output = vm.GetOutputs(); output.RemoveAt(output.Count - 1); // remove last \n int lastLineStart = output.LastIndexOf(10); // get last sentence // convert characters to a string StringBuilder lastLine = new StringBuilder(); for (int i = lastLineStart + 1; i < output.Count; i++) { if (output[i] < 255) { lastLine.Append((char)output[i]); } else { lastLine.Append(output[i]); } } // get the number from the last line return(Regex.Match(lastLine.ToString(), @"\d+").Value); } return($""); }