Completed part 1 of Day 21 puzzle, with help to cut the number of path to explore

main
oabrivard 2 years ago
parent c431e8741b
commit 3c98bec85a

@ -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
}

@ -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)
}
}

@ -0,0 +1,131 @@
...................................................................................................................................
..##....#...#.............#......................#......#..............#....#....#.#...............#......#.....#.....#............
..##.......#......#...###..#...#............................................................#............#..#.....#................
.....##...#.......................#..#.......#...#.#..#..................................#.........#.............#.#.##............
............##....................#.....#........#..##....................#..........#...........#...............................#.
..#.......#...........................#..#.##..#.....##.........#......................#...#...##.........#.............#.#....#...
.....##.................#.#.###..#.........#................................#.......#....#..#.........#...#.......##..#..........#.
.#....#.........#.......#....#.##..#.....#........................#.............#......#.......#...............#......#.........#..
......#.............#......#.#................#...#..........................#...........#..#.....#.......#...........#....#...#...
..........#....#...............#....................#.............#.............##..#.#.#.#.......#...........##..............#....
..###.....#......#.......#...#....#.....#.........#...................................#.#....#..#..#...#...#......#................
....#.........#.#..........##.#............#....................................#....#..............###............#....#.......#..
....#....#............#...............#.....................#...#.#...#..................#.............................#...........
..............#...#.........#......#.....#...............#...........................#.............#...#...........................
.................#............#............#.#.....................#.....#..........#..#..#..##..........#.............#...#.......
................##......#.............#..............................#....#............#..#.........##........##......#..........#.
......#..........#...#..#............#..#.....................##...#....#.#.................................#.....#...........##...
..........#.....#......#...#......#......##...........#.....#...........#.#..#................#..#..#.....#...#......#...#...#...#.
..........#........#...#...........##....#.........#...#.....#...............#........................#...#.................#......
.........#.....#...#....#.....#.......................##...#......#........................#.............#.......#....#..#....#....
..#............#.#.....#............................###...#.#.#....#..###...................###..#.#........#....#......#........#.
...#........#....#.#........##....#..#.............##.....#....#.......#......#.......................#...#.............#........#.
.......#...###..#..................#.............#......#.............................................#....#.......#......#..#.#...
....................................##.........#..............#...........#.................##....#..............#.#........#......
.#....##......#.............#.....................#....#..........##..#..##....#.........................#......................#..
...........#.............#........#...........#............................##....#...#........#..........##.##....#.....#.#........
.#..................##..#.......#.............#........#..#.#........#............#...................#.#...##.#.#.................
.....#.....#.....#...........#.#....................#.....#..#..#............#.........#.........#......#......#...............#...
.....#........#..#....#..............................#..#...........#............#....#.#...................#.....#.#........#..#..
.....#.......#......#...#...#...........#.......#.......#.................................#..........#...#.#......#.............#..
......#..........#........#..................#...#.........##.....#.............##...#..............#................#...........#.
................#........#...#..............#.......##......#.#....##...#.....#..#......#...#.......#.................#....#.#...#.
.....##.......#.....###.........................................#..........###.....#...##......................#............#......
...##..#....#........................#........#..##.#.##.#.........#...#........#.#.........#...................#.#...........#..#.
....#..............#...............#...................#............#.......................#...........#..#.#.....................
...##............#..#...............#.#.#.....#............................##..#.#.........#..#....................................
........####..#.#.................#..#.......#.#...................................#.........................#..#...........#.#....
....................................##.....#.............##..#....#.........##.....#..............................#......#.#.......
..#.........##..##.#...................#....#...............#.......#.........#..............................#.#.#.....#....#..#...
..........#...#..#....#.........#..#........#.........##......#......#.............###.....#.......#...................##.#.#......
.........#....................#...##.......#............##..........#..#..#...#....#..........#..............#........#...#.##.....
.#........#..........................#.......##....#.#...#......#........#.....#...........#.....................#......#..........
...................................................................#..##.............###..........##............#........#.......#.
.#..............................................#.#.#.......#.........#........#................................#...#....#.........
..............#.#.............####.....#.#.....#......#.........#...............#......#...#.....##..............##.#......##......
...##...#...#..............#.......#.#....#....#.....#..#......#...#.#.#...#..#...............#.......................#........#...
........#..#................#.....#..#.#.............#.#....#......#.................................................#.............
...#...#......#..............#..#.......#...#.....#.#..##..............##...............#..#.#.#........#...............#..........
......#.....................#..##..#..........#........#....##............#......#.........#.....#....#.......................#.#..
.........#.#.........#...............#.#...........#....#......#...........#..#..#.........................................#.......
..##..............................##...#......#...........#...........#...........................#.....................#..#.......
.....#...................#.#.#...........###....#.....................##...........................#...........#........#.#....#...
.#.....#................#..##........##....#............#..........#............#....#...#..#.....#...........#...............#....
........#.............##.#.......................#.......................#...#......#.####.............#....................#......
....#...............#....#......#.#.............##........#....#.......#...#..#............#.......................#..........##...
.#.#..................#..#..............#......#..#............#...#.......#.#....#.#..#......#.#.#.##.......#......#...........##.
.................#.......#.........#...........#.......#.......#...#....................###......#.....#..#.....#..............#...
..#...............#.....#.#.....#....#.#.......#..#..........#.............................#......#...#............#............#..
...........#....##...##...........#...#...........#.................#...........................#...##....#........................
.#.........#.....##.........###......#................##...#..#.#......#...................#.#...................#......#..........
..................#.#........##...............#.......#..#...#..#.........##....#.#....#.............#................##...........
........#..................#..........#..#....#.............#.............#.........#...............#........#.....................
...................#...............#....#.....#................#...#.............#.......................#.#.....#..#......#.......
.......#..###.............#..#........#..................#........................#...................#...#..........##....#.......
.......#................##...................#.................................#.#.....#..#............#.......#........#..........
.................................................................S.................................................................
........###..#.........#.........##..............#..............#.#.....#.......##.......#.....#...#.............#.................
............#.................#....#.....................................#...#..#...#.............#............##.....#............
.............#..............................................................#.##..........................#.........#..............
........##...................#.....#..#...#.....#.....#.............#............#...#..#........#.......#.#............#..........
.#.........#.......#......#....#...##.###.....#..#..........##........#....#....#.##.......#......#..##.............#.#............
..............#.....#.....#.......#...................#......#....##....#.#............#.................##........................
..#........#.....#.#.#.#.............#.#............#....#......#.......#...........#.......##..#.....#.#.##...####....#.......#...
.#..............#....#.......#........................#........#........#.#.#...#..........#........#..##..#...#..#...........#....
....#..........#.##.##.##......##....#...............#.............#..#...#...........#.###...........#.....##.#...#............#..
.#.................#..............#.................#..........#.....#..................#..................#.......................
...#.##............#..#.....#.......#......##.#....#...........#...................#.#............#.##.#.....#.................#.#.
......#.............#.....#...#.............#.......................##....##............#.##..#..#.......#......................#..
...#...............#.........#.#...........#......#.....##..#...#..#.........#.#....#......#...#....#......#.#...................#.
.......#...............#..##.......#..#.....#.....#.....#..#.#....##..#....#..........##........#.........................#...#....
.......#..#.................##..............#.......#.#....................#.#....#....#..................#............##..........
.......#.............#.............#....#.#.###...........#....#...#......#........#......#.....#........#...#.....................
........#.....................#.#...#....................................#..#..#....#..#.......#.......................#.#....#....
..#.....##............#................#........##...#.....##..............#.....#............##..#..#...............#....#....#...
....#.#..................###.##..#.#...#...........................#.#.............#...##.#.............#.....................##...
.............#..............#......#..................................#...................#.........#.....#.......#..#..#..........
.....#..#......#.............#.............#...#.........#....##....##..................#.........#................#.....#...#.#...
.................#............................#...........#..............#.....#....#.#.........#....#.#........#........#.........
..#.......#............................#.#....#.##.......................#..................#.#....####..........#.#...#.....##....
......#...#.....#...............#.#..........##....#........#..............#.......#...#...#...................#...........#.#.....
.....................#.......#..#.............#...................#..............................#...............#.....#....#......
....#..#.......#.........................#.#..........#....#...............#............#.......#...........................#......
.........#......#...............##.#......#................#....#.....#................#.....#.#....................#..#...........
..#....#..#...#....#.#................#..#............#.#.#.............#.#....#......#.#.................#....#..#.........#....#.
.....#.....#..#..................................#......#.......#............................................#.............#...#...
.##..#.................#...............#...........................#...........#..#.......#............................#.....#.....
.................##......##...........#.#.....#......#.........#......#.......#.........#....#.............##.....#............#...
....#....#...##...#...#....##.........#......##.................#.........#.......#....#...#...................#....#...#.....#....
........#.#......................................#.............#......#.#.#.....#.......#.............##...#.....#.................
.#.....#.#..............................................#.#...##......................#.....#........##..#............#....#.......
.........#........#........................##..#........##....#.#...#......#.#...#...#.............#.......#..#.#..................
........#..#.#...............#...........##.....#....#...#..#..#..........#......#......#..........#.....#.....##.........#.....##.
...#....#...#.........#..#.#...#.#........##...#............#..##.#.##.#..##............#.........#.#..........#...................
.#...........##..#........##....#.............#...#...#.......#.............#...#.#...#............#.........#.............##......
.#.....................#......................#...........#...#.....#...#..............................#.........#.....#.#....#.#..
............#......#...............................#......#....#...............#...................#....................#..........
...##...............................#...............#..##........................#....................#.#..#...##................#.
...#..#......#..#....#....#...#.#...#.....................#.#......#.#..........................#..#............#....#....#........
.....##.#.....#..........#..#......##............##.........#.........#.....##.....#............#.............#...........##...#...
...........#....#............#......#....................#...#..........##......#................##.........##....#...#............
.....##...........#.....#.#.............#............#........................#.............#......##..#......#..#.....#........#..
...#.#......#.......#..#.................#................#..#........#...................###............##....#..#..........##....
.#..#.................###....##......................#.#...................#...............#...#.#....#.#.##...........#.......#...
....#..#................#........#..#................................#.......#...........#.......#.#..............##....#......#...
......#................#....#................#............#.#...#......#...............#............#..##....#..................#..
.........#..................................#.#...........#..................................#............#.#..........##..##.#....
.#..............#......#...........####.....#..............#.............................#...#......#....#........#.............#..
....####...........#..#....#.............#.....#...........#...#..........................#..#....#.....#..#...........#.........#.
.....#.#.....#...........................#.....#...........#...............................##...............##..#.#.#.........#....
.##............#.#.#.#....##.#...#.#.............................................#.........#......#.#.............#...##...........
.#....#.................#.#....#............#............................................#........#...........#..#.................
..................#....#.##.#.#.#..........#........#.............#....................#...........#.....#.........................
.........#...#.........#..................#........#...............#.................#......##........#........#.#.#.......##....#.
.......#.......#......#.......##........#....#....#.#.......................................#..............#.....#.....#...#..#....
......#.................#.........##....#.......................#...............#.#.....................#..#....###.#........##....
.......#....#.....#.............................................................#..........#..#.............#..#.#..#..............
.#.....#................#...#....#..#....##..#..##........................................#...#..............#.....#...........##..
........#....#...##..#.....#.#.........#..............#.........................................................#......#..#.....##.
....#..#.#....#..............................#.#.....##..##...........................#...............#......#.....................
.##.....#.#...........##.......#........#....#.........................##.#......#.........................#.......................
...................................................................................................................................

@ -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
}

@ -191,3 +191,12 @@ func Map[T, M any](s []T, f func(T) M) []M {
} }
return res 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
}

Loading…
Cancel
Save