-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
93 lines (75 loc) · 1.88 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"container/heap"
"fmt"
"strings"
"github.com/Alex-Waring/AoC/utils"
)
func part1(input []string, bytes int) bool {
// defer utils.Timer("part1")()
board := utils.NewBoard()
for row := 0; row < 71; row++ {
for col := 0; col < 71; col++ {
board[utils.NewPosition(row, col)] = "."
}
}
for i := 0; i < bytes; i++ {
mem := strings.Split(input[i], ",")
board[utils.NewPosition(utils.IntegerOf(mem[1]), utils.IntegerOf(mem[0]))] = "#"
}
pq := make(utils.PriorityQueue, 1)
pq[0] = utils.NewItem(utils.NewPosition(0, 0), 0, 0)
heap.Init(&pq)
cost_so_far := map[utils.Position]int{}
cost_so_far[utils.NewPosition(0, 0)] = 0
target := utils.NewPosition(70, 70)
dirs := []utils.Direction{utils.Up, utils.Down, utils.Left, utils.Right}
for pq.Len() > 0 {
item := heap.Pop(&pq).(*utils.Item)
pos := item.GetValue().(utils.Position)
cost := item.GetPriority()
if pos == target {
// fmt.Println(cost)
return true
}
for _, dir := range dirs {
newPos := pos.Move(dir, 1)
newCost := cost + 1
if tile, ok := board[newPos]; ok && tile != "#" {
if cost, ok := cost_so_far[newPos]; !ok || cost > newCost {
cost_so_far[newPos] = newCost
newItem := utils.NewItem(newPos, newCost, 0)
heap.Push(&pq, newItem)
pq.Update(newItem, newCost)
}
}
}
}
return false
}
func part2(input []string) {
defer utils.Timer("part2")()
max := 3450
start_bytes := 3450
previous_check := 1024
for {
can_escape := part1(input, start_bytes)
if can_escape {
new_start_bytes := (start_bytes + max) / 2
previous_check = start_bytes
start_bytes = new_start_bytes
} else {
if start_bytes-previous_check == 1 {
fmt.Println(input[previous_check])
return
} else {
start_bytes = (start_bytes + previous_check) / 2
}
}
}
}
func main() {
input := utils.ReadInput("input.txt")
part1(input, 1024)
part2(input)
}