private async Task <(Dictionary <(int, int), char>, (int, int))> GetMapAsync() { var map = new Dictionary <(int, int), char>(); var pos = (0, 0); var tar = pos; var dir = N; var input = Channel.CreateUnbounded <BigInteger>(); var intcode = new IntcodeComputer(_input) { Input = () => input.Reader.ReadAsync().AsTask() }; intcode.Output = async status => { switch ((int)status) { case 0: // hit wall map[Step(pos, dir)] = '#'; dir = dir switch { N => W, W => S, S => E, E => N, _ => throw new Exception("dir?"), }; await input.Writer.WriteAsync(dir); break; case 1: // moved pos = Step(pos, dir); map[pos] = '.'; dir = dir switch { N when !IsWall(Step(pos, E)) => E, N => N, W when !IsWall(Step(pos, N)) => N, W => W, S when !IsWall(Step(pos, W)) => W, S => S, E when !IsWall(Step(pos, S)) => S, E => E, _ => throw new Exception("dir?"), }; await input.Writer.WriteAsync(dir); if (pos == default && tar != default) { intcode.Halt(); } break; case 2: // found it tar = Step(pos, dir); goto case 1; } }; await input.Writer.WriteAsync(dir); await intcode.RunAsync(); return(map, tar); bool IsWall((int, int) pos) => map.TryGetValue(pos, out var c) && c == '#'; }