Completed both parts of Day 16 puzzle

main
oabrivard 2 years ago
parent 870c689063
commit 30674b7527

@ -0,0 +1,222 @@
package day16
import (
"fmt"
"sync"
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
type Move struct {
row int
col int
direction rune
}
func nextMoves(origin *Move, lines []string) []*Move {
result := []*Move{}
switch lines[origin.row][origin.col] {
case '/':
switch origin.direction {
case 'R':
result = append(result, &Move{origin.row - 1, origin.col, 'U'})
case 'L':
result = append(result, &Move{origin.row + 1, origin.col, 'D'})
case 'U':
result = append(result, &Move{origin.row, origin.col + 1, 'R'})
case 'D':
result = append(result, &Move{origin.row, origin.col - 1, 'L'})
}
case '\\':
switch origin.direction {
case 'R':
result = append(result, &Move{origin.row + 1, origin.col, 'D'})
case 'L':
result = append(result, &Move{origin.row - 1, origin.col, 'U'})
case 'U':
result = append(result, &Move{origin.row, origin.col - 1, 'L'})
case 'D':
result = append(result, &Move{origin.row, origin.col + 1, 'R'})
}
case '|':
switch origin.direction {
case 'R', 'L':
result = append(result, &Move{origin.row - 1, origin.col, 'U'})
result = append(result, &Move{origin.row + 1, origin.col, 'D'})
case 'U':
result = append(result, &Move{origin.row - 1, origin.col, 'U'})
case 'D':
result = append(result, &Move{origin.row + 1, origin.col, 'D'})
}
case '-':
switch origin.direction {
case 'R':
result = append(result, &Move{origin.row, origin.col + 1, 'R'})
case 'L':
result = append(result, &Move{origin.row, origin.col - 1, 'L'})
case 'U', 'D':
result = append(result, &Move{origin.row, origin.col - 1, 'L'})
result = append(result, &Move{origin.row, origin.col + 1, 'R'})
}
default:
switch origin.direction {
case 'R':
result = append(result, &Move{origin.row, origin.col + 1, 'R'})
case 'L':
result = append(result, &Move{origin.row, origin.col - 1, 'L'})
case 'U':
result = append(result, &Move{origin.row - 1, origin.col, 'U'})
case 'D':
result = append(result, &Move{origin.row + 1, origin.col, 'D'})
}
}
return result
}
func Part1(lines []string, startRow int, startCol int, direction rune) int {
height := len(lines)
width := len(lines[0])
cache := map[Move]bool{}
isEnergized := make([][]bool, height)
beamMoves := utils.NewStack[*Move]()
for row := range lines {
isEnergized[row] = make([]bool, width)
}
beamMoves.Push(&Move{startRow, startCol, direction})
i := 0
for beamMoves.HasElement() {
currOrigin := beamMoves.Pop()
isEnergized[currOrigin.row][currOrigin.col] = true
_, hasKey := cache[*currOrigin]
if hasKey {
continue
}
cache[*currOrigin] = true
moves := nextMoves(currOrigin, lines)
for _, move := range moves {
if move.row >= 0 && move.row < height && move.col >= 0 && move.col < width {
beamMoves.Push(move)
}
}
i++
if i > 1000000 {
fmt.Println("loop ?")
return -1
}
}
count := 0
for row := range isEnergized {
for col := range isEnergized[row] {
if isEnergized[row][col] {
count++
}
}
}
return count
}
func Part2(lines []string) int {
height := len(lines)
width := len(lines[0])
max := -1
var wgD sync.WaitGroup
chD := make(chan int, width)
for i := 0; i < width; i++ {
wgD.Add(1)
go func(col int) {
defer wgD.Done()
result := Part1(lines, 0, col, 'D')
chD <- result
}(i)
}
wgD.Wait()
close(chD)
for i := range chD {
if i > max {
max = i
}
}
var wgU sync.WaitGroup
chU := make(chan int, width)
for i := 0; i < width; i++ {
wgU.Add(1)
go func(col int) {
defer wgU.Done()
result := Part1(lines, height-1, col, 'U')
chU <- result
}(i)
}
wgU.Wait()
close(chU)
for i := range chU {
if i > max {
max = i
}
}
var wgL sync.WaitGroup
chL := make(chan int, height)
for i := 0; i < height; i++ {
wgL.Add(1)
go func(row int) {
defer wgL.Done()
result := Part1(lines, row, width-1, 'L')
chL <- result
}(i)
}
wgL.Wait()
close(chL)
for i := range chL {
if i > max {
max = i
}
}
var wgR sync.WaitGroup
chR := make(chan int, height)
for i := 0; i < height; i++ {
wgR.Add(1)
go func(row int) {
defer wgR.Done()
result := Part1(lines, row, width-1, 'L')
chR <- result
}(i)
}
wgR.Wait()
close(chR)
for i := range chR {
if i > max {
max = i
}
}
return max
}

@ -0,0 +1,69 @@
package day16
import (
"testing"
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
func TestPart1(t *testing.T) {
lines := []string{
`.|...\....`,
`|.-.\.....`,
`.....|-...`,
`........|.`,
`..........`,
`.........\`,
`..../.\\..`,
`.-.-/..|..`,
`.|....-|.\`,
`..//.|....`,
}
result := Part1(lines, 0, 0, 'R')
if result != 46 {
t.Fatalf("expected 46, got %v", result)
}
}
func TestPart1WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := Part1(lines, 0, 0, 'R')
if result != 8021 {
t.Fatalf("expected 8021, got %v", result)
}
}
func TestPart2(t *testing.T) {
lines := []string{
`.|...\....`,
`|.-.\.....`,
`.....|-...`,
`........|.`,
`..........`,
`.........\`,
`..../.\\..`,
`.-.-/..|..`,
`.|....-|.\`,
`..//.|....`,
}
result := Part2(lines)
if result != 51 {
t.Fatalf("expected 51, got %v", result)
}
}
func TestPart2WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := Part2(lines)
if result != 8216 {
t.Fatalf("expected 8216, got %v", result)
}
}

@ -0,0 +1,110 @@
\....../..-......-.\.........\.......................-....../......../....................................|...
......\../../.....\-................../...........|................-../.............-./........|.|............
..-...-..../..............................-..............\.........-../...........................-.\.......\.
............./-..........|..............\/.................../........../............\.......|................
....|.....\.../...|..............\/..|-.................-..........\.\........................\...............
...........\...........-..|..../..\.-|........................-/.|/....../.........\.....|................/...
./....-|./.......|......-...-............-.......-......................................../....-............\.
....\...........|............-............-..\..|...|.........-..||.................\/...........|-|.|-.......
-............................-....................|........-...............\..................\...............
...............\......................-....../......|..||.|.-........................./......-............\...
.-...|........-.......|.........|....|.....-.........|..|............................./.../\...-........\.....
....................../...........-......-..--.|-...............-....................\......\.................
-....................-......-......./.......\|./......./........|...........|..................|..............
..-............../....................|.............-.......-.................-..................\......\.|...
....................\...............................................|.....\................../..-/............
...-.-/...\.//...|.............|........................\.............-|..|...........--..\........./...\.....
....................................................................\..........-......................-/......
..................................\......-.....-...........-.............-...........\...................|...-
......................\........|../..............-.........../......-...|......../.\......./..||..............
................................/......-................................./.........-......\./......|..........
........../....../....\.\|......-..............................\.....................--......|.............\..
..-.................-............../\............|.......................................\...|....\...........
./................\.|....\.........................../................|..............-....-..../..............
../...........\.\/./........\........-\...-/...........-............../........................|..............
......\.||.....................|..................\..............|........../......\/........../.....-........
..|/...........\.....|../.......\...........-.............|..............-........|...............-.....|.....
....................../.....-..|.......-...-...|.....................|./...\.........-........................
......................../........../\../.........-...\........./...............................|..\...........
.......................|\............./...|...............\/-...............|........................../..\...
..|....-.......\..................................\................................|......../.|..............-
........../...\.\........-......|.\.|.....................-............/..\..........|.../...-.............../
..\.-..............-............/..-..\..............\.........\....../...|........|........\....../..........
.....................|........................../..|....|.-.../........................-.\../-................
./..........-....|......|.|.................-....|........\......|............../.........................../.
....-..................................................................................-............|..-....//
......./...-.......................-..-.........-.............|........................../....................
.-...................-.......................................|.......-.................../..\...............\|
.........|.\......-.....\............./-....................../.........-..|....|......-......................
......./............./..........-......-......\...................................../............/..\.........
.....\......-................................/..........|.............\........\............/.................
......../..............\.........................|..........\......-............\.....|.....\....|...\|....-..
.....\.......\/................/...\.......|./......|............\./..........|/.....\\..\...\...|..-.........
..................|.....................-..........\....................../...../..............|......../..../
........./...........|....-..\.....................--..|......|...\|.......|...............|...-.||...........
..............-.....\...|...|./...|..........-......../......./..........-...../..|........../................
..|.../...................................|...................|......./..-.....-..............-...............
...-.........../..................-..........|.........................\..-................//\............/...
|...............\.........\.../.....................|.....-........................\...........-../.-......-..
........//..........-......................-....\...-.......-./.../......../........./...........|.|..........
...................\..../...../...|........--.....\../..........|...........................|.\...............
.\......................-........|\.....\....|.........\...............|.......\...-...|.................-....
.....................|......./..-........................../......-.........../........................../....
--.............\..........\-..../..-........\....-..........|./....|.\.................-..--.....\../.........
.......|........../|...................|.................\..-..........\../....|\.....|...-.......\..-........
........../|.|.....\....................|\..\...........-............./.......|.\.............................
...........|..........-..............|.....|-................/.........|..../.........................-.......
......-..........................|............-.......|/...-....--/................/..-.........|.............
......../.-.............|....\.../............................|.|.....|....../...............\............./..
........./.......\..........\...........\.....\..|....-...../........./........................./..|..........
...|...|........\.......-.......\..................\....................../............-...|.........\........
.........-...........|.........\....................../..........-.....\|.\...................\...............
.....|..........|................................../......................|............/.....|.........|..-|..
.../.......\....//....../....\....../..........\........................./....................\....-.../......
/.......\..\...........\................-|............/...-|.|...-..........\.................\.....|.../.....
.....-\.........|....../.......\.............-..........................\...........................\.........
.|.............|................\....\...........-................./............./............................
./...|\...........-\....................\..............-....|....|..........-.........|.../.....-.....\.\.....
....-...............|........-............./.....\....../..\.|.....|./.\......-...........\....../.\.......\..
..........\.....\................../......|.\..../.\..-......-.........-............/....\...................\
..\.........|.....\..........\............./...-....../....|.......-|\-............................../........
..|...\/........\..-\.|.\......./.....|.........-..|........|......................|..........................
............|..........................--.-....\..............-................................|...|..........
.-............../.....................|........../.................-....../.-...........................\-....
.-.........................-......|-./\.........................\.....|.................|......|..\.......\...
.....\...|....-......................................-...............\...........\..\...\..-|.....\...........
|...........|................|.........-............|....................|............-..-.............../....
.................../.|...........\.......\....|......-..|.....................\...................|..\.....\..
.|........-.../...|....../...|......|.|.|..-......\............../....|...........\|.......|.......\\.........
.......|.....-..-.-./....-/\.|./.............|.../......\...|/............/........./...-..........|\.\.......
..|.........-....\.........\.......\....-................|-..........................-.|............|.........
......-..\......|..\.../......\|..........|............../........../............/..\........................|
|/.|................../....|............../..........-........-............................|.\................
........|.....|/................../....\....../....../...................--..............\/..\................
.../-..........................|...-.........-.................\\.......-\.........\..|.....|.................
-./...-.....-....................../.../........./........-........../.........-...........\..................
.\../............|.\..........-.................................\.............../............../.........\./..
...-.....-......-......../.\...\................\...........|.................................................
...........-...//.....-/...-...........\|./......................\.........................|.-|...|...........
....../.....................-.......|........|-..................\............-.....................|.........
.....................\.\................../..|/......\........|.\..............|\..............\..-...........
....\................|\......................./.....-...............................-......../....-...........
...\....................-....|......|........-.\..|.......................\...\.|..............|............/.
...................-/.....................................-..\............-............-.............-....\...
.|....../.....\.....-.../......../..../..\.-...........\.../................|........\.................../....
.......|........./........................\.....-........-...............\....../....|../....\......./........
..........|.........../|......|......................-..............|./......................................\
....................../...../..............|.||............./......-......\...................................
\........|...-..................\./.................\.\.........-....\........../.../.-...\...................
....-..........|.......-......../................................./.../....-.............-..........\-........
..............................-.............\..\......................................-......../..............
......./.\|......../...-........|.........|................/.........................-....|...\.........|.....
......|..........-.......-............./........|..\...|.|..-.............................-.-...\.............
.||...........-.......\...../.....................-././..../.............-................|../.............--.
................\.-.....-\..........\.............\............/.........\.......-........\...................
......./...........\........\./.|..............|......-...........\................\...../.\...../..........|.
.-..-...|.....................-....../..............-.\|....\.......|..|....././.......|......................
./...-..................../................/....-/..\............/..................................\.........
....\.-..........\-......../............|...\.............|..................|.....\.................../......
...........-/..\..-................-....|............/...-.|.......-.|........./.....-/......./...............
..../...-.....\..............-..\.....\.|............./...|.\..................\...|.........\-./..|...../....

@ -22,28 +22,14 @@ IN THE SOFTWARE.
package utils
// stack head == 0 if stack is empty.
// stack head == size if stack is full.
type Stack[T any] struct {
size int
head int
data []T
}
// New creates an empty stack that can contain a maximum of size elements.
func NewStack[T any](size int) Stack[T] {
if size < 0 {
panic("stack size must be >= 0")
}
// New creates an empty stack
func NewStack[T any]() Stack[T] {
result := Stack[T]{
size,
0,
nil,
}
if size > 0 {
result.data = make([]T, size)
[]T{},
}
return result
@ -51,12 +37,7 @@ func NewStack[T any](size int) Stack[T] {
// Push pushes the value v on top of stack s.
func (s *Stack[T]) Push(v T) {
if s.head == s.size {
panic("called Push() on a full stack")
}
s.data[s.head] = v
s.head++
s.data = append(s.data, v)
}
// Pop removes the value v from the top of stack s and returns it.
@ -65,27 +46,26 @@ func (s *Stack[T]) Pop() T {
panic("called Pop() on an empty stack")
}
s.head--
return s.data[s.head]
value := s.data[len(s.data)-1]
s.data = s.data[0 : len(s.data)-1]
return value
}
// HasElement returns true if the stack s contains at least one element.
func (s *Stack[T]) HasElement() bool {
return s.head > 0
return len(s.data) > 0
}
// Count returns the number of elements contained in s.
func (s *Stack[T]) Count() int {
return s.head
return len(s.data)
}
// Reversed returns a new stack built from stack s, with its elements in reverse order.
// s will be emptied by this operation.
func (s *Stack[T]) Reversed() Stack[T] {
result := Stack[T]{
s.size,
0,
make([]T, s.size),
make([]T, len(s.data)),
}
for s.HasElement() {

@ -24,38 +24,18 @@ package utils
import "testing"
func TestNegativeSize(t *testing.T) {
defer func() { _ = recover() }() // turn off the panic
_ = NewStack[int](-1)
// Never reaches here if New() panics.
t.Errorf("New() with negative size should panic")
}
func TestEmpty(t *testing.T) {
defer func() { _ = recover() }() // turn off the panic
s := NewStack[int](0)
s := NewStack[int]()
s.Pop()
// Never reaches here if Pop() panics.
t.Errorf("Pop() on empty stack should panic")
}
func TestFull(t *testing.T) {
defer func() { _ = recover() }() // turn off the panic
s := NewStack[int](1)
s.Push(1)
s.Push(2)
// Never reaches here if Push() panics.
t.Errorf("Push() on full stack should panic")
}
func TestHasElements(t *testing.T) {
s := NewStack[int](1)
s := NewStack[int]()
if s.HasElement() {
t.Errorf("HasElement() should return false for empty stack")
@ -69,7 +49,7 @@ func TestHasElements(t *testing.T) {
}
func TestCount(t *testing.T) {
s := NewStack[int](1)
s := NewStack[int]()
if s.Count() != 0 {
t.Errorf("Count() should be 0 for empty stack")
@ -83,7 +63,7 @@ func TestCount(t *testing.T) {
}
func TestPushPop(t *testing.T) {
s1 := NewStack[int](3)
s1 := NewStack[int]()
s1.Push(1)
s1.Push(2)
s1.Push(3)
@ -100,7 +80,7 @@ func TestPushPop(t *testing.T) {
}
func TestReversed(t *testing.T) {
s1 := NewStack[int](3)
s1 := NewStack[int]()
s1.Push(1)
s1.Push(2)
s1.Push(3)

Loading…
Cancel
Save