01020304050607080910111213141516171819202122232425

Advent of Code

2019/25

Cryostasis

in C#

by encse

As you approach Santa's ship, your sensors report two important details:

First, that you might be too late: the internal temperature is -40 degrees.

Read the full puzzle.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace AdventOfCode.Y2019.Day25;

[ProblemName("Cryostasis")]
class Solution : Solver {

    public object PartOne(string input) {
        var securityRoom = "== Security Checkpoint ==";
        var icm = new IntCodeMachine(input);
        var description = icm.Run().ToAscii();

        VisitRooms(securityRoom, icm, description, args => {
            foreach (var item in args.items) {
                if (item != "infinite loop") {
                    var takeCmd = "take " + item;
                    var clone = icm.Clone();
                    clone.Run(takeCmd);
                    if (!clone.Halted() && Inventory(clone).Contains(item)) {
                        icm.Run(takeCmd);
                    }
                }
            }
            return null;
        });

        var door = VisitRooms(securityRoom, icm, description, args =>
           args.room == securityRoom ? args.doors.Single(door => door != ReverseDir(args.doorTaken)) : null);
        
        Random r = new Random();
        void TakeOrDrop(string cmd, List<string> from, List<string> to) {
            var i = r.Next(from.Count);
            var item = from[i];
            from.RemoveAt(i);
            to.Add(item);
            icm.Run(cmd + " " + item);
        }

        var inventory = Inventory(icm).ToList();
        var floor = new List<string>();
        while (true) {
            var output = icm.Run(door).ToAscii();
            if (output.Contains("heavier")) {
                TakeOrDrop("take", floor, inventory);
            } else if (output.Contains("lighter")) {
                TakeOrDrop("drop", inventory, floor);
            } else {
                return long.Parse(Regex.Match(output, @"\d+").Value);
            }
        }
    }

    List<string> directions = new List<string>() { "south", "east", "west", "north" };
    string ReverseDir(string direction) => directions[3 - directions.IndexOf(direction)];

    string VisitRooms(
        string securityRoom,
        IntCodeMachine icm, 
        string description, 
        Func<(IEnumerable<string> items, string room, string doorTaken, IEnumerable<string> doors), string> callback
    ) {

        var roomsSeen = new HashSet<string>();
        string DFS(string description, string doorTaken) {
            var room = description.Split("\n").Single(x => x.Contains("=="));
            var listing = GetListItems(description).ToHashSet();
            var doors = listing.Intersect(directions);
            var items = listing.Except(doors);

            if (!roomsSeen.Contains(room)) {
                roomsSeen.Add(room);

                var res = callback((items, room, doorTaken, doors));
                if (res != null) {
                    return res;
                }
                if (room != securityRoom) {
                    foreach (var door in doors) {
                        res = DFS(icm.Run(door).ToAscii(), door);
                        if (res != null) {
                            return res;
                        }
                        icm.Run(ReverseDir(door));
                    }
                }
            }
            return null;
        }

        return DFS(description, null);
    }

    IEnumerable<string> Inventory(IntCodeMachine icm) => GetListItems(icm.Run("inv").ToAscii());

    IEnumerable<string> GetListItems(string description) =>
        from line in description.Split("\n")
        where line.StartsWith("- ")
        select line.Substring(2);
}

Please ☆ my repo if you like it!

© 2025 Advent of Code is a registered trademark in the US Images provided by Bing image creator