Skip to content

Commit a694621

Browse files
committed
Update: 2024 Day 18
1 parent 337cc0c commit a694621

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

2024/day-18/main.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"strconv"
8+
"strings"
9+
)
10+
11+
type Point struct {
12+
X, Y int
13+
}
14+
15+
func parseInput(fileName string) ([]Point, error) {
16+
file, err := os.Open(fileName)
17+
if err != nil {
18+
return nil, err
19+
}
20+
defer file.Close()
21+
22+
var points []Point
23+
scanner := bufio.NewScanner(file)
24+
for scanner.Scan() {
25+
line := scanner.Text()
26+
coords := strings.Split(line, ",")
27+
if len(coords) != 2 {
28+
return nil, fmt.Errorf("invalid input format: %s", line)
29+
}
30+
x, err1 := strconv.Atoi(coords[0])
31+
y, err2 := strconv.Atoi(coords[1])
32+
if err1 != nil || err2 != nil {
33+
return nil, fmt.Errorf("invalid coordinates: %s", line)
34+
}
35+
points = append(points, Point{X: x, Y: y})
36+
}
37+
return points, nil
38+
}
39+
40+
func buildGrid(size int) [][]bool {
41+
grid := make([][]bool, size)
42+
for i := range grid {
43+
grid[i] = make([]bool, size)
44+
}
45+
return grid
46+
}
47+
48+
func bfs(grid [][]bool, start, end Point) bool {
49+
size := len(grid)
50+
directions := []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
51+
queue := []Point{start}
52+
visited := make(map[Point]bool)
53+
visited[start] = true
54+
55+
for len(queue) > 0 {
56+
curr := queue[0]
57+
queue = queue[1:]
58+
59+
if curr == end {
60+
return true
61+
}
62+
63+
for _, dir := range directions {
64+
next := Point{X: curr.X + dir.X, Y: curr.Y + dir.Y}
65+
if next.X >= 0 && next.X < size && next.Y >= 0 && next.Y < size && !grid[next.Y][next.X] && !visited[next] {
66+
visited[next] = true
67+
queue = append(queue, next)
68+
}
69+
}
70+
}
71+
72+
return false
73+
}
74+
75+
func findShortestPath(grid [][]bool, start, end Point) int {
76+
size := len(grid)
77+
directions := []Point{{0, 1}, {1, 0}, {0, -1}, {-1, 0}}
78+
queue := []struct {
79+
Point Point
80+
Steps int
81+
}{{Point: start, Steps: 0}}
82+
visited := make(map[Point]bool)
83+
visited[start] = true
84+
85+
for len(queue) > 0 {
86+
curr := queue[0]
87+
queue = queue[1:]
88+
89+
if curr.Point == end {
90+
return curr.Steps
91+
}
92+
93+
for _, dir := range directions {
94+
next := Point{X: curr.Point.X + dir.X, Y: curr.Point.Y + dir.Y}
95+
if next.X >= 0 && next.X < size && next.Y >= 0 && next.Y < size && !grid[next.Y][next.X] && !visited[next] {
96+
visited[next] = true
97+
queue = append(queue, struct {
98+
Point Point
99+
Steps int
100+
}{Point: next, Steps: curr.Steps + 1})
101+
}
102+
}
103+
}
104+
105+
return -1
106+
}
107+
108+
func main() {
109+
inputFile := "input.txt"
110+
points, err := parseInput(inputFile)
111+
if err != nil {
112+
fmt.Println("Error parsing input:", err)
113+
return
114+
}
115+
116+
size := 71
117+
grid := buildGrid(size)
118+
start := Point{X: 0, Y: 0}
119+
end := Point{X: size - 1, Y: size - 1}
120+
121+
// Part 1: Find the shortest path after 1024 bytes
122+
for i := 0; i < 1024 && i < len(points); i++ {
123+
point := points[i]
124+
grid[point.Y][point.X] = true
125+
}
126+
shortestPath := findShortestPath(grid, start, end)
127+
if shortestPath == -1 {
128+
fmt.Println("No valid path to the exit after 1024 bytes.")
129+
} else {
130+
fmt.Printf("Shortest Path after 1024 bytes: %d\n", shortestPath)
131+
}
132+
133+
// Reset the grid for Part 2
134+
grid = buildGrid(size)
135+
136+
// Part 2: Find the first byte that blocks the path
137+
for _, point := range points {
138+
grid[point.Y][point.X] = true
139+
if !bfs(grid, start, end) {
140+
fmt.Printf("First blocking byte: %d,%d\n", point.X, point.Y)
141+
break
142+
}
143+
}
144+
}

2024/day-18/main1.go

Whitespace-only changes.

0 commit comments

Comments
 (0)