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()); }
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()); }