AoC 2019 D25: Cryostasis

C++ | Problem statement | Source code | Tags: IntcodePuzzleManual inspection

← Previous Back to AoC Index

This is a problem I really enjoyed, especially the gaming part. I bet there are more elegant ways to do it, but C++ makes parsing strings a huge pain, so I just manually played the game and drew the map. This is the first truly "interactive" Intcode program, since day 13 was solved by an intelligence. The game loop looks like:

std::cout << "\x1b[2J\x1b[1;1H" << start_prog(prog);
while (!prog.halted) {
std::string command;
std::getline(std::cin, command);
std::cout << "\x1b[2J\x1b[1;1H" << exchange_msg(prog, command);
}
cpp

I need to step over all input instructions and then all output instructions, so exchange_msg looks like:

std::string exchange_msg(Program &prog, const std::string &msg) {
prog.send_input(msg);
prog.send_input('\n');
prog.run_until_output(); // Step over input instructions
prog.run_until_input(); // Step over output instructions
return prog.pop_str_output();
}
cpp

The map I drew is as follows:

Map of the ship

I also experimented with which items are takeable. The final commands are:

std::vector<std::string> take_everything = {
"east", "south", "south", "take hologram",
"north", "north", "west", "south", "take mouse",
"east", "take shell",
"west", "west", "take whirled peas",
"east", "north", "west", "north", "north", "west", "take semiconductor",
"east", "south", "west", "south", "take hypercube",
"north", "east", "south", "west", "take antenna",
"south", "take spool of cat6",
"north", "west", "south", "south"
};
cpp

Once I execute these commands, I am at the security checkpoint with all items. The final step is to try all combinations of items to pass the checkpoint. There are 8 items, so I can just enumerate all combinations of drop x and take x commands. If the program halts after going south, I know I passed the checkpoint.

int n = items.size();
for (int mask = 0; mask < (1 << n); mask++) {
std::vector<std::string> to_drop;
std::vector<std::string> to_take;
for (int i = 0; i < n; i++) {
if (mask & (1 << i)) {
exchange_msg(prog, "drop " + items[i]);
} else {
exchange_msg(prog, "take " + items[i]);
}
}
auto output = exchange_msg(prog, "south");
if (prog.halted) {
std::cout << output;
break;
}
}
cpp

← Previous Back to AoC Index