work
This commit is contained in:
@@ -52,14 +52,54 @@ func Part1(input string) int {
|
||||
return dist
|
||||
}
|
||||
func Part2(input string) int {
|
||||
const saves int = 100
|
||||
count := 0
|
||||
maze := Maze{}.Parse(input)
|
||||
fmt.Println(maze)
|
||||
// fmt.Println(maze)
|
||||
data := inputGraph(*maze)
|
||||
graph := dijkstra.CreateGraph(data)
|
||||
_, count := dijkstra.GetShortestPath(data.From, data.To, graph)
|
||||
path, dist := dijkstra.GetShortestPath(data.From, data.To, graph)
|
||||
cost := make(map[Vec]int)
|
||||
cheats := []Cheat{}
|
||||
|
||||
for i, p := range path {
|
||||
cost[Vec{p.X, p.Y}] = i
|
||||
}
|
||||
cheat_data := cheatGraph(*maze)
|
||||
|
||||
for _, s := range path[:len(path)-saves] {
|
||||
fmt.Println("Checking start:", s)
|
||||
for _, e := range path[saves:] {
|
||||
fmt.Println("\tChecking end", e)
|
||||
cheat_data_1 := cheatGraphAdd(maze, cheat_data, s)
|
||||
cheat_data_2 := cheatGraphAdd(maze, cheat_data_1, e)
|
||||
cheat_graph := dijkstra.CreateGraph(cheat_data_2)
|
||||
_, cheat_dist := dijkstra.GetShortestPath(dijkstra.Point{X: s.X, Y: s.Y}, dijkstra.Point{X: e.X, Y: e.Y}, cheat_graph)
|
||||
fmt.Println("\t\tcheat distance:", cheat_dist)
|
||||
if cheat_dist <= 20 {
|
||||
cheat := Cheat{start: Vec{s.X, s.Y}, end: Vec{e.X, e.Y}, cost: cost[Vec{s.X, s.Y}] + cheat_dist + dist - cost[Vec{e.X, e.Y}]}
|
||||
fmt.Println("\t\tSaving cheat:", cheat)
|
||||
cheats = append(cheats, cheat)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, cheat := range cheats {
|
||||
save := dist - cheat.cost
|
||||
// fmt.Println("[", i, "]", "save", save)
|
||||
if save >= saves {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func abs(in int) int {
|
||||
if in < 0 {
|
||||
return in * -1
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
func inputGraph(maze Maze) dijkstra.InputGraph {
|
||||
data := dijkstra.InputGraph{}
|
||||
data.From = dijkstra.Point{X: maze.start.x, Y: maze.start.y}
|
||||
@@ -89,6 +129,58 @@ func inputGraph(maze Maze) dijkstra.InputGraph {
|
||||
return data
|
||||
}
|
||||
|
||||
func cheatGraph(maze Maze) dijkstra.InputGraph {
|
||||
data := dijkstra.InputGraph{}
|
||||
for y := 0; y < maze.height; y++ {
|
||||
for x := 0; x < maze.width; x++ {
|
||||
if maze.grid.Get(x, y) == CORRIDOR {
|
||||
continue
|
||||
}
|
||||
for _, dir := range DIRECTIONS {
|
||||
nx, ny := x+dir.x, y+dir.y
|
||||
if nx < 0 || ny < 0 || nx >= maze.width || ny >= maze.height {
|
||||
continue
|
||||
}
|
||||
if maze.grid.Get(nx, ny) == CORRIDOR {
|
||||
continue
|
||||
}
|
||||
data.Graph = append(data.Graph, dijkstra.InputData{
|
||||
Source: dijkstra.Point{X: x, Y: y},
|
||||
Destination: dijkstra.Point{X: nx, Y: ny},
|
||||
Weight: 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func cheatGraphAdd(maze *Maze, in dijkstra.InputGraph, s dijkstra.Point) dijkstra.InputGraph {
|
||||
x := s.X
|
||||
y := s.Y
|
||||
out := dijkstra.InputGraph{}
|
||||
out.From = in.From
|
||||
out.To = in.To
|
||||
out.Graph = append([]dijkstra.InputData{}, in.Graph...)
|
||||
|
||||
for _, dir := range DIRECTIONS {
|
||||
nx, ny := x+dir.x, y+dir.y
|
||||
if nx < 0 || ny < 0 || nx >= maze.width || ny >= maze.height {
|
||||
continue
|
||||
}
|
||||
if maze.grid.Get(nx, ny) == CORRIDOR {
|
||||
continue
|
||||
}
|
||||
out.Graph = append(out.Graph, dijkstra.InputData{
|
||||
Source: dijkstra.Point{X: x, Y: y},
|
||||
Destination: dijkstra.Point{X: nx, Y: ny},
|
||||
Weight: 1,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (m Maze) Parse(input string) *Maze {
|
||||
m.grid = inputs.ToGrid2D(input, "\n", "", '?', func(c string) Cell { return Cell(c[0]) })
|
||||
m.height, m.width = m.grid.SizeY(), m.grid.SizeX()
|
||||
|
||||
Reference in New Issue
Block a user