Пример #1
0
        public static Board2D <T> GetBoard2D <T>(IDay day, Func <char, T> parser, string row = "\r\n")
        {
            string raw = GetString(day);

            if (raw == null)
            {
                return(null);
            }

            String[]    lines = raw.Split(row);
            Board2D <T> board = new Board2D <T>();

            for (int y = 0; y < lines.Length; ++y)
            {
                for (int x = 0; x < lines[y].Length; ++x)
                {
                    board[x, y] = parser(lines[y][x]);
                }
            }

            return(board);
        }
Пример #2
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);
        }
Пример #3
0
        private bool GetNextState(Board2D <bool> board, int x, int y)
        {
            int count = 0;

            for (int i = x - 1; i <= x + 1; ++i)
            {
                for (int j = y - 1; j <= y + 1; ++j)
                {
                    if (board[i, j])
                    {
                        count++;
                    }
                }
            }
            if (board[x, y])
            {
                return((count == 3) || (count == 4));
            }
            else
            {
                return(count == 3);
            }
        }
Пример #4
0
        private int CountAround(Board2D <Cell> current, int x, int y, Cell cell)
        {
            // Count the cell around us
            int count = 0;

            for (int i = x - 1; i <= x + 1; ++i)
            {
                for (int j = y - 1; j <= y + 1; ++j)
                {
                    if (current[i, j] == cell)
                    {
                        count++;
                    }
                }
            }

            if (current[x, y] == cell)
            {
                count--;
            }

            return(count);
        }
Пример #5
0
        private Board2D <Cell> Tick(Board2D <Cell> current)
        {
            Board2D <Cell> after = new Board2D <Cell>();

            for (int x = 0; x < 50; ++x)
            {
                for (int y = 0; y < 50; ++y)
                {
                    switch (current[x, y])
                    {
                    case Cell.Open:
                    {
                        int trees = CountAround(current, x, y, Cell.Tree);
                        after[x, y] = trees >= 3 ? Cell.Tree : Cell.Open;
                        break;
                    }

                    case Cell.Tree:
                    {
                        int lumberyards = CountAround(current, x, y, Cell.Lumberyard);
                        after[x, y] = lumberyards >= 3 ? Cell.Lumberyard : Cell.Tree;
                        break;
                    }

                    case Cell.Lumberyard:
                    {
                        int lumberyards = CountAround(current, x, y, Cell.Lumberyard);
                        int trees       = CountAround(current, x, y, Cell.Tree);
                        after[x, y] = (lumberyards >= 1 && trees >= 1) ? Cell.Lumberyard : Cell.Open;
                        break;
                    }
                    }
                }
            }
            return(after);
        }
Пример #6
0
 public void Init()
 {
     _input = Aoc.Framework.Input.GetInt(this);
     _board = new Board2D <int?>();
 }
Пример #7
0
 public void Init()
 {
     _cpu   = new IntCpu();
     _board = new Board2D <long>();
 }
Пример #8
0
        public string Run(Aoc.Framework.Part part)
        {
            if (part == Aoc.Framework.Part.Part1)
            {
                // Pass time
                Board2D <Cell> current = _ground;
                for (int i = 0; i < 10; ++i)
                {
                    current = Tick(current);
                }

                // Calculate result
                var result = current.Values.Count(v => v == Cell.Tree) * current.Values.Count(v => v == Cell.Lumberyard);
                return(result.ToString());
            }

            if (part == Aoc.Framework.Part.Part2)
            {
                // Run a long time in order to stabilize
                Board2D <Cell> current = _ground;
                for (int i = 0; i < 1000; ++i)
                {
                    current = Tick(current);
                }

                // Look for a cycle
                Dictionary <string, int> recorded = new Dictionary <string, int>();
                int index = 1000;
                while (index < 1000000000)
                {
                    string hash = string.Join("", current.Cells.OrderBy(cell => cell.Item1.Y).ThenBy(cell => cell.Item1.Y).Select(cell => ((int)cell.Item2).ToString()));
                    if (recorded.ContainsKey(hash))
                    {
                        // Cycle found !
                        int start       = recorded[hash];
                        int cycleLength = index - start;

                        // Advance the index
                        index += cycleLength * ((1000000000 - index) / cycleLength);

                        // Exit this loop
                        break;
                    }
                    recorded.Add(hash, index);
                    current = Tick(current);
                    index++;
                }

                // Iterate a few more times
                while (index < 1000000000)
                {
                    current = Tick(current);
                }

                // Calculate result
                var result = current.Values.Count(v => v == Cell.Tree) * current.Values.Count(v => v == Cell.Lumberyard);
                return(result.ToString());
            }

            return("");
        }
Пример #9
0
        public string Run(Aoc.Framework.Part part)
        {
            if (part == Aoc.Framework.Part.Part1)
            {
                Board2D <bool> board = new Board2D <bool>();
                foreach (string instruction in _instructions)
                {
                    // Parse the instruction
                    string[] items = instruction.Split(" ");

                    // Process the instruction
                    switch (items[0])
                    {
                    // turn on 931,331 through 939,812
                    // turn off 756,53 through 923,339
                    case "turn":
                    {
                        Point from = ParsePoint(items[2]);
                        Point to   = ParsePoint(items[4]);
                        bool  mode = items[1] == "on";
                        for (int x = from.X; x <= to.X; ++x)
                        {
                            for (int y = from.Y; y <= to.Y; ++y)
                            {
                                board[x, y] = mode;
                            }
                        }
                        break;
                    }

                    // toggle 756,965 through 812,992
                    case "toggle":
                    {
                        Point from = ParsePoint(items[1]);
                        Point to   = ParsePoint(items[3]);
                        bool  mode = items[1] == "on";
                        for (int x = from.X; x <= to.X; ++x)
                        {
                            for (int y = from.Y; y <= to.Y; ++y)
                            {
                                board[x, y] = !board[x, y];
                            }
                        }
                        break;
                    }
                    }
                }

                return(board.Values.Count(light => light).ToString());
            }

            if (part == Aoc.Framework.Part.Part2)
            {
                Board2D <int> board = new Board2D <int>();
                foreach (string instruction in _instructions)
                {
                    // Parse the instruction
                    string[] items = instruction.Split(" ");

                    // Process the instruction
                    switch (items[0])
                    {
                    // turn on 931,331 through 939,812
                    // turn off 756,53 through 923,339
                    case "turn":
                    {
                        Point from = ParsePoint(items[2]);
                        Point to   = ParsePoint(items[4]);
                        bool  mode = items[1] == "on";
                        for (int x = from.X; x <= to.X; ++x)
                        {
                            for (int y = from.Y; y <= to.Y; ++y)
                            {
                                board[x, y] = mode ? board[x, y] + 1 : Math.Max(board[x, y] - 1, 0);
                            }
                        }
                        break;
                    }

                    // toggle 756,965 through 812,992
                    case "toggle":
                    {
                        Point from = ParsePoint(items[1]);
                        Point to   = ParsePoint(items[3]);
                        bool  mode = items[1] == "on";
                        for (int x = from.X; x <= to.X; ++x)
                        {
                            for (int y = from.Y; y <= to.Y; ++y)
                            {
                                board[x, y] += 2;
                            }
                        }
                        break;
                    }
                    }
                }

                return(board.Values.Sum().ToString());
            }

            return("");
        }
Пример #10
0
 public void Init()
 {
     _input = Aoc.Framework.Input.GetInt(this);
     _cells = new Board2D <int>();
     BuildPowerLevels();
 }
Пример #11
0
        public void Init()
        {
            _tracks = new Board2D <Track>();
            _carts  = new Board2D <Cart>();
            string[] input = Aoc.Framework.Input.GetStringVector(this);
            for (int y = 0; y < input.Length; ++y)
            {
                for (int x = 0; x < input[y].Length; ++x)
                {
                    switch (input[y][x])
                    {
                    case '|':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Up, Direction.Down
                            });
                        break;
                    }

                    case '^':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Up, Direction.Down
                            });
                        _carts[x, y] = new Cart {
                            Direction = Direction.Up
                        };
                        break;
                    }

                    case 'v':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Up, Direction.Down
                            });
                        _carts[x, y] = new Cart {
                            Direction = Direction.Down
                        };
                        break;
                    }

                    case '-':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Left, Direction.Right
                            });
                        break;
                    }

                    case '>':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Left, Direction.Right
                            });
                        _carts[x, y] = new Cart {
                            Direction = Direction.Right
                        };
                        break;
                    }

                    case '<':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Left, Direction.Right
                            });
                        _carts[x, y] = new Cart {
                            Direction = Direction.Left
                        };
                        break;
                    }

                    case '/':
                    {
                        if (_tracks[x - 1, y] != null && _tracks[x - 1, y].Directions.Contains(Direction.Right))
                        {
                            _tracks[x, y] = new Track(new List <Direction> {
                                    Direction.Left, Direction.Up
                                });
                        }
                        else
                        {
                            _tracks[x, y] = new Track(new List <Direction> {
                                    Direction.Down, Direction.Right
                                });
                        }
                        break;
                    }

                    case '\\':
                    {
                        if (_tracks[x - 1, y] != null && _tracks[x - 1, y].Directions.Contains(Direction.Right))
                        {
                            _tracks[x, y] = new Track(new List <Direction> {
                                    Direction.Left, Direction.Down
                                });
                        }
                        else
                        {
                            _tracks[x, y] = new Track(new List <Direction> {
                                    Direction.Up, Direction.Right
                                });
                        }
                        break;
                    }

                    case '+':
                    {
                        _tracks[x, y] = new Track(new List <Direction> {
                                Direction.Left, Direction.Right, Direction.Up, Direction.Down
                            });
                        break;
                    }
                    }
                }
            }
        }
Пример #12
0
        public string Run(Aoc.Framework.Part part)
        {
            if (part == Aoc.Framework.Part.Part1)
            {
                // Initial position
                Board2D <int> grid = new Board2D <int>();
                int           x    = 0;
                int           y    = 0;
                grid[x, y] += 1;

                // Follow the instructions
                foreach (char c in _input)
                {
                    switch (c)
                    {
                    case '^':
                    {
                        y++;
                        break;
                    }

                    case 'v':
                    {
                        y--;
                        break;
                    }

                    case '>':
                    {
                        x++;
                        break;
                    }

                    case '<':
                    {
                        x--;
                        break;
                    }
                    }

                    grid[x, y] += 1;
                }

                // Count houses with gift
                return(grid.Values.Where(v => v >= 1).Count().ToString());
            }

            if (part == Aoc.Framework.Part.Part2)
            {
                // Initial position
                Board2D <int> grid = new Board2D <int>();
                int           x1   = 0;
                int           y1   = 0;
                int           x2   = 0;
                int           y2   = 0;
                grid[0, 0] += 2;

                // Follow the instructions
                for (int i = 0; i < _input.Length; i += 2)
                {
                    switch (_input[i])
                    {
                    case '^':
                    {
                        y1++;
                        break;
                    }

                    case 'v':
                    {
                        y1--;
                        break;
                    }

                    case '>':
                    {
                        x1++;
                        break;
                    }

                    case '<':
                    {
                        x1--;
                        break;
                    }
                    }

                    switch (_input[i + 1])
                    {
                    case '^':
                    {
                        y2++;
                        break;
                    }

                    case 'v':
                    {
                        y2--;
                        break;
                    }

                    case '>':
                    {
                        x2++;
                        break;
                    }

                    case '<':
                    {
                        x2--;
                        break;
                    }
                    }

                    grid[x1, y1] += 1;
                    grid[x2, y2] += 1;
                }

                // Count houses with gift
                return(grid.Values.Where(v => v >= 1).Count().ToString());
            }

            return("");
        }
Пример #13
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;
            }
            }
        }
Пример #14
0
        private Board2D <Cell> BuildMap()
        {
            Board2D <Cell>          map   = new Board2D <Cell>();
            Queue <(string, Point)> queue = new Queue <(string, Point)>();

            queue.Enqueue((_regex, new Point(0, 0)));
            map[0, 0] = Cell.Room;

            while (queue.TryDequeue(out var from))
            {
                bool  straight = true;
                int   index    = 0;
                Point position = from.Item2;

                while (straight && index < from.Item1.Length)
                {
                    switch (from.Item1[index])
                    {
                    case '^':
                    {
                        // Ignore
                        index++;
                        break;
                    }

                    case '$':
                    {
                        // Finished !
                        straight = false;
                        break;
                    }

                    case 'N':
                    {
                        position = Move(position, map, 0, -1);
                        index++;
                        break;
                    }

                    case 'W':
                    {
                        position = Move(position, map, -1, 0);
                        index++;
                        break;
                    }

                    case 'E':
                    {
                        position = Move(position, map, 1, 0);
                        index++;
                        break;
                    }

                    case 'S':
                    {
                        position = Move(position, map, 0, 1);
                        index++;
                        break;
                    }

                    case '(':
                    {
                        // Start a new fork
                        StartFork(index, from.Item1, position, queue);
                        straight = false;
                        break;
                    }
                    }
                }
            }

            return(map);
        }
Пример #15
0
 private void EnqueueIfValid(int x, int y, int xoffset, int yoffset, Board2D <int> pathes, Board2D <Cell> map, Queue <Point> queue)
 {
     if (map[x + xoffset, y + yoffset] == Cell.Door && pathes[x + 2 * xoffset, y + yoffset * 2] <= 0)
     {
         pathes[x + 2 * xoffset, y + yoffset * 2] = pathes[x, y] + 1;
         queue.Enqueue(new Point(x + 2 * xoffset, y + yoffset * 2));
     }
 }
Пример #16
0
 private Point Move(Point from, Board2D <Cell> map, int xoffset, int yoffset)
 {
     map[from.X + xoffset, from.Y + yoffset]         = Cell.Door;
     map[from.X + 2 * xoffset, from.Y + 2 * yoffset] = Cell.Room;
     return(new Point(from.X + 2 * xoffset, from.Y + 2 * yoffset));
 }