Example #1
0
        public string Solve(string data)
        {
            var vm = new AsyncIntCodeVm(data);

            vm.InputBuffer.Post(1);

            int direction        = 0;                     // Facing up
            var location         = new Point(0, 0);
            var paintedLocations = new HashSet <Point>(); // So we won't get dupes

            // Initialise with current location as white
            var hullLocationColours = new Dictionary <Point, long>()
            {
                { location, 1 },
            };

            Task vmTask = vm.ExecuteAsync();

            while (!vmTask.IsCompleted)
            {
                // Get the colour
                long colour;

                try
                {
                    colour = vm.OutputBuffer.Receive(TimeSpan.FromMilliseconds(10));
                }
                catch (Exception)
                {
                    if (vmTask.IsCompleted)
                    {
                        // Edge case. We managed to loop between reading the last value and before the program properly ended.
                        // This is OK, and we just break out of the loop and write the answer.
                        break;
                    }

                    throw;
                }

                // Paint
                hullLocationColours[location] = colour;
                paintedLocations.Add(location);

                // Get the location change
                long turn = vm.OutputBuffer.Receive(TimeSpan.FromMilliseconds(10));

                // Turn and move
                direction = (direction + (turn == 0 ? -1 : 1) + 4) % 4;
                location  = new Point(location.X + Directions[direction].X, location.Y + Directions[direction].Y);

                hullLocationColours.TryGetValue(location, out colour); // If there is no value, colour gets set to default(long), i.e. 0
                vm.InputBuffer.Post(colour);
            }

            // Build the visualisation; remove black locations from the list to ensure we only visualise what's needed.
            StringBuilder display = this.BuildVisualisation(hullLocationColours);

            return(display.ToString());
        }
Example #2
0
        public string Solve(string data)
        {
            var vm = new AsyncIntCodeVm(data);

            vm.InputBuffer.Post(0);

            int direction           = 0;                     // Facing up
            var location            = new Point(0, 0);
            var paintedLocations    = new HashSet <Point>(); // So we won't get dupes
            var hullLocationColours = new Dictionary <Point, long>();

            Task vmTask = vm.ExecuteAsync();

            // Assuming we'll always get outputs in pairs. If not, we'd need to check between the two Receive calls.
            while (!vmTask.IsCompleted)
            {
                // Get the colour
                long colour = vm.OutputBuffer.Receive(TimeSpan.FromSeconds(1));

                // Paint
                hullLocationColours[location] = colour;
                paintedLocations.Add(location);

                // Get the location change
                long turn = vm.OutputBuffer.Receive(TimeSpan.FromSeconds(1));

                // Turn and move
                direction = (direction + (turn == 0 ? -1 : 1) + 4) % 4;
                location  = new Point(location.X + Directions[direction].X, location.Y + Directions[direction].Y);

                // Post colour of current location to VM
                hullLocationColours.TryGetValue(location, out colour); // If there is no value, colour gets set to default(long), i.e. 0
                vm.InputBuffer.Post(colour);
            }

            return(paintedLocations.Count.ToString());
        }