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); }
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); }
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); } }
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); }
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); }
public void Init() { _input = Aoc.Framework.Input.GetInt(this); _board = new Board2D <int?>(); }
public void Init() { _cpu = new IntCpu(); _board = new Board2D <long>(); }
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(""); }
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(""); }
public void Init() { _input = Aoc.Framework.Input.GetInt(this); _cells = new Board2D <int>(); BuildPowerLevels(); }
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; } } } } }
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(""); }
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; } } }
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); }
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)); } }
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)); }