From 3c98bec85ab1b6bc10d3484e4123f4ad7b60c62d Mon Sep 17 00:00:00 2001 From: oabrivard Date: Thu, 21 Dec 2023 23:04:34 +0100 Subject: [PATCH] Completed part 1 of Day 21 puzzle, with help to cut the number of path to explore --- day21/day21.go | 253 ++++++++++++++++++++++++++++++++++++++++++++ day21/day21_test.go | 64 +++++++++++ day21/input.txt | 131 +++++++++++++++++++++++ utils/queue.go | 45 ++++++++ utils/utils.go | 9 ++ 5 files changed, 502 insertions(+) create mode 100644 day21/day21.go create mode 100644 day21/day21_test.go create mode 100644 day21/input.txt create mode 100644 utils/queue.go diff --git a/day21/day21.go b/day21/day21.go new file mode 100644 index 0000000..b6d484a --- /dev/null +++ b/day21/day21.go @@ -0,0 +1,253 @@ +package day21 + +import ( + "fmt" + + "gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils" +) + +type Coord struct { + row int + col int +} + +func BFS1(matrix [][]byte, root Coord, maxSteps int) int { + height := len(matrix) + width := len(matrix[0]) + queue := utils.NewQueue[*Coord]() + + matrix[root.row][root.col] = 'O' + queue.Enqueue(&root) + + moves := 0 + for moves < maxSteps { + //fmt.Println(moves + 1) + newQueue := utils.NewQueue[*Coord]() + + for queue.HasElement() { + coord := queue.Dequeue() + matrix[coord.row][coord.col] = '.' + + if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' { + newCoord := Coord{coord.row - 1, coord.col} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + } + + if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' { + newCoord := Coord{coord.row + 1, coord.col} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + } + + if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' { + newCoord := Coord{coord.row, coord.col - 1} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + } + + if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' { + newCoord := Coord{coord.row, coord.col + 1} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + } + } + + queue = newQueue + moves++ + } + + // count 'O' in matrix + count := 0 + for r := range matrix { + for _, b := range matrix[r] { + if b == 'O' { + count++ + } + } + } + + return count +} + +func redrawFromCache(matrix [][]byte, cacheQueue utils.Queue[*Coord]) { + for _, coord := range cacheQueue.GetData() { + if coord != nil { + matrix[coord.row][coord.col] = 'O' + } + } +} + +func BFS2(matrix [][]byte, root Coord, maxSteps int) int { + height := len(matrix) + width := len(matrix[0]) + queue := utils.NewQueue[*Coord]() + + cache := make([][]utils.Queue[*Coord], height) + for r, row := range matrix { + cache[r] = make([]utils.Queue[*Coord], width) + for c := range row { + cache[r][c] = utils.NewQueue[*Coord]() + } + } + + matrix[root.row][root.col] = 'O' + queue.Enqueue(&root) + + moves := 0 + for moves < maxSteps { + fmt.Println(moves + 1) + newQueue := utils.NewQueue[*Coord]() + + for queue.HasElement() { + coord := queue.Dequeue() + + if cache[coord.row][coord.col].HasElement() { + + matrix[coord.row][coord.col] = '.' + redrawFromCache(matrix, cache[coord.row][coord.col]) + + } else { + cacheQueue := utils.NewQueue[*Coord]() + matrix[coord.row][coord.col] = '.' + + if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' { + newCoord := Coord{coord.row - 1, coord.col} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + cacheQueue.Enqueue(&newCoord) + } + + if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' { + newCoord := Coord{coord.row + 1, coord.col} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + cacheQueue.Enqueue(&newCoord) + } + + if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' { + newCoord := Coord{coord.row, coord.col - 1} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + cacheQueue.Enqueue(&newCoord) + } + + if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' { + newCoord := Coord{coord.row, coord.col + 1} + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + cacheQueue.Enqueue(&newCoord) + } + + cache[coord.row][coord.col] = cacheQueue + } + } + + queue = newQueue + moves++ + } + + // count 'O' in matrix + count := 0 + for r := range matrix { + for _, b := range matrix[r] { + if b == 'O' { + count++ + } + } + } + + return count +} + +func BFS3(matrix [][]byte, root Coord, maxSteps int) int { + height := len(matrix) + width := len(matrix[0]) + queue := utils.NewQueue[*Coord]() + + matrix[root.row][root.col] = 'O' + queue.Enqueue(&root) + + moves := 0 + for moves < maxSteps { + //fmt.Println(moves + 1) + newQueue := utils.NewQueue[*Coord]() + coordInQueue := map[Coord]bool{} + + for queue.HasElement() { + coord := queue.Dequeue() + matrix[coord.row][coord.col] = '.' + + if coord.row > 0 && matrix[coord.row-1][coord.col] != '#' { + newCoord := Coord{coord.row - 1, coord.col} + if !coordInQueue[newCoord] { + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + coordInQueue[newCoord] = true + } + } + + if coord.row < height-1 && matrix[coord.row+1][coord.col] != '#' { + newCoord := Coord{coord.row + 1, coord.col} + if !coordInQueue[newCoord] { + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + coordInQueue[newCoord] = true + } + } + + if coord.col > 0 && matrix[coord.row][coord.col-1] != '#' { + newCoord := Coord{coord.row, coord.col - 1} + if !coordInQueue[newCoord] { + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + coordInQueue[newCoord] = true + } + } + + if coord.col < width-1 && matrix[coord.row][coord.col+1] != '#' { + newCoord := Coord{coord.row, coord.col + 1} + if !coordInQueue[newCoord] { + newQueue.Enqueue(&newCoord) + matrix[newCoord.row][newCoord.col] = 'O' + coordInQueue[newCoord] = true + } + } + } + + queue = newQueue + moves++ + } + + // count 'O' in matrix + count := 0 + for r := range matrix { + for _, b := range matrix[r] { + if b == 'O' { + count++ + } + } + } + + return count +} + +func Part1(lines []string, maxSteps int) int { + matrix := make([][]byte, len(lines)) + + var root Coord + for r, line := range lines { + matrix[r] = make([]byte, len(line)) + for c, b := range line { + matrix[r][c] = byte(b) + if b == 'S' { + root.row = r + root.col = c + } + } + } + + result := BFS3(matrix, root, maxSteps) + + return result +} diff --git a/day21/day21_test.go b/day21/day21_test.go new file mode 100644 index 0000000..08b9376 --- /dev/null +++ b/day21/day21_test.go @@ -0,0 +1,64 @@ +package day21 + +import ( + "fmt" + "testing" + + "gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils" +) + +func TestPart1(t *testing.T) { + lines := []string{ + "...........", + ".....###.#.", + ".###.##..#.", + "..#.#...#..", + "....#.#....", + ".##..S####.", + ".##..#...#.", + ".......##..", + ".##.#.####.", + ".##..##.##.", + "...........", + } + + result := Part1(lines, 1) + + if result != 2 { + t.Fatalf("expected 2, got %d", result) + } + + result = Part1(lines, 2) + + if result != 4 { + t.Fatalf("expected 4, got %d", result) + } + + result = Part1(lines, 3) + + if result != 6 { + t.Fatalf("expected 6, got %d", result) + } + + result = Part1(lines, 6) + + if result != 16 { + t.Fatalf("expected 16, got %d", result) + } + + for i := 1; i < 20; i++ { + result = Part1(lines, i) + + fmt.Println(i, " : ", result) + } +} + +func TestPart1WithInput(t *testing.T) { + lines := utils.ReadLines("input.txt") + + result := Part1(lines, 64) + + if result != 3758 { + t.Fatalf("expected 3758, got %d", result) + } +} diff --git a/day21/input.txt b/day21/input.txt new file mode 100644 index 0000000..5f40d68 --- /dev/null +++ b/day21/input.txt @@ -0,0 +1,131 @@ +................................................................................................................................... +..##....#...#.............#......................#......#..............#....#....#.#...............#......#.....#.....#............ +..##.......#......#...###..#...#............................................................#............#..#.....#................ +.....##...#.......................#..#.......#...#.#..#..................................#.........#.............#.#.##............ +............##....................#.....#........#..##....................#..........#...........#...............................#. +..#.......#...........................#..#.##..#.....##.........#......................#...#...##.........#.............#.#....#... +.....##.................#.#.###..#.........#................................#.......#....#..#.........#...#.......##..#..........#. +.#....#.........#.......#....#.##..#.....#........................#.............#......#.......#...............#......#.........#.. +......#.............#......#.#................#...#..........................#...........#..#.....#.......#...........#....#...#... +..........#....#...............#....................#.............#.............##..#.#.#.#.......#...........##..............#.... +..###.....#......#.......#...#....#.....#.........#...................................#.#....#..#..#...#...#......#................ +....#.........#.#..........##.#............#....................................#....#..............###............#....#.......#.. +....#....#............#...............#.....................#...#.#...#..................#.............................#........... +..............#...#.........#......#.....#...............#...........................#.............#...#........................... +.................#............#............#.#.....................#.....#..........#..#..#..##..........#.............#...#....... +................##......#.............#..............................#....#............#..#.........##........##......#..........#. +......#..........#...#..#............#..#.....................##...#....#.#.................................#.....#...........##... +..........#.....#......#...#......#......##...........#.....#...........#.#..#................#..#..#.....#...#......#...#...#...#. +..........#........#...#...........##....#.........#...#.....#...............#........................#...#.................#...... +.........#.....#...#....#.....#.......................##...#......#........................#.............#.......#....#..#....#.... +..#............#.#.....#............................###...#.#.#....#..###...................###..#.#........#....#......#........#. +...#........#....#.#........##....#..#.............##.....#....#.......#......#.......................#...#.............#........#. +.......#...###..#..................#.............#......#.............................................#....#.......#......#..#.#... +....................................##.........#..............#...........#.................##....#..............#.#........#...... +.#....##......#.............#.....................#....#..........##..#..##....#.........................#......................#.. +...........#.............#........#...........#............................##....#...#........#..........##.##....#.....#.#........ +.#..................##..#.......#.............#........#..#.#........#............#...................#.#...##.#.#................. +.....#.....#.....#...........#.#....................#.....#..#..#............#.........#.........#......#......#...............#... +.....#........#..#....#..............................#..#...........#............#....#.#...................#.....#.#........#..#.. +.....#.......#......#...#...#...........#.......#.......#.................................#..........#...#.#......#.............#.. +......#..........#........#..................#...#.........##.....#.............##...#..............#................#...........#. +................#........#...#..............#.......##......#.#....##...#.....#..#......#...#.......#.................#....#.#...#. +.....##.......#.....###.........................................#..........###.....#...##......................#............#...... +...##..#....#........................#........#..##.#.##.#.........#...#........#.#.........#...................#.#...........#..#. +....#..............#...............#...................#............#.......................#...........#..#.#..................... +...##............#..#...............#.#.#.....#............................##..#.#.........#..#.................................... +........####..#.#.................#..#.......#.#...................................#.........................#..#...........#.#.... +....................................##.....#.............##..#....#.........##.....#..............................#......#.#....... +..#.........##..##.#...................#....#...............#.......#.........#..............................#.#.#.....#....#..#... +..........#...#..#....#.........#..#........#.........##......#......#.............###.....#.......#...................##.#.#...... +.........#....................#...##.......#............##..........#..#..#...#....#..........#..............#........#...#.##..... +.#........#..........................#.......##....#.#...#......#........#.....#...........#.....................#......#.......... +...................................................................#..##.............###..........##............#........#.......#. +.#..............................................#.#.#.......#.........#........#................................#...#....#......... +..............#.#.............####.....#.#.....#......#.........#...............#......#...#.....##..............##.#......##...... +...##...#...#..............#.......#.#....#....#.....#..#......#...#.#.#...#..#...............#.......................#........#... +........#..#................#.....#..#.#.............#.#....#......#.................................................#............. +...#...#......#..............#..#.......#...#.....#.#..##..............##...............#..#.#.#........#...............#.......... +......#.....................#..##..#..........#........#....##............#......#.........#.....#....#.......................#.#.. +.........#.#.........#...............#.#...........#....#......#...........#..#..#.........................................#....... +..##..............................##...#......#...........#...........#...........................#.....................#..#....... +.....#...................#.#.#...........###....#.....................##...........................#...........#........#.#....#... +.#.....#................#..##........##....#............#..........#............#....#...#..#.....#...........#...............#.... +........#.............##.#.......................#.......................#...#......#.####.............#....................#...... +....#...............#....#......#.#.............##........#....#.......#...#..#............#.......................#..........##... +.#.#..................#..#..............#......#..#............#...#.......#.#....#.#..#......#.#.#.##.......#......#...........##. +.................#.......#.........#...........#.......#.......#...#....................###......#.....#..#.....#..............#... +..#...............#.....#.#.....#....#.#.......#..#..........#.............................#......#...#............#............#.. +...........#....##...##...........#...#...........#.................#...........................#...##....#........................ +.#.........#.....##.........###......#................##...#..#.#......#...................#.#...................#......#.......... +..................#.#........##...............#.......#..#...#..#.........##....#.#....#.............#................##........... +........#..................#..........#..#....#.............#.............#.........#...............#........#..................... +...................#...............#....#.....#................#...#.............#.......................#.#.....#..#......#....... +.......#..###.............#..#........#..................#........................#...................#...#..........##....#....... +.......#................##...................#.................................#.#.....#..#............#.......#........#.......... +.................................................................S................................................................. +........###..#.........#.........##..............#..............#.#.....#.......##.......#.....#...#.............#................. +............#.................#....#.....................................#...#..#...#.............#............##.....#............ +.............#..............................................................#.##..........................#.........#.............. +........##...................#.....#..#...#.....#.....#.............#............#...#..#........#.......#.#............#.......... +.#.........#.......#......#....#...##.###.....#..#..........##........#....#....#.##.......#......#..##.............#.#............ +..............#.....#.....#.......#...................#......#....##....#.#............#.................##........................ +..#........#.....#.#.#.#.............#.#............#....#......#.......#...........#.......##..#.....#.#.##...####....#.......#... +.#..............#....#.......#........................#........#........#.#.#...#..........#........#..##..#...#..#...........#.... +....#..........#.##.##.##......##....#...............#.............#..#...#...........#.###...........#.....##.#...#............#.. +.#.................#..............#.................#..........#.....#..................#..................#....................... +...#.##............#..#.....#.......#......##.#....#...........#...................#.#............#.##.#.....#.................#.#. +......#.............#.....#...#.............#.......................##....##............#.##..#..#.......#......................#.. +...#...............#.........#.#...........#......#.....##..#...#..#.........#.#....#......#...#....#......#.#...................#. +.......#...............#..##.......#..#.....#.....#.....#..#.#....##..#....#..........##........#.........................#...#.... +.......#..#.................##..............#.......#.#....................#.#....#....#..................#............##.......... +.......#.............#.............#....#.#.###...........#....#...#......#........#......#.....#........#...#..................... +........#.....................#.#...#....................................#..#..#....#..#.......#.......................#.#....#.... +..#.....##............#................#........##...#.....##..............#.....#............##..#..#...............#....#....#... +....#.#..................###.##..#.#...#...........................#.#.............#...##.#.............#.....................##... +.............#..............#......#..................................#...................#.........#.....#.......#..#..#.......... +.....#..#......#.............#.............#...#.........#....##....##..................#.........#................#.....#...#.#... +.................#............................#...........#..............#.....#....#.#.........#....#.#........#........#......... +..#.......#............................#.#....#.##.......................#..................#.#....####..........#.#...#.....##.... +......#...#.....#...............#.#..........##....#........#..............#.......#...#...#...................#...........#.#..... +.....................#.......#..#.............#...................#..............................#...............#.....#....#...... +....#..#.......#.........................#.#..........#....#...............#............#.......#...........................#...... +.........#......#...............##.#......#................#....#.....#................#.....#.#....................#..#........... +..#....#..#...#....#.#................#..#............#.#.#.............#.#....#......#.#.................#....#..#.........#....#. +.....#.....#..#..................................#......#.......#............................................#.............#...#... +.##..#.................#...............#...........................#...........#..#.......#............................#.....#..... +.................##......##...........#.#.....#......#.........#......#.......#.........#....#.............##.....#............#... +....#....#...##...#...#....##.........#......##.................#.........#.......#....#...#...................#....#...#.....#.... +........#.#......................................#.............#......#.#.#.....#.......#.............##...#.....#................. +.#.....#.#..............................................#.#...##......................#.....#........##..#............#....#....... +.........#........#........................##..#........##....#.#...#......#.#...#...#.............#.......#..#.#.................. +........#..#.#...............#...........##.....#....#...#..#..#..........#......#......#..........#.....#.....##.........#.....##. +...#....#...#.........#..#.#...#.#........##...#............#..##.#.##.#..##............#.........#.#..........#................... +.#...........##..#........##....#.............#...#...#.......#.............#...#.#...#............#.........#.............##...... +.#.....................#......................#...........#...#.....#...#..............................#.........#.....#.#....#.#.. +............#......#...............................#......#....#...............#...................#....................#.......... +...##...............................#...............#..##........................#....................#.#..#...##................#. +...#..#......#..#....#....#...#.#...#.....................#.#......#.#..........................#..#............#....#....#........ +.....##.#.....#..........#..#......##............##.........#.........#.....##.....#............#.............#...........##...#... +...........#....#............#......#....................#...#..........##......#................##.........##....#...#............ +.....##...........#.....#.#.............#............#........................#.............#......##..#......#..#.....#........#.. +...#.#......#.......#..#.................#................#..#........#...................###............##....#..#..........##.... +.#..#.................###....##......................#.#...................#...............#...#.#....#.#.##...........#.......#... +....#..#................#........#..#................................#.......#...........#.......#.#..............##....#......#... +......#................#....#................#............#.#...#......#...............#............#..##....#..................#.. +.........#..................................#.#...........#..................................#............#.#..........##..##.#.... +.#..............#......#...........####.....#..............#.............................#...#......#....#........#.............#.. +....####...........#..#....#.............#.....#...........#...#..........................#..#....#.....#..#...........#.........#. +.....#.#.....#...........................#.....#...........#...............................##...............##..#.#.#.........#.... +.##............#.#.#.#....##.#...#.#.............................................#.........#......#.#.............#...##........... +.#....#.................#.#....#............#............................................#........#...........#..#................. +..................#....#.##.#.#.#..........#........#.............#....................#...........#.....#......................... +.........#...#.........#..................#........#...............#.................#......##........#........#.#.#.......##....#. +.......#.......#......#.......##........#....#....#.#.......................................#..............#.....#.....#...#..#.... +......#.................#.........##....#.......................#...............#.#.....................#..#....###.#........##.... +.......#....#.....#.............................................................#..........#..#.............#..#.#..#.............. +.#.....#................#...#....#..#....##..#..##........................................#...#..............#.....#...........##.. +........#....#...##..#.....#.#.........#..............#.........................................................#......#..#.....##. +....#..#.#....#..............................#.#.....##..##...........................#...............#......#..................... +.##.....#.#...........##.......#........#....#.........................##.#......#.........................#....................... +................................................................................................................................... diff --git a/utils/queue.go b/utils/queue.go new file mode 100644 index 0000000..6d114e0 --- /dev/null +++ b/utils/queue.go @@ -0,0 +1,45 @@ +package utils + +type Queue[T any] struct { + data []T + len int +} + +// New creates an empty stack +func NewQueue[T any]() Queue[T] { + q := Queue[T]{ + []T{}, + 0, + } + + return q +} + +// Push pushes the value v on top of stack s. +func (q *Queue[T]) Enqueue(v T) { + q.data = append(q.data, v) + q.len++ +} + +func (q *Queue[T]) Dequeue() T { + if !q.HasElement() { + panic("called Dequeue() on an empty queue") + } + + value := q.data[0] + var zeroValue T + q.data[0] = zeroValue + q.data = q.data[1:] + + q.len-- + + return value +} + +func (q *Queue[T]) HasElement() bool { + return q.len > 0 +} + +func (q *Queue[T]) GetData() []T { + return q.data +} diff --git a/utils/utils.go b/utils/utils.go index bc59dea..dd3439b 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -191,3 +191,12 @@ func Map[T, M any](s []T, f func(T) M) []M { } return res } + +func DuplicateMatrix[T any](matrix [][]T) [][]T { + duplicate := make([][]T, len(matrix)) + for i := range matrix { + duplicate[i] = make([]T, len(matrix[i])) + copy(duplicate[i], matrix[i]) + } + return duplicate +}