public (int Count, char[, ] Pattern) Solve(Data inputData) { var data = inputData.OpCodes.Split(',').Select(long.Parse).ToArray(); var intMachine = IntMachine.CreateDefault(); var machineToServerChannel = Channel.CreateUnbounded <long>(); var serverToMachineChannel = Channel.CreateUnbounded <long>(); intMachine.InputRequested += (sender, args) => { args.ValueAsync = serverToMachineChannel.Reader.ReadAsync(); }; intMachine.Output += (sender, args) => { machineToServerChannel.Writer.WriteAsync(args.Output); }; intMachine.Completed += (sender, args) => { machineToServerChannel.Writer.Complete(); }; serverToMachineChannel.Writer.WriteAsync(inputData.StartColor); var answerTask = Task.Run(async() => { (int X, int Y)position = (0, 0); (int U, int V)forwardVec = (0, 1); var paintedCells = new Dictionary <(int X, int Y), Color>(); while (await machineToServerChannel.Reader.WaitToReadAsync()) { var colour = (Color)await machineToServerChannel.Reader.ReadAsync(); // Paint the cell! paintedCells[position] = colour; var direction = await machineToServerChannel.Reader.ReadAsync(); switch (direction) { case 0: forwardVec = this.RotateVector(forwardVec, 90); break; case 1: forwardVec = this.RotateVector(forwardVec, -90); break; } position = (position.X + forwardVec.U, position.Y + forwardVec.V); await serverToMachineChannel.Writer.WriteAsync(this.GetCellColour(paintedCells, position)); } return(inputData.OutputPaintedValue ? (paintedCells.Count, GetMap(paintedCells)) : (paintedCells.Count, (char[, ])null)); }); Task.Run(async() => { await intMachine.ProcessAsync(data); }); return(answerTask.Result); }
public int Solve(Data inputData) { var data = inputData.OpCodes.Split(',').Select(int.Parse).ToArray(); var intMachine = IntMachine.CreateDefault(); var output = 0; intMachine.InputRequested += (sender, args) => { args.Value = inputData.InputValue; }; intMachine.Output += (sender, args) => { output = (int)args.Output; }; var state = intMachine.Process(data); return(output); }
public string Solve(Data inputData) { var data = inputData.OpCodes.Split(',').Select(long.Parse).ToArray(); var intMachine = IntMachine.CreateDefault(); var output = new List <long>(); intMachine.InputRequested += (sender, args) => { args.Value = inputData.InputValue; }; intMachine.Output += (sender, args) => { output.Add(args.Output); }; intMachine.Process(data); return(string.Join(',', output)); }
private IntMachine CreateIntMachine(Channel <int> inputCommChannel, Channel <int> outputCommChannel, int machineIdx) { var intMachine = IntMachine.CreateDefault(); intMachine.InputRequested += (sender, args) => { args.ValueAsync = new ValueTask <long>(Task.Run(async() => { var value = await inputCommChannel.Reader.ReadAsync(); return((long)value); })); }; intMachine.Output += (sender, args) => { _ = outputCommChannel.Writer.WriteAsync((int)args.Output); }; intMachine.Completed += (sender, args) => { outputCommChannel.Writer.Complete(); }; return(intMachine); }
public int Solve(Data inputData) { var cts = new CancellationTokenSource(); var data = inputData.OpCodes.Split(',').Select(long.Parse).ToArray(); var intMachine = IntMachine.CreateDefault(); var machineToServerChannel = Channel.CreateUnbounded <long>(); var serverToMachineChannel = Channel.CreateUnbounded <long>(); intMachine.InputRequested += (sender, args) => { args.ValueAsync = serverToMachineChannel.Reader.ReadAsync(cts.Token); }; intMachine.Output += (sender, args) => { machineToServerChannel.Writer.WriteAsync(args.Output, cts.Token); }; intMachine.Completed += (sender, args) => { machineToServerChannel.Writer.Complete(); serverToMachineChannel.Writer.Complete(); }; var tiles = new Dictionary <(long X, long Y), ExploredTile>(); (long X, long Y)position = (0, 0); AddTile(position, tiles, TileType.Open); var state = inputData.States.Dequeue(); var result = Task.Run(async() => { Queue <Direction> path = null; while (!cts.IsCancellationRequested) { if (state == DroidState.Explore && (path == null || path.Count <= 0)) { var steps = DecideMovement(position, tiles); if (steps != null && steps.Length > 0) { path = new Queue <Direction>(steps); } else { // Exploration done, move to next state state = inputData.States.Dequeue(); } } switch (state) { case DroidState.Explore: position = await this.Explore(position, path, serverToMachineChannel, machineToServerChannel, tiles, cts.Token); this.VisualisableUpdate?.Invoke(this, new VisualiserUpdateEventArgs(tiles)); break; case DroidState.CalculateDistance: var pathToOxygen = PathingUtility.DijkstraSearch((0, 0), t => t.Type == TileType.OxygenSystem, tiles); cts.Cancel(); return(pathToOxygen.Length); case DroidState.CalculateOxygenDistributionTime: var disbursementTime = CalculateOxygenDistributionTime(tiles); cts.Cancel(); return(disbursementTime); default: throw new ArgumentOutOfRangeException(); } } return(0); }, cts.Token); Task.Run(async() => { try { await intMachine.ProcessAsync(data, cts.Token); } catch (OperationCanceledException) { // Ignored } }, cts.Token); return(result.Result); }
public (int BlocksRemaining, long Score) Solve(Data inputData) { var data = inputData.OpCodes.Split(',').Select(long.Parse).ToArray(); var intMachine = IntMachine.CreateDefault(); long score = 0; var cellTiles = new Dictionary <(long X, long Y), Tile>(); var serverToMachineChannel = Channel.CreateUnbounded <long>(); var machineToServerChannel = Channel.CreateUnbounded <long>(); var cts = new CancellationTokenSource(); intMachine.InputRequested += (sender, args) => { args.ValueAsync = serverToMachineChannel.Reader.ReadAsync(cts.Token); }; intMachine.Output += (sender, args) => { machineToServerChannel.Writer.WriteAsync(args.Output, cts.Token); }; intMachine.Completed += (sender, args) => { machineToServerChannel.Writer.Complete(); serverToMachineChannel.Writer.Complete(); cts.Cancel(); }; var ballPosSemaphore = new SemaphoreSlim(0, 1); Task.Run(async() => { while (!cts.Token.IsCancellationRequested) { await ballPosSemaphore.WaitAsync(cts.Token); if (cts.Token.IsCancellationRequested) { return; } while (true) { if (cellTiles.ContainsValue(Tile.Ball) && cellTiles.ContainsValue(Tile.HorizontalPaddle)) { KeyValuePair <(long X, long Y), Tile> ballPos; KeyValuePair <(long X, long Y), Tile> paddlePos; lock (cellTiles) { ballPos = cellTiles.FirstOrDefault(v => v.Value == Tile.Ball); paddlePos = cellTiles.FirstOrDefault(v => v.Value == Tile.HorizontalPaddle); } if (ballPos.Key.X > paddlePos.Key.X) { await serverToMachineChannel.Writer.WriteAsync(1, cts.Token); } else if (ballPos.Key.X < paddlePos.Key.X) { await serverToMachineChannel.Writer.WriteAsync(-1, cts.Token); } else { await serverToMachineChannel.Writer.WriteAsync(0, cts.Token); } break; } // We don't have a paddle position yet... await Task.Delay(100, cts.Token); } } }, cts.Token); var answerTask = Task.Run(async() => { var populationOccured = false; (long X, long Y)position = (0, 0); while (await machineToServerChannel.Reader.WaitToReadAsync(cts.Token)) { position.X = await machineToServerChannel.Reader.ReadAsync(cts.Token); position.Y = await machineToServerChannel.Reader.ReadAsync(cts.Token); var movePaddle = false; if (position.X == -1 && position.Y == 0) { score = await machineToServerChannel.Reader.ReadAsync(cts.Token); populationOccured = true; } else { var tile = (Tile)await machineToServerChannel.Reader.ReadAsync(cts.Token); lock (cellTiles) { cellTiles[position] = tile; } movePaddle = cellTiles[position] == Tile.Ball; } if (inputData.PrintMap) { this.PrintMap(GetMap(cellTiles), score); await Task.Delay(10, cts.Token); } if (movePaddle) { ballPosSemaphore.Release(); } } return(cellTiles.Count(t => t.Value == Tile.Block), score); }, cts.Token); Task.Run(async() => { await intMachine.ProcessAsync(data, cts.Token); }, cts.Token); return(answerTask.Result); }