Beispiel #1
0
        private void EnqueueNeighbors(Queue <Point> queue, Point position)
        {
            for (int i = 0; i < (int)Direction.Count; ++i)
            {
                Point newPos = Board2D <int?> .MoveForward(position, (Direction)i, 1, true);

                if (!IsValid(newPos))
                {
                    // Off-limit
                    continue;
                }

                if (_board[newPos.X, newPos.Y] != null)
                {
                    // Already done
                    continue;
                }

                if (IsWall(newPos))
                {
                    // Unreachable
                    _board[newPos.X, newPos.Y] = -1;
                    continue;
                }

                int weight = _board[position.X, position.Y].Value;
                _board[newPos.X, newPos.Y] = weight + 1;
                queue.Enqueue(newPos);
            }
        }
Beispiel #2
0
        private void Spread(Point p)
        {
            Point moved = Board2D <long> .MoveForward(p, Direction.Up);

            if (_board[moved] == 0)
            {
                _board[moved] = 1;
            }

            moved = Board2D <long> .MoveForward(p, Direction.Down);

            if (_board[moved] == 0)
            {
                _board[moved] = 1;
            }

            moved = Board2D <long> .MoveForward(p, Direction.Left);

            if (_board[moved] == 0)
            {
                _board[moved] = 1;
            }

            moved = Board2D <long> .MoveForward(p, Direction.Right);

            if (_board[moved] == 0)
            {
                _board[moved] = 1;
            }
        }
Beispiel #3
0
        private long Search(Point origin, int nbKeys)
        {
            // Clear history
            _history = new HashSet <long>();

            // Prepare initial state
            State         initial = new State(origin);
            Queue <State> queue   = new Queue <State>();

            queue.Enqueue(initial);

            while (queue.Count > 0)
            {
                // Get  the state to process
                State current = queue.Dequeue();

                // Abort if we've already been here
                long hash = current.GetHashLong();
                if (_history.Contains(hash))
                {
                    continue;
                }
                _history.Add(hash);

                // Add the new key if we're on a key
                char c = _board[current.Position];
                if (char.IsLower(c))
                {
                    current.AddKey(c);
                    if (current.CountKeys() == nbKeys)
                    {
                        // We just add the final key, we have a solution
                        return(current.Distance);
                    }
                }

                // Add the next states
                for (int d = 0; d < (int)Direction.Count; ++d)
                {
                    Point np = Board2D <long> .MoveForward(current.Position, (Direction)d);

                    char nc = _board[np];
                    if (nc == '#')
                    {
                        continue;
                    }

                    if (char.IsUpper(nc) && !current.ContainsKey(char.ToLower(nc)))
                    {
                        continue;
                    }

                    State nextState = new State(current, np);
                    queue.Enqueue(nextState);
                }
            }

            return(0);
        }
Beispiel #4
0
        private void Burst(Aoc.Framework.Part part)
        {
            Direction turnDirection = GetTurnDirection();

            _direction = Board2D <Cell> .Turn(_direction, turnDirection);

            Infect(part);
            _position = Board2D <Int64> .MoveForward(_position, _direction);
        }
Beispiel #5
0
        public string Run(Aoc.Framework.Part part)
        {
            if (part == Aoc.Framework.Part.Part1)
            {
                Direction direction = Direction.Up;
                Point     position  = new Point(0, 0);
                foreach (string s in _input)
                {
                    direction = Board2D <Int64> .Turn(direction, (s[0] == 'R')?Direction.Right : Direction.Left);

                    position = Board2D <Int64> .MoveForward(position, direction, Int32.Parse(s[1..]));
Beispiel #6
0
            private void Move()
            {
                _steps++;
                _position = Board2D <Int64> .MoveForward(_position, _direction, 1, true);

                char c = _network[_position.Y][_position.X];

                if ((c >= 'A') && (c <= 'Z'))
                {
                    _letters += c;
                }
            }
Beispiel #7
0
        private long Paint(long initial)
        {
            long painted = 0;

            _hull       = new Board2D <long>();
            _hull[0, 0] = initial;
            _painted    = new Board2D <bool>();
            _direction  = Direction.Up;
            _position   = new Point(0, 0);
            _cpu.Reset(Aoc.Framework.Input.GetLongVector(this, ","));
            _cpu.Input.Enqueue(_hull[_position.X, _position.Y]);
            while (_cpu.State != IntCpu.RunningState.Halted)
            {
                _cpu.Run();

                if (_cpu.State != IntCpu.RunningState.Halted)
                {
                    if (!_painted[_position.X, _position.Y])
                    {
                        _painted[_position.X, _position.Y] = true;
                        painted++;
                    }

                    _hull[_position.X, _position.Y] = _cpu.Output.Dequeue();
                    long turn = _cpu.Output.Dequeue();
                    if (turn == 0)
                    {
                        _direction = Board2D <long> .Turn(_direction, Direction.Left);
                    }

                    if (turn == 1)
                    {
                        _direction = Board2D <long> .Turn(_direction, Direction.Right);
                    }

                    _position = Board2D <long> .MoveForward(_position, _direction);

                    _cpu.Input.Enqueue(_hull[_position.X, _position.Y]);
                }
            }

            return(painted);
        }
Beispiel #8
0
            public Point Move(Point from, Board2D <Track> tracks)
            {
                // Move the cart
                Point next = Board2D <Track> .MoveForward(from, Direction, 1, true);

                // Change the direction if needed
                Track cell = tracks[next.X, next.Y];

                if (cell.IsIntersection)
                {
                    Direction = Board2D <Track> .Turn(Direction, DirectionChooser[DirectionIndex]);

                    DirectionIndex = (DirectionIndex + 1) % DirectionChooser.Length;
                }
                else
                {
                    // We need to follow the track
                    Direction = cell.GetNextDirection(Direction);
                }

                return(next);
            }
Beispiel #9
0
        private string FindCode(Board2D <int> board, Point position)
        {
            // Look for the code
            string chars = "0123456789ABCD";
            string code  = "";

            foreach (string s in _input)
            {
                if (s != "")
                {
                    foreach (char c in s)
                    {
                        Direction d = Direction.Up;
                        if (c == 'L')
                        {
                            d = Direction.Left;
                        }
                        if (c == 'R')
                        {
                            d = Direction.Right;
                        }
                        if (c == 'D')
                        {
                            d = Direction.Down;
                        }

                        position = Board2D <Int64> .MoveForward(position, d);

                        if (board[position.X, position.Y] == 0)
                        {
                            position = Board2D <Int64> .MoveBackward(position, d);
                        }
                    }
                    code += chars[board[position.X, position.Y]];
                }
            }
            return(code);
        }
Beispiel #10
0
        private void Move(Direction d)
        {
            // Get the place we want to visit
            Point moved = Board2D <long> .MoveForward(_position, d);

            // Check if there's a wall
            if (_board[moved] == -1)
            {
                return;
            }

            // Check if it has been visited
            if (_board[moved] > 0)
            {
                // Already visited, update its distance
                if (_board[moved] > _board[_position])
                {
                    _board[moved] = _board[_position] + 1;
                }

                // Don't propragate
                return;
            }

            // Ask the robot to visit the place
            _cpu.Input.Enqueue(DirectionToMovement[(int)d]);
            _cpu.Run(true);
            long result = _cpu.Output.Dequeue();

            switch (result)
            {
            case 0:
            {
                // We hit a wall
                _board[moved] = -1;
                return;
            }

            case 1:
            case 2:
            {
                _board[moved] = _board[_position] + 1;
                _position     = moved;
                if (result == 2)
                {
                    _oxygen = _position;
                }

                // Process other movements
                Move(Direction.Up);
                Move(Direction.Down);
                Move(Direction.Left);
                Move(Direction.Right);

                // Once explored, backtrack
                BackTrack(d);

                // All done
                return;
            }
            }
        }