예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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));
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }