add day16
This commit is contained in:
207
day16/allbestpaths.go
Normal file
207
day16/allbestpaths.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package main
|
||||
|
||||
import ( "os"; "fmt"; "strings")
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Direction uint8
|
||||
|
||||
const (
|
||||
Up Direction = iota
|
||||
Down Direction = iota
|
||||
Left Direction = iota
|
||||
Right Direction = iota
|
||||
)
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Path struct {
|
||||
position [2]uint
|
||||
direction Direction
|
||||
}
|
||||
|
||||
func (p Path) StepUnbound(d Direction) Path {
|
||||
switch {
|
||||
case d == Down: p.position[1]++
|
||||
case d == Up: p.position[1]--
|
||||
case d == Left: p.position[0]--
|
||||
case d == Right: p.position[0]++
|
||||
}
|
||||
p.direction = d
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Maze struct {
|
||||
start [2]uint
|
||||
end [2]uint
|
||||
field [][]byte
|
||||
}
|
||||
|
||||
func NewMaze(str string) *Maze {
|
||||
var maze Maze
|
||||
|
||||
for y, line := range strings.Split(str, "\n") {
|
||||
line_arr := make([]byte, len(line))
|
||||
for x, char := range []byte(line) {
|
||||
switch {
|
||||
case char == 'S':
|
||||
line_arr[x] = '.'
|
||||
maze.start = [...]uint{uint(x), uint(y)}
|
||||
case char == 'E':
|
||||
line_arr[x] = '.'
|
||||
maze.end = [...]uint{uint(x), uint(y)}
|
||||
default: line_arr[x] = char
|
||||
}
|
||||
}
|
||||
maze.field = append(maze.field, line_arr)
|
||||
}
|
||||
|
||||
return &maze
|
||||
}
|
||||
|
||||
func (m *Maze) Step(path Path) []Path {
|
||||
out := make([]Path, 0, 4)
|
||||
|
||||
if m.field[path.position[1] + 1][path.position[0]] == '.' && path.direction != Up {
|
||||
out = append(out, path.StepUnbound(Down))
|
||||
}
|
||||
if m.field[path.position[1] - 1][path.position[0]] == '.' && path.direction != Down {
|
||||
out = append(out, path.StepUnbound(Up))
|
||||
}
|
||||
if m.field[path.position[1]][path.position[0] + 1] == '.' && path.direction != Left {
|
||||
out = append(out, path.StepUnbound(Right))
|
||||
}
|
||||
if m.field[path.position[1]][path.position[0] - 1] == '.' && path.direction != Right {
|
||||
out = append(out, path.StepUnbound(Left))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Maze) Start() Path {
|
||||
return Path{m.start, Right}
|
||||
}
|
||||
|
||||
func (m *Maze) Finished(path Path) bool {
|
||||
return m.end == path.position
|
||||
}
|
||||
|
||||
func (m *Maze) Print() {
|
||||
for _, line := range m.field {
|
||||
fmt.Println(string(line))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type MazeGraph struct {
|
||||
cost uint
|
||||
position [2]uint
|
||||
children []*MazeGraph
|
||||
}
|
||||
|
||||
var new_maze_graph_visited map[Path]uint
|
||||
|
||||
func NewMazeGraph(m *Maze, start Path, cost uint) *MazeGraph {
|
||||
children := make([]*MazeGraph, 0, 3)
|
||||
|
||||
// finish reached?
|
||||
if m.Finished(start) { return &MazeGraph{ cost: cost, position: start.position, children: children } }
|
||||
|
||||
// check for loop
|
||||
value, exists := new_maze_graph_visited[start]
|
||||
if exists {
|
||||
if value < cost { return nil }
|
||||
}
|
||||
new_maze_graph_visited[start] = cost
|
||||
|
||||
// build subgraphs/ children
|
||||
for _, path := range m.Step(start) {
|
||||
var child *MazeGraph
|
||||
if start.direction != path.direction {
|
||||
child = NewMazeGraph(m, path, cost + 1001)
|
||||
} else {
|
||||
child = NewMazeGraph(m, path, cost + 1)
|
||||
}
|
||||
|
||||
if child != nil { children = append(children, child) }
|
||||
}
|
||||
|
||||
// found dead end
|
||||
if len(children) == 0 { return nil }
|
||||
|
||||
return &MazeGraph{ cost: cost, children: children, position: start.position }
|
||||
}
|
||||
|
||||
func (graph *MazeGraph) Leaves() []*MazeGraph {
|
||||
out := make([]*MazeGraph, 0)
|
||||
|
||||
if len(graph.children) == 0 {
|
||||
out = append(out, graph)
|
||||
return out
|
||||
}
|
||||
|
||||
for _, g := range graph.children {
|
||||
out = append(out, g.Leaves()...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (graph *MazeGraph) PathsToLeaves(leave_cost uint) [][2]uint {
|
||||
out := make([][2]uint, 0)
|
||||
|
||||
if len(graph.children) == 0 {
|
||||
// leave found
|
||||
if graph.cost == leave_cost {
|
||||
return append(out, graph.position)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// collect from children
|
||||
for _, g := range graph.children {
|
||||
subpath := g.PathsToLeaves(leave_cost)
|
||||
if subpath != nil {
|
||||
out = append(out, subpath...)
|
||||
}
|
||||
}
|
||||
// if all children returned nil
|
||||
if len(out) == 0 { return nil }
|
||||
|
||||
return append(out, graph.position)
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
func check(err error) { if err != nil { panic(err) } }
|
||||
|
||||
func uniq_count(slice [][2]uint) int {
|
||||
m := make(map[[2]uint]bool)
|
||||
for _, s := range slice {
|
||||
m[s] = true
|
||||
}
|
||||
return len(m)
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
dat, err := os.ReadFile("data.txt")
|
||||
check(err)
|
||||
|
||||
input := strings.TrimSpace(string(dat))
|
||||
maze := NewMaze(input)
|
||||
|
||||
var best *MazeGraph
|
||||
new_maze_graph_visited = make(map[Path]uint)
|
||||
maze_graph := NewMazeGraph(maze, maze.Start(), 0)
|
||||
|
||||
for _, leave := range maze_graph.Leaves() {
|
||||
if best == nil || best.cost > leave.cost { best = leave }
|
||||
}
|
||||
fmt.Println(best.cost)
|
||||
fmt.Println(uniq_count(maze_graph.PathsToLeaves(best.cost)))
|
||||
}
|
||||
141
day16/data.txt
Normal file
141
day16/data.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
#############################################################################################################################################
|
||||
#.#.....#.........#...#.......#.......#.......#.................#...#...#.........#...#.........#.....#.....#.......#.......#...#.......#..E#
|
||||
#.#.###.#.###.#####.#.#.#####.#.#.###.#.###.###.#####.#.#######.#.###.#.#.###.#.#.#.#.#.#####.#.#.###.#.#.###.#.#####.#.###.###.#.###.#.#.#.#
|
||||
#.....#.#...#.......................#...#...#.....#...#.#.....#.......#...#...#.#...#...........#...#...#.....#.#.....#...#.....#...#.#.....#
|
||||
#.#####.###.#.#.#####.#####.###.###.#########.#####.#####.###.#.#.#.#######.###.#####.#.###.#.#####.#######.###.#.#######.#######.###.#####.#
|
||||
#.#...#.#...#...#...#.....#.#.#...#...........#...#.#.....#...#.#.#...#.......#.#.....#...#.#...#...#...#.....#...#.#...#.........#...#.....#
|
||||
#.#.#.#.#.###.#.###.###.###.#.#.#.#############.#.#.#.#####.###.#.###.#.#####.#.#########.#.###.#.###.#.#.###.#####.#.#.###########.###.#.#.#
|
||||
#...#...#.....#...#...#.....#...#.....#.....#...#.#.#.#...#...#.#.#...#.#.....#.............#...#.#.#.#...#.......#...#...#.........#...#...#
|
||||
###.###.#####.#.#.#.#.#########.###.#.###.#.#.###.#.#.#.#####.#.#.#.###.#.###.###############.#.#.#.#.#####.#####.###.#.###.###########.#####
|
||||
#...#...#...#...#...#.#.#...........#.......#.#.....#.#.....#.#...#.#...#.#.....#...........................#.......#.#...#...#.......#.....#
|
||||
#.###.###.#.#.#.#####.#.#.###.#.#########.#.#.#######.#####.#.#.#.#.#.###.#####.###.#######.#####.#.###.#.#########.###.#.###.#.#####.#####.#
|
||||
#.#...#...#.........#.#...#...#.#.......#...#.......#.#.....#...#.#.#.#.#.........................#.#...#.......#.#...#.#...#.#...#.#...#...#
|
||||
#.#.#######.#.#.#####.#####.###.#.#.#####.#######.#.#.#.###.###.###.#.#.###.#.###.#.#.###.#.#.#####.#.#########.#.###.#.#.###.###.#.###.###.#
|
||||
#.#.......#...#.....#.....#.#.....#.#.....#...#.#...#.#.#...#...#...#.....#.#.......#.#.....#...#.....#...................#...#...#...#...#.#
|
||||
#.#######.#####.###.#####.#.###.###.#.###.#.#.#.#.###.#.#.###.###.###.#####.#.#######.#.#######.#.#####.#########.#.#.###.#.###.###.#.###.#.#
|
||||
#.#...#...#...#.#.#.....#.#...#...#.........#...#...#...#...#.....#...#.....#.#...#...#.#.....#.#.....#.........#.#.#.#...#.........#.#...#.#
|
||||
#.#.###.###.#.#.#.###.#.#.###.###.#########.###.###.#######.#######.#.#.#######.#.#.###.#.#.###.#####.#########.#.#.#.#.###############.###.#
|
||||
#.#.........#.#...#...#...#...#.....#.......#...#.#.......#.#...#.....#...#.....#...#...#.#.....#...#...#.....#.#.....#.................#...#
|
||||
#.###########.#####.#.###.#.#######.#.#######.###.#######.#.###.#.#######.#.#########.###.#######.#####.#.###.#.#.#######.#.#.#########.#####
|
||||
#.#...#.....#...#...#.#...#.....#...#.#.....#.#.....#...#...#...#.#.......#.#.......#...#...#.#.........#...#...#...#.....#.#...#.#.....#...#
|
||||
#.#.#.#####.###.#.###.#.#######.#.###.###.###.###.#.###.#.###.###.#.#.#.###.#.#####.#######.#.#.#####.###.#.#######.#.#.#.#####.#.#.#####.#.#
|
||||
#...#.#.....#.#.#...#.#.#.......#.#.....#...#.....#.#.......#.#...#.#...#...#...#.#...#.....#...#...#.#...#.....#...#.#.#.......#...#...#.#.#
|
||||
#####.#.###.#.#.#.#.#.#.#.#######.###.#.#.#.#######.#.#####.#.#.###.#.###.#.###.#.###.#.#########.#.###.###.#####.###.#.###.#####.###.###.#.#
|
||||
#...............#.#.#.#...#.....#.....#.#.#...#...#.#...#.#.....#...#...#.#.#.......#.#...#.......#.....#.....#...#...#...#.#.......#...#.#.#
|
||||
#.#.#.#.#.###.#.#.#.#####.#.#.#.###.###.#.###.#.#.#.###.#.#.#####.#######.###.#######.#.#.#.###############.#.#.#########.#.#.#####.###.#.#.#
|
||||
#.......#.#.#.#.#.....#...#.#.#...#.#...#...#.#.#.#.....#.#.......#.....#...#...#...#.#...#.#.#.....#.......#.#.#.....#...#.#.#...#.....#.#.#
|
||||
#.#######.#.#.#.###.#.#.#.#.#.#####.#.#####.#.#.#.#######.#####.#.#.###.###.#.###.#.#.#.###.#.#.#.#.###.###.#.#.###.#.#.###.#.#.#.#####.#.#.#
|
||||
#...#.....#...#...#.....#...#.......#...#...#...#...#...#.......#...#...#.#...#...#...#.#...#...#.#.....#...#.#.#...#...#...#...#.....#.#.#.#
|
||||
#.#.###.#######.#.#.#.#.###############.#.#######.#.#.###.###########.#.#.#####.#####.#.###.#.###.#.#######.#.#.#.#####.#.#.#.#######.###.#.#
|
||||
#.#...#...#...........#...#.#...........#.....#...#.#.#...#...#.........#.#.....#.#...#.....#...#...#.....#...#.#.#.....#...............#.#.#
|
||||
#####.#.#.#.#############.#.#.#####.#.###.#####.###.#.#.###.###.#.#####.#.#.#####.#.#############.#.#.###.#####.#.#####.#######.#######.#.#.#
|
||||
#.....#.#.#...#...........#...#...#...#...#.....#.....#...#.....#.#.......#.....#.#...#...#.....#.#.#...#.#...#.#.#...........#.......#...#.#
|
||||
#.#####.#.###.#.###############.#.#.#######.#.###########.#.#####.#.###########.#.###.#.#.###.#.#.#####.#.#.#.#.#.#.#.#.#####.#.#####.#####.#
|
||||
#.......#...#.#...#.....#.......#...#.......#.#...........#.#...#.#...#.........#...#...#.....#...#...#.#.#.#.#.#...#.#.......#...#.....#.#.#
|
||||
#.#.###.#.###.###.###.#.#.#############.#####.#.#.###########.#.#.#.###.#########.###.#############.#.#.#.#.#.#.#.###.###########.#.###.#.#.#
|
||||
#.#.....#.....#...#...#.#.....#...#.....#...#.#.....#.........#.#.#.#...#...#...#.....#...#...#...#.#...#...#...#...#.......#.....#.#.....#.#
|
||||
#.###########.#.###.###.###.#.#.#.#.#.#####.#.#####.#.#####.###.#.#.#.###.#.#.#.#######.#.#.#.#.#.#.###############.#######.#.#####.#####.#.#
|
||||
#...........#.#.....#.....#.#.#.#.#.#.#...#.......#.#.#...#.#...#.#.#.....#...#.#...#...#...#...#...#.#.............#.....#...#...#...#...#.#
|
||||
#.#########.#########.###.#.#.#.###.#.#.#.#.#######.#.###.#.#.###.#.###########.#.#.#.###############.#.###############.#.#######.###.#.###.#
|
||||
#.#.......#.#.........#...#.#.#.....#.#.#...#...#...#...#.#.#...#.#...#.#.....#...#...#...#.......#.....#.........#.....#.#.........#.#.....#
|
||||
#.#.#####.#.#.###.###.#.#####.#.###.#.#.#.#.#.#.#.#####.#.#.###.#.###.#.#.###.#########.#.#.#####.#.#####.#######.#.#.###.#.#####.###.###.#.#
|
||||
#.........#...#.#.#...#.#.....#.......#.#.#.#.#.#.....#...#.....#.#.#.#.#.#.........#...#...#...#...#.....#...#...#.#...#...#...#.#...#...#.#
|
||||
###.#######.###.#.#.###.#.#####.#######.#.###.#.#####.#######.#.#.#.#.#.#.#.#######.#.#.###.###.#####.#######.#.###.###.#.###.#.###.###.###.#
|
||||
#...#.....#...#.#.#.#...#...#.#.........#.#...#.....#...#.....#.#.#.#.#...#.#.....#.#.#...#.....#.#...#.....#...#.....#.#.#...#.....#...#.#.#
|
||||
#.###.###.###.#.#.#.#.#####.#.#.#######.#.#.#.#.#######.#.#####.#.#.#.#####.###.#.#.#.###.#####.#.#.#.#.###.#.###.###.#.#.#.#######.#.###.#.#
|
||||
#...#.#.#...#...#.#.#.#.....#...#.....#.#.....#.......#.#.#...#...#.#.......#...#.#...#.#.....#.#...#...#.#.........#.#.#.#.#.#.............#
|
||||
###.#.#.###.###.#.###.#.#####.###.###.#.#########.#.#.#.#.#.#.#####.#########.###.#####.#####.#.#####.###.#.#######.###.#.#.#.#.#.#.#.###.#.#
|
||||
#...#.#.#...#.#.#.......#...#.#.......#...#.....#...#.#...#.#.................#...........#...#.#...#.#...#...#...#.....#.#.#.......#...#...#
|
||||
#####.#.#.###.#.#########.#.#.#.###.#######.###.#.###.#####.#########.#################.###.###.#.#.#.###.###.#.#.#########.#.###.#.###.###.#
|
||||
#.......#...#...#.........#.#.#.#.....#.....#...#...#.......#.........#...#.....#...#...#...#...#.#.#.....#...#.#...........#.#.#.#...#...#.#
|
||||
#.#########.#.###.#########.#.#.#####.#.#####.###############.#######.#.#.#.###.###.#.###.###.###.#.#####.#.###.###.#########.#.#.###.###.###
|
||||
#.#...#.....#...#...#.#.....#.#...#.#...#.............#.....#.....#...#.#.#...#...#.#...#...#.....#...#...#.#...#...#...#...#...#.#...#.#...#
|
||||
#.#.#.#.#####.#.###.#.#.#####.###.#.#####.###########.#.###.#####.#####.#.###.###.#.#.#####.#########.#.###.#.###.###.#.#.#####.#.#.###.###.#
|
||||
#.#.#.#.........#.....#.#.....#...#.....#.#.#.......#...#.#.#...#.......#...#.#...#...#...#.......#.......#.#.#...#...#.#.......#.......#.#.#
|
||||
#.###.###.###.#.#.###.#.###.###.#.#####.#.#.#.#.###.#####.#.#.#.###.#####.###.#.#####.#.#.#######.###.#####.#.#.###.###.###############.#.#.#
|
||||
#...#.#.......#.#...#.....#.#...#.#...#.....#.#...#.....#.#...#...#...#...#...#.....#...#.......#...#.......#.#.#...#.....#...........#...#.#
|
||||
###.#.#.#.###.#.###.#####.###.#####.#.#######.###.#####.#.#######.#####.###.#.#####.###.#.#####.###.#######.#.###.#######.#.#.#######.#####.#
|
||||
#.#.#.#...#...#.#.#...#.....#.#.....#.#...#...#.......#.#.......#.....#.....#.....#.....#...#.....#...#.....#...#.......#.....#...#.#.....#.#
|
||||
#.#.#.###.#.#.#.#.###.###.#.#.#.#####.#.#.#.###.###.###.#.#####.#####.#.#####.#.#.###.###.#.#.###.#.#.#.###.###.#####.#.#.#####.#.#.#####.#.#
|
||||
#...................#.....#...#.....#...#.....#.#...#...#.#...#.....#.#...#...#.#.#...#...#...#.....#...#...........#.#.#.#.....#...........#
|
||||
#.###.#.#.###.#####.#####.#.#######.#########.#.#####.###.#.#.#####.#.###.#####.#.###.#.#.#########.#####.###########.#.#.#.#####.#.#.#####.#
|
||||
#.#.#...#.........#...#...#.#.......#.....#.....#.....#...#.#.#...#.....#.......#.#...#.#.#.......#.......#.......#...#.#.#...#.#.#.#.....#.#
|
||||
#.#.#.#.#.###.###.#####.#####.#######.###.#.###.#.#####.###.#.#.#.#####.#########.#.#.#.###.#####.#.#####.#.#####.#.###.#.###.#.#.#.#####.#.#
|
||||
#.#...#.......#...#...#.......#.......#.#.#.....#.#.....#...#...#.....#.....#.....#.#.#.....#.....#.#.........#...........#.#.#.#.#.....#...#
|
||||
#.#.###.#.###.#.###.#.#########.#######.#.#.#####.#######.###########.#####.#####.#.#########.#####.#.#######.###########.#.#.#.#.###.#.###.#
|
||||
#.#...#.#.....#.....#.........#.#.......#.#.....#.#.....#.......#...#.....#.....#.#.......#...#...#.#.......#...#...#...#.#.#.#.#...#.#.#...#
|
||||
#.###.#.#.#.#.###.#######.#.###.#.#####.#.#####.#.#.###.#.#.###.#.###.###.#####.#.#.#.###.#.###.#.#########.###.#.#.#.#.#.#.#.#.###.#.###.###
|
||||
#...#.#.#...........#.....#.#...#.#.#...#.....#.#...#...#.#.#.#.#.#.....#.#...#.#...#...#.#.....#.........#.#...#.#...#.#...#...#.#.#.....#.#
|
||||
###.#.#.#.###.###.#.#.#######.###.#.#.#.#####.#.#####.#.#.#.#.#.#.#.###.#.#.###.#.#.###.#.#############.###.#.###.#####.#######.#.#.#.#####.#
|
||||
#.................#.#.....#...#...#.#.......#.#.#.....#.#...#.#.#.#.#.#.#.#...#.#.#...#.....#.....#...#...#.#...#...#...#...#...#.#.#.......#
|
||||
#.#.###.#.###.#.#########.#.###.#.#.#######.#.###.###########.#.#.#.#.#.#.###.#.#.###.###.#.#.###.#.#.###.#.###.#.###.###.#.#.###.#.#.###.#.#
|
||||
#.#...#.#.#...#.#.........#.#...#.#.........#.....#...#...#...#.#.#.#.#.#.#...#.#.#.....#.#...#.#...#...#...#.#.#.#...#.......#...#.#.....#.#
|
||||
#.###.#.#.#.#.#.#.#####.#.#.#.###.###.#.#########.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#####.#.#.###.#######.#####.#.#.#.###.#######.#.#.#######.#
|
||||
#...#.#...#.#.........#...#.#.#.#...#...#.....#...#.#...#...#.....#.#.....#...#.#...#...#...#.....#.....#.....#...#.....#.....#.#.#.#.......#
|
||||
#.###.#.#.#.###.#####.#.###.#.#.###.###.#.###.#.###.###########.#.#.#.#.###.###.###.#######.#.#####.#####.#.#####.#######.###.#.#.#.#.#.#####
|
||||
#.#...#...#.#.#...#...#...#.#.....#...#...#...#...#...............#.....#...#...#...........#.#...#...#.#.#...........#.#...#...#.#.#.......#
|
||||
#.#.#####.#.#.###.#.#####.#.#.#####.#.###########.###.#######.###.#########.#.###############.#.#.###.#.#.#########.#.#.#.#.###.###.###.###.#
|
||||
#...#.....#.#.....#.....#.#.#.#...#.#.............#...#...#...#.#.#.........#.........#.........#...#.#...........#.#.#.....#...#...#.....#.#
|
||||
#.#####.#.#.###.#######.###.###.#.###############.#.###.#.#.#.#.#.#.#.###############.###########.###.#.#####.#####.#.#####.#####.###.#.###.#
|
||||
#.#.....#.#...#...#...#...#.....#.....#.........#.#...#.#...#...#...#.#.............#...#.............#.#...#.....#.#.......#...#.#.#.#...#.#
|
||||
#.#.#####.#.#.###.#.#.###.###########.#.#######.#####.#.#####.###.#.#.#.###########.###.#.#####.###.#####.#.#.###.#.#########.#.#.#.#.#.#.#.#
|
||||
#...#...........#.#.#.#.#...........#...#...#.#.......#.#.#.......#.#...#.........#.....#.....#...#...#...#...#.#...#.........#.#.#.#.#.#...#
|
||||
#####.#.#.#.###.#.#.#.#.#.#.###.###.#####.#.#.#########.#.#.#######.###.#####.###.###########.###.###.#.#######.#.###.#########.#.#.#.#.#####
|
||||
#.............#...#.#...#...#.#.#...#.....#...#.........#.........#...#.....#...#...#...#...#...#.#.....#.....#.#.#...#.......#...#.#...#...#
|
||||
#.#.#####.#.###.###.#########.#.#.#####.#######.###.#############.###.###.#.#####.#.#.#.#.#.###.#.#####.#.###.#.#.#.###.#.#######.#.###.###.#
|
||||
#.#.#.....#.#...#.............#.#.#...#...#.......#.....#.......#.#.#.....#.......#.#.#...#.#...#.#...#.#.....#...#.#...#.#.....#.....#.#...#
|
||||
#.###.###.#.#.###.#.###.#.#####.#.#.#.###.#.###########.#.#####.#.#.#############.#.#.#####.#.###.#.#.###.#.###.###.#.###.#.###.#.#.###.#.#.#
|
||||
#...#.#.#.#...#.....#...#.#.....#...#.#...#.#...#.....#.#...#...#...#.....#.......#.....#.#...#...#.#.....#...#...#.#.#...#.#.#...#...#...#.#
|
||||
###.#.#.#.#.#########.###.#.#########.#.#.#.###.#.###.#.###.#.#####.#.###.#.###.###.###.#.#####.###.#########.#####.#.#####.#.###.###.#.#.#.#
|
||||
#...#...#.#.#.......#.#.......#.....#.#.#.#...#.#...#.....#.#...#.....#...#...#.....#...#.#.........#.......#.....#.#.#.....#.....#.#...#...#
|
||||
#.###.###.#.###.###.#.#.#####.#.###.#.#.#.###.#.###.#######.###.#############.#######.###.#.#########.#####.#####.#.#.#.#####.###.#.#.#.#.###
|
||||
#...#.#...#...#...#...#.#...#.#...#.....#.#.#.#...#.......#...#...........#...#.......#...#.#...#.........#.....#.....#.......#.....#.#.#.#.#
|
||||
#.#.#.#.#####.###.#####.#.#.#.###########.#.#.###.#######.###.#######.###.#.#########.#.###.#.#.#.#########.#.#######.###.#.#####.#.#.#.#.#.#
|
||||
#.#...#.....#...#...#.....#.#.......#...#...#...#.......#.....#.......#...#.......#...#.....#.#.#...#.......#.......#.....#.....#...#.....#.#
|
||||
#.#######.#####.#.#.#######.#######.#.#.#######.#.#####.#############.#.#########.#.#.#####.#.#.###.#.#########.#.###.###.#.###.#.#####.#.#.#
|
||||
#.#.....#.#...#.#.#.#...#...#.....#...#.#.......#.#.....#.............#.........#.#...#...#...#...#.#...#.......#...#.#...#.#...#.......#...#
|
||||
#.###.###.#.#.#.#.#.#.#.#####.###.#####.#.#######.#####.#####.#.#.#.#.#######.###.#.###.#.###.#.#.#.###.#.###.#.###.#.#.#.#.#.#########.#.#.#
|
||||
#...#...#.#.#.#.#.#...#...#...#.#...#...#...#.#...#...#.#.....#...#.#.#.#.....#...#...#.#.......#.#...#.#...#.#.....#.#.#...#.......#.#.....#
|
||||
###.###.#.#.#.#.#.#######.#.###.#.###.#####.#.#.#.#.#.#.#.#####.###.#.#.#.#.###.###.#.#.#########.###.#.###.#.#.#.###.#####.#######.#.###.#.#
|
||||
#.#...#.#...#...#.#.....#...........#.....#.....#...#.#.#.#.#...#...#...#.#.#...#...#.......#.....#...#...#.#...#...#.....#.#.#.....#.....#.#
|
||||
#.#.#.#.#####.###.#####.###########.###.###.#.###.#.#.#.#.#.#.#####.###.#.###.###.###########.#########.#.#.#######.#####.#.#.#.#####.#####.#
|
||||
#...#.#...#.....#...#.....#.....#.....#.#...#.#.#...#.#.............#...#.....#.#.....#.#.....#.........#.#.#.....#.......#...#.#.....#.....#
|
||||
#.#.#.#.###.###.###.#.#####.###.#.###.#.#.###.#.#####.#####.###################.#####.#.#.#####.#######.###.#.#.###############.#.###.#.#####
|
||||
#.#.#.#...#...#.#.....#...#...#...#...#...#.......#...#.....#.#...........#.........#.#.#.#.....#.......#...#.#...............#.#.#...#.#...#
|
||||
#.#.#.###.###.#.#.#####.#.###.#####.###############.###.###.#.#.#.#####.###.#######.#.#.#.###.#######.###.#########.#########.#.#.#.###.###.#
|
||||
#.#.#...#.....#...#.....#.....#...#.......#.......#.#.........#.#.........#.#.....#...#.#...#...#...#.#.#.......#...#.......#...#.#...#.#...#
|
||||
#.#####.#.#####.###.#.#########.#########.#.#####.#.#.#####.#.#.###.#####.#.#.#.#.#####.###.#.#.#.#.#.#.#.#.#.#.#.###.###########.###.#.#.#.#
|
||||
#.#.....#.#...#...#...#.#...#...........#.#.....#...#...#...#.#...#.....#...#.#.#.......#...#.#...#.#...#.#.#...#...#.#.........#.#.#.#...#.#
|
||||
#.#.#######.#.###.###.#.#.#.#.#######.#.#.#####.#######.#.###.###.#####.#######.#######.#.###.#####.#.###.#.#.#.###.#.#.#######.#.#.#.#####.#
|
||||
#...#.......#.#.....#.#...#.#.#.#...#.#.#.....#.....#.#...#...#.#...............#...#...#.#.#...#...#.#.....#.....#.#...#.....#...#.#.....#.#
|
||||
#.#####.#####.#####.#.#.#.#.#.#.#.#.#.#.#####.#.###.#.#.###.###.#####.#########.#.#.#####.#.#.#.#.###.#.###.#####.#.#.###.#.#.#####.###.###.#
|
||||
#.......#...#...#...#.#...#.#.#.#.#.#.#...#...#...#.#.....#...#.#...#.......#.....#...#...#.....#...#.#...#.....#.#.#.....#.#.....#...#.#...#
|
||||
#########.#.###.#####.#.###.#.#.#.#.#.#####.#######.#.###.###.#.#.#.#.#.###.#.###.###.#.###.#######.#.###.#####.#.#.#######.#####.#.#.#.#.###
|
||||
#...#.....#...#...#...#.#.#.....#.#...#...........#.#...#...#...#.#...#.#...#.#.....#.#.#.#.#.....#.#.....#.....#.#...#...........#.#.#.....#
|
||||
#.#.#.#####.#.###.#.###.#.#.#####.###.#.#.###.#.#.#.###.#.###.###.#####.###.#.#.#.###.#.#.#.###.#.#.###.#.#.#.###.###.#######.#.#.#.#.#.###.#
|
||||
#.#.#.#...#.#...#.#.#.#.#...#.....#...#.....#.#.#.#...#.#...#.#...#...#...#.#.#.#...#.#.#...#...#.#...#.#.#...#.#...#.#.......#.....#.#...#.#
|
||||
#.###.#.###.#####.#.#.#.###.#.#############.#.#.#.###.###.#.#.#.#####.###.#.#.#.###.#.#.#.###.#.#####.#.#.#.#.#.###.#.#.#####.#######.###.#.#
|
||||
#.....#...#.#...#...#.#.#...#...#...#...#...#...#...#...#.#...#.......#...#...#...#...#.#.#...#.#...#.#.#.#.#.#...#.#...#...#.....#...#...#.#
|
||||
#.#######.#.#.#.#####.#.#.#.###.#.#.#.#.#.###.#####.###.###########.###.#########.#####.#.#.###.#.#.#.###.###.#.#.#.#.###.#.#####.#####.###.#
|
||||
#.........#...#.......#.#.#...#...#.#.#...#.....#.....#.....#...#...#...#.......#.......#...#.....#.#...#.....#.#.#.#.#...#.......#...#.....#
|
||||
#####.#######.###.###.#.#.###.#####.#.#####.###.#####.#####.#.#.#.###.###.#####.#############.#####.#.#.#######.###.#.###.#####.#.#.#.#####.#
|
||||
#...#.#.....#...#...#.#.#.#...#...#.#.....#...#.....#.......#.#...#...#.......#.#...........#...#.#.#.#.......#.....#...#.....#.#...#.....#.#
|
||||
#.#.#.#.###.#######.###.#.#####.#.#.#####.#.#######.#######.#.#####.###.#####.###.#####.###.###.#.#.#####.###.#.#######.#####.#.#######.#.#.#
|
||||
#.#...#.#...#.....#.#...#.......#.#.......#.#.....#.....#...#.#...#.#.....#...#.........#...#...#.#.......#...#.....#.........#...#...#.#.#.#
|
||||
#.#####.#.###.###.#.#.###########.###########.#.#.#.#.###.###.#.#.#.#####.#.###.#####.#.#.###.###.#.###############.#.#######.#####.#.###.#.#
|
||||
#.....#.#.#...#.....#...........#.......#.....#...#.#...#...#.#.#.#...#...#.....#...#.#.#...#.#.....#.......#.....#.#.#...#...#...#.#.#...#.#
|
||||
#####.#.#.###.#.###.###.#.#####.#.#####.###.###.###.#.#.###.#.###.#.#.#.#.#######.#.###.###.#.#.#####.#####.#.#.#.#.###.#.#.###.#.#.#.#.#.#.#
|
||||
#...#.#.#.....#.#.........................................#.#...#...#...#.....#...#.....#...#.#.#...#.#...#.#.#.#.#...........#.#...#...#.#.#
|
||||
#.#.#.#.#####.###.#.###.#.###.#.#.#.#########.#.#.#.#.###.#.###.###.###.#####.#.#########.###.#.###.#.#.#.#.#.#.#####.#.#.#####.#########.#.#
|
||||
#.#...#.#.....#...#.....#.#...#...#.........#.#.....#...#...#...#.....#.....#.#...#.....#.....#.#...#...#.#...#.....#...#.#.....#.......#...#
|
||||
#.#####.#.#####.###.#.#.#.#########.###.#####.#.#.###.###.###.###.#.#######.#.###.#.#.#########.#.#.###.#.#######.#.#####.#.#####.###.###.###
|
||||
#.....#.#.....#.....#.#.#...#.....#...#.....#...#.......#.#...#...#.........#.#.#.#.#.........#...#.....#.....#...#...#.#.#...#.....#...#...#
|
||||
#####.#.###########.#.#.#.#.#.###.###.#####.###.#.###.#.###.#####.#.#.#.#####.#.#.#########.#.#.###.###.#.#.###.#####.#.#.###.#.#######.###.#
|
||||
#.....#...#.......#.#.#...#.#...#.#...#.#...#...#...#.#.#...#.....#.#.#.....#.#.#.........#.#...#.......#...............#.....#.#...#...#...#
|
||||
#.#######.#.#.###.#.#.#.#.#.###.#.#.###.#.###.#.#.#.#.#.#.#####.#.#.###.###.#.#.#########.#.###.#.###.#.###.#.###.#.###.#########.#.#.#.#.###
|
||||
#.#.......#.#...#...#...#.#...#.#.#...#.#.....#...#.#.#.........#.#.......#.#.#...........................#.#...#.#.........#.....#...#.#.#.#
|
||||
#.#.#######.#.#.#####.#.#.#.#.#.#.###.#.#######.#.#.#.#.###########.###.###.#.#.###.#.#########.#######.#.#.###.#.#.#######.#.#####.#####.#.#
|
||||
#.#.#.......#.....#...#.#.#.#...#...............#.#.#.............#...#.#...#.#...#.#.#.......#.........#.......#.#.....#.....#.....#...#.#.#
|
||||
#.#.#.#######.###.#####.#.#.#######.#.#####.###.#.#.#.#.#########.#.#.#.#.###.###.#.#.#.#####.#.#####.#####.###.#.#.###.#############.#.#.#.#
|
||||
#S#...........#.........#.........#.........#.........#.............#.....#.......#.#.......#.......#...........#.....#...............#.....#
|
||||
#############################################################################################################################################
|
||||
176
day16/maze.go
Normal file
176
day16/maze.go
Normal file
@@ -0,0 +1,176 @@
|
||||
package main
|
||||
|
||||
import ( "os"; "fmt"; "strings")
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Direction uint8
|
||||
|
||||
const (
|
||||
Up Direction = iota
|
||||
Down Direction = iota
|
||||
Left Direction = iota
|
||||
Right Direction = iota
|
||||
)
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Path struct {
|
||||
position [2]uint
|
||||
direction Direction
|
||||
}
|
||||
|
||||
func (p Path) StepUnbound(d Direction) Path {
|
||||
switch {
|
||||
case d == Down: p.position[1]++
|
||||
case d == Up: p.position[1]--
|
||||
case d == Left: p.position[0]--
|
||||
case d == Right: p.position[0]++
|
||||
}
|
||||
p.direction = d
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type Maze struct {
|
||||
start [2]uint
|
||||
end [2]uint
|
||||
field [][]byte
|
||||
}
|
||||
|
||||
func NewMaze(str string) *Maze {
|
||||
var maze Maze
|
||||
|
||||
for y, line := range strings.Split(str, "\n") {
|
||||
line_arr := make([]byte, len(line))
|
||||
for x, char := range []byte(line) {
|
||||
switch {
|
||||
case char == 'S':
|
||||
line_arr[x] = '.'
|
||||
maze.start = [...]uint{uint(x), uint(y)}
|
||||
case char == 'E':
|
||||
line_arr[x] = '.'
|
||||
maze.end = [...]uint{uint(x), uint(y)}
|
||||
default: line_arr[x] = char
|
||||
}
|
||||
}
|
||||
maze.field = append(maze.field, line_arr)
|
||||
}
|
||||
|
||||
return &maze
|
||||
}
|
||||
|
||||
func (m *Maze) Step(path Path) []Path {
|
||||
out := make([]Path, 0, 4)
|
||||
|
||||
if m.field[path.position[1] + 1][path.position[0]] == '.' && path.direction != Up {
|
||||
out = append(out, path.StepUnbound(Down))
|
||||
}
|
||||
if m.field[path.position[1] - 1][path.position[0]] == '.' && path.direction != Down {
|
||||
out = append(out, path.StepUnbound(Up))
|
||||
}
|
||||
if m.field[path.position[1]][path.position[0] + 1] == '.' && path.direction != Left {
|
||||
out = append(out, path.StepUnbound(Right))
|
||||
}
|
||||
if m.field[path.position[1]][path.position[0] - 1] == '.' && path.direction != Right {
|
||||
out = append(out, path.StepUnbound(Left))
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Maze) Start() Path {
|
||||
return Path{m.start, Right}
|
||||
}
|
||||
|
||||
func (m *Maze) Finished(path Path) bool {
|
||||
return m.end == path.position
|
||||
}
|
||||
|
||||
|
||||
func (m *Maze) Print() {
|
||||
for _, line := range m.field {
|
||||
fmt.Println(string(line))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
type MazeGraph struct {
|
||||
cost uint
|
||||
children []*MazeGraph
|
||||
}
|
||||
|
||||
var new_maze_graph_visited map[Path]uint
|
||||
|
||||
func NewMazeGraph(m *Maze, start Path, cost uint) *MazeGraph {
|
||||
children := make([]*MazeGraph, 0, 3)
|
||||
|
||||
// finish reached?
|
||||
if m.Finished(start) { return &MazeGraph{ cost, children } }
|
||||
|
||||
// check for loop
|
||||
value, exists := new_maze_graph_visited[start]
|
||||
if exists {
|
||||
if value <= cost { return nil }
|
||||
}
|
||||
new_maze_graph_visited[start] = cost
|
||||
|
||||
// build subgraphs/ children
|
||||
for _, path := range m.Step(start) {
|
||||
var child *MazeGraph
|
||||
if start.direction != path.direction {
|
||||
child = NewMazeGraph(m, path, cost + 1001)
|
||||
} else {
|
||||
child = NewMazeGraph(m, path, cost + 1)
|
||||
}
|
||||
|
||||
if child != nil { children = append(children, child) }
|
||||
}
|
||||
|
||||
// found dead end
|
||||
if len(children) == 0 { return nil }
|
||||
|
||||
// collapse if there is only one possible way
|
||||
if len(children) == 0 { return children[0] }
|
||||
|
||||
return &MazeGraph{ cost: cost, children: children }
|
||||
}
|
||||
|
||||
func (graph *MazeGraph) Leaves() []*MazeGraph {
|
||||
out := make([]*MazeGraph, 0)
|
||||
|
||||
if len(graph.children) == 0 {
|
||||
out = append(out, graph)
|
||||
return out
|
||||
}
|
||||
|
||||
for _, g := range graph.children {
|
||||
out = append(out, g.Leaves()...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
func check(err error) { if err != nil { panic(err) } }
|
||||
|
||||
|
||||
func main() {
|
||||
dat, err := os.ReadFile("data.txt")
|
||||
check(err)
|
||||
|
||||
input := strings.TrimSpace(string(dat))
|
||||
maze := NewMaze(input)
|
||||
|
||||
var best *MazeGraph
|
||||
new_maze_graph_visited = make(map[Path]uint)
|
||||
|
||||
for _, leave := range NewMazeGraph(maze, maze.Start(), 0).Leaves() {
|
||||
if best == nil || best.cost > leave.cost { best = leave }
|
||||
}
|
||||
|
||||
fmt.Println(best.cost)
|
||||
}
|
||||
Reference in New Issue
Block a user