finish 2023
This commit is contained in:
202
2023/go/day16/day16.go
Normal file
202
2023/go/day16/day16.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package day16
|
||||
|
||||
import (
|
||||
_ "adventofcode2023/utils"
|
||||
"adventofcode2023/utils/grid2d"
|
||||
_ "adventofcode2023/utils/grid2d"
|
||||
"adventofcode2023/utils/inputs"
|
||||
"fmt"
|
||||
_ "strings"
|
||||
)
|
||||
|
||||
type Tile struct {
|
||||
object rune
|
||||
energized int
|
||||
}
|
||||
|
||||
type Beam struct {
|
||||
dir rune
|
||||
r int
|
||||
c int
|
||||
rm bool
|
||||
}
|
||||
|
||||
var startBeams []Beam
|
||||
|
||||
func Part1(input string) int {
|
||||
beams := []Beam{}
|
||||
beams = addBeam(beams, Beam{'s', 0, 3, false})
|
||||
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
return score(grid, beams)
|
||||
}
|
||||
|
||||
func Part2(input string) int {
|
||||
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
G := grid.Matrix()
|
||||
R := len(G)
|
||||
C := len(G[0])
|
||||
ans := 0
|
||||
for r:=0;r<R;r++{
|
||||
beams := []Beam{}
|
||||
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
beams = addBeam(beams, Beam{'e', r, 0, false})
|
||||
ans = max(ans, score(grid, beams))
|
||||
beams = []Beam{}
|
||||
beams = addBeam(beams, Beam{'w', r, C-1, false})
|
||||
grid = inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
ans = max(ans, score(grid, beams))
|
||||
}
|
||||
for c:=0;c<C;c++{
|
||||
beams := []Beam{}
|
||||
grid := inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
beams = addBeam(beams, Beam{'s', 0, c, false})
|
||||
ans = max(ans, score(grid, beams))
|
||||
beams = []Beam{}
|
||||
beams = addBeam(beams, Beam{'n', R-1, c, false})
|
||||
grid = inputs.ToGrid2D[Tile](input, "\n", "", Tile{}, func(c string) Tile { return Tile{ object: rune(c[0]), energized: 0}})
|
||||
ans = max(ans, score(grid, beams))
|
||||
}
|
||||
|
||||
return ans
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func score(grid *grid2d.Grid[Tile], beams []Beam) int {
|
||||
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { return string(t.object)}))
|
||||
G := grid.Matrix()
|
||||
R := len(G)
|
||||
C := len(G[0])
|
||||
fmt.Println("r:", R, "c:", C, "tiles:", R*C )
|
||||
for i:=0;i<1000;i++ {
|
||||
beams = rmBeams(beams)
|
||||
fmt.Println(i, ":", len(beams), ":", energy(G))
|
||||
for i, _ := range beams {
|
||||
r := beams[i].r
|
||||
c := beams[i].c
|
||||
if r >= 0 && r < R && c >= 0 && c < C {
|
||||
G[r][c].energized++
|
||||
switch beams[i].dir {
|
||||
case 'n':
|
||||
tile := &G[r][c]
|
||||
switch tile.object {
|
||||
case '.':
|
||||
beams[i].r--
|
||||
case '|':
|
||||
beams[i].r--
|
||||
case '-':
|
||||
beams[i].dir = 'e'
|
||||
beams[i].c++
|
||||
beams = addBeam(beams, Beam{'w', beams[i].r, beams[i].c-1, false})
|
||||
case '\\':
|
||||
beams[i].dir = 'w'
|
||||
beams[i].c--
|
||||
case '/':
|
||||
beams[i].dir = 'e'
|
||||
beams[i].c++
|
||||
}
|
||||
case 'e':
|
||||
tile := &G[r][c]
|
||||
switch tile.object {
|
||||
case '.':
|
||||
beams[i].c++
|
||||
case '-':
|
||||
beams[i].c++
|
||||
case '|':
|
||||
beams[i].dir = 'n'
|
||||
beams[i].r--
|
||||
beams = addBeam(beams, Beam{'s', beams[i].r+1, beams[i].c, false})
|
||||
case '\\':
|
||||
beams[i].dir = 's'
|
||||
beams[i].r++
|
||||
case '/':
|
||||
beams[i].dir = 'n'
|
||||
beams[i].r--
|
||||
}
|
||||
case 's':
|
||||
tile := &G[r][c]
|
||||
switch tile.object {
|
||||
case '.':
|
||||
beams[i].r++
|
||||
case '|':
|
||||
beams[i].r++
|
||||
case '-':
|
||||
beams[i].dir = 'e'
|
||||
beams[i].c++
|
||||
beams = addBeam(beams, Beam{'w', beams[i].r, beams[i].c-1, false})
|
||||
case '\\':
|
||||
beams[i].dir = 'e'
|
||||
beams[i].c++
|
||||
case '/':
|
||||
beams[i].dir = 'w'
|
||||
beams[i].c--
|
||||
}
|
||||
case 'w':
|
||||
tile := &G[r][c]
|
||||
switch tile.object {
|
||||
case '.':
|
||||
beams[i].c--
|
||||
case '-':
|
||||
beams[i].c--
|
||||
case '|':
|
||||
beams[i].dir = 'n'
|
||||
beams[i].r--
|
||||
beams = addBeam(beams, Beam{'s', beams[i].r+1, beams[i].c, false})
|
||||
case '\\':
|
||||
beams[i].dir = 'n'
|
||||
beams[i].r--
|
||||
case '/':
|
||||
beams[i].dir = 's'
|
||||
beams[i].r++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
beams[i].rm = true
|
||||
}
|
||||
}
|
||||
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { if t.energized > 0 {return "#"}; return "."}))
|
||||
}
|
||||
fmt.Println(grid.StringWithFormatter(func(t Tile, x int, y int) string { if t.energized > 0 {return "#"}; return "."}))
|
||||
return energy(G)
|
||||
}
|
||||
|
||||
func rmBeams(slice []Beam) []Beam {
|
||||
var result []Beam
|
||||
|
||||
for _, value := range slice {
|
||||
if ! value.rm {
|
||||
result = append(result, value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func addBeam(beams []Beam, beam Beam) []Beam {
|
||||
for _, value := range startBeams {
|
||||
if value == beam { return beams }
|
||||
}
|
||||
startBeams = append(startBeams, beam)
|
||||
for _, value := range beams {
|
||||
if value == beam { return beams }
|
||||
}
|
||||
return append(beams, beam)
|
||||
}
|
||||
|
||||
func energy(G [][]Tile) int {
|
||||
ans := 0
|
||||
R := len(G)
|
||||
C := len(G[0])
|
||||
for r:=0;r<R;r++ {
|
||||
for c:=0;c<C;c++ {
|
||||
if G[r][c].energized > 0 {
|
||||
ans++
|
||||
}
|
||||
}
|
||||
}
|
||||
return ans
|
||||
}
|
||||
Reference in New Issue
Block a user