Skip to content

Commit a6dca37

Browse files
committed
day12
1 parent 0d0a15a commit a6dca37

File tree

9 files changed

+407
-26
lines changed

9 files changed

+407
-26
lines changed

day12.sh

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#! /bin/bash
2+
3+
CHALLENGE=day12
4+
5+
go build -o $(pwd)/bin/$CHALLENGE ./$CHALLENGE/*.go
6+
7+
echo "Tests 1"
8+
cat $CHALLENGE/input_test_01.txt | bin/$CHALLENGE
9+
10+
echo "Tests 2"
11+
cat $CHALLENGE/input.txt | bin/$CHALLENGE

day12/debug.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
const (
9+
TopLeftCorner = '╔'
10+
TopRightCorner = '╗'
11+
BottomLeftCorner = '╚'
12+
BottomRightCorner = '╝'
13+
VerticalLine = '║'
14+
HorizontalLine = '═'
15+
)
16+
17+
func PrintGrid(grid Grid) {
18+
fmt.Print(" ")
19+
for i := 0; i < len(grid[0]); i++ {
20+
fmt.Printf("%d", i%10)
21+
}
22+
fmt.Println()
23+
24+
fmt.Printf(" %s", string(TopLeftCorner))
25+
fmt.Print(strings.Repeat(string(HorizontalLine), len(grid[0])))
26+
fmt.Print(string(TopRightCorner))
27+
fmt.Println()
28+
29+
for i, row := range grid {
30+
fmt.Printf("%d%s", i%10, string(VerticalLine))
31+
for _, r := range row {
32+
fmt.Printf("%c", r)
33+
}
34+
fmt.Print(string(VerticalLine))
35+
fmt.Println()
36+
}
37+
38+
fmt.Printf(" %s", string(BottomLeftCorner))
39+
fmt.Print(strings.Repeat(string(HorizontalLine), len(grid[0])))
40+
fmt.Print(string(BottomRightCorner))
41+
fmt.Println()
42+
}

day12/grid.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"io"
5+
6+
"github.com/dwethmar/adventofcode2022/pkg/iterate"
7+
)
8+
9+
type Grid [][]rune
10+
11+
func (g Grid) Get(x, y int) rune {
12+
return g[y][x]
13+
}
14+
15+
func CreateGrid(in io.Reader) (grid Grid, err error) {
16+
i := 0
17+
err = iterate.Lines(in, func(s string) iterate.Step {
18+
if grid == nil {
19+
grid = make(Grid, 0)
20+
}
21+
22+
grid = append(grid, make([]rune, len(s)))
23+
24+
for j, r := range s {
25+
grid[i][j] = r
26+
}
27+
28+
i++
29+
30+
return iterate.Continue
31+
})
32+
33+
return
34+
}
35+
36+
func FindPoints(grid Grid, p ...rune) []*Point {
37+
points := make([]*Point, 0)
38+
39+
for y, row := range grid {
40+
for x, r := range row {
41+
for _, c := range p {
42+
if r == c {
43+
points = append(points, &Point{x, y})
44+
}
45+
}
46+
}
47+
}
48+
49+
return points
50+
}

day12/input.txt

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
abcccccccccccccccccccccccccccccccccccccaaaaaaacccccccaaaaaaaaaaaccccccccccccccccccccaaacaaaaaaaacccccccccccccccccccccccccccccccccccaaaaa
2+
abccccccccccccccccccaaccaacccccccccccccaaaaaaaccccccccaaaaaaaaaaacccccccaaaaccccccccaaaaaaaaaaaaacccccccccccccccccccccccccccccccccaaaaaa
3+
abccccccccccccccccccaaaaaaccccccccccaaaccaaaaaacccccccaaaaaaaaaaccccccccaaaaccccccaaaaaaaaaaaaaaacccccccccccccccccccaaacccccccccccaaaaaa
4+
abcccccccccccccccccccaaaaacccccccccccaaccaacaaaccccccaaaaaaaaaaaccccccccaaaacccccaaaaaaaaacaaaaaaacccccccccccccccccaaaacccccccccccaaacaa
5+
abccccccccccccccccccaaaaaaccccccccaacaaaaaacccccccccaaaaaaaaaaaaacaaaccccaaccccccaaaaaaaaacaacccccccccccccccccaaaccaaaacccccccccccccccaa
6+
abcccccccccccccccccaaaaaaaacccccccaaaaaaaaccccccaaaaaaaacaaaacaaaaaaacccccccccaaccccaaaaaacaaacccccccccccccccaaaakkkaaccccccccccccccccaa
7+
abcccccccccccccccccaaaaaaaaccccccccaaaaaccccaacccaaaaaaaaaaaacaaaaaaccccccccccaacccaaaaaaaaaaaacccccccccccccccakkkkkklcccccccccccccccccc
8+
abaaacccccccccccaaccccaaccccccccccccaaaaaccaaacccaaaaaaaaaaaaaaaaaaaaccccccaaaaaaaacaacccaaaaaaccccccccccccccckkkkkkkllcccccccaaaccccccc
9+
abaaaacccccccaacaaccccaacccccccccccaaacaaaaaaaccccaaaaaaaaaaaaaaaaaaaacccccaaaaaaaaaaaccccaaaaacccccccccccccckkkksssllllccccccaaaaaacccc
10+
abaaaacccccccaaaaacccccccccccaaaccccaacaaaaaaccccaaaaaacaaaaaaaaaaaaaacccccccaaaaccccccccaaaaacccccccccccccckkkksssssllllcccccaaaaaacccc
11+
abaaacccccccccaaaaaaccccccccaaaaccccccccaaaaaaaacaaaaaaaaaaaaacaaacaaacccccccaaaaacccccccaaaaacccccccccccccjkkkrssssssllllccccccaaaccccc
12+
abccccccccccaaaaaaaaccccccccaaaacccccccaaaaaaaaacaacaaaaaaaaaacaaaccccccccccaaacaaccccccccccccccccccccccccjjkkrrsuuussslllllcccccaaccccc
13+
abccaaacccccaaaaacccccccccccaaaaccccccaaaaaaaaaacccccaaaaaaaaaacaaccccccccccaacccacccccccccccccccccccccjjjjjjrrrsuuuussslllllmcccddacccc
14+
abcccaaaccaccacaaaccccccccccccccccccccaaaaaaaccccccccccaaaaaaaaccccccaacccccccccccaaaaacccccccccccccccjjjjjjrrrruuuuuusssllmmmmmddddcccc
15+
abccaaaaaaaacccaaaccccccccccccccccaaacccccaaaccccccccccccaaacccccccccaacccccccccccaaaaacccccccccccccjjjjjrrrrrruuuxuuussqqqqmmmmmdddcccc
16+
abcaaaaaaaacccaaaaaacaaaaaccccccaaaaaaccccaaacccaaccccccccaaccccccaaaaaaaaccaaacccaaaaaaccccccccccccjjjjrrrrrruuuxxxuuuqqqqqqqmmmdddcccc
17+
abaaaaaaaaaccccaaaaacaaaaaccccccaaaaaaaaccccccaaaaaaccccccccccccccaaaaaaaaccaaacaaaaaaaacccccccccccjjjjrrrtttuuuuxxxyvvvvvqqqqmmmdddcccc
18+
abaaaaaaaaaccaaaaaaacaaaaaaccccccaaaaaaaacccccaaaaaaccccccccccccccccaaaaccaaaaaaaaaaaaaacccccccccaaiijqqqrttttuuuxxyyvvvvvvvqqmmmdddcccc
19+
abcaaaaaaaaccaaaaaaaaaaaaaacccccaaaaaaaacccccccaaaacccccaaaaccccccccaaaaacaaaaaaaaccaaccccccccccaaaiiiqqqttttxxxxxxyyyyyyvvvqqmmmdddcccc
20+
abcccaaaaaaacaaaaaaaaaaaaaacccccaaaaaaaaaaaccccaaaaccccaaaaacccccccaaaaaacaaaaaaacccccccccccccccaaaiiiqqqtttxxxxxxxyyyyyyvvqqqmmmdddcccc
21+
SbcccaacccaccccaaacacccaaacccccccccaaaaaaaaacccaccaccccaaaaaaccccccaaccaacccaaaaaccccccccccccccccaaiiiiqqtttxxxxEzzzyyyyvvvqqqmmmddccccc
22+
abccaaaccccccccaaccccccccccccccccccaaaaaaaaccccccccccccaaaaaaccccccccccccccaaacaaaccaacccccccccccccciiiqqqttttxxxyyyyyvvvvqqqmmmdddccccc
23+
abccccccccccccccccccccccccccccccccaaaaaaaccccccccccccccaaaaaacccccccccccccccaacccccaaaaaaaccccccccccciiiqqqttttxxyyyyyvvvrrrnnneeecccccc
24+
abcaaaaccccccccccccccccccccccccccaaaaaaaaccccccccccccccccaacccccccccccccccccccccccccaaaaacccccccccccciiiqqqqttxxyyyyyyyvvrrnnnneeecccccc
25+
abcaaaaacccccccccccccccccccccccccaaaacaaacccaccaaacccccccccccccccccccccccccaaaccccaaaaaaaccccccccccccciiiqqqttwwyywwyyywwrrnnneeeccccccc
26+
abaaaaaacccaccaccccccccccccccccccaaaaccaacccaaaaaaccccccccccccccccaaaccccaaaaaacccaaaaaaaacccccccccccciiiqqqtswwwwwwwwwwwrrnnneeeccccccc
27+
abaaaaaacccaaaaccccccccaaaacccccccaaacccccccaaaaaacccccccccccccccaaaaaaccaaaaaacccaaaaaaaacaaccccccaaciiiqppsswwwwsswwwwwrrrnneeeccccccc
28+
abcaaaaacccaaaaacccccccaaaacccccccccccccccccaaaaaaaccccccccccccccaaaaaaccaaaaaacccccaaaaaaaaaccccccaaaahhpppssswwsssswwwwrrrnneeeacccccc
29+
abcaaaccccaaaaaacccccccaaaaccccccccccccccccaaaaaaaaccccccccccccccaaaaacccaaaaaccccccaacaaaaaaaaccaaaaaahhpppsssssssssrrrrrrnnneeeacccccc
30+
abccccccccaaaaaaccccccccaacccccccccccccccccaaaaaaaaccccaacccccccccaaaaaccaaaaacccccccccaaaaaaaaccaaaaachhpppssssssoosrrrrrrnnneeeaaacccc
31+
abccccccccccaaccccccccccccccccaaaaaccccccaacccaaacccaaaaacccccccccaacaacccccccccccccccccaaaaaaacccaaaaahhhppppssppooooorroonnffeaaaacccc
32+
abaaccccccccccccccccccccccccccaaaaaccccccaacccaaaccccaaaaacccccccccccccccccccccccccccaacaaaaacccccaacaahhhppppppppoooooooooonfffaaaacccc
33+
abaccccccccccccccccccccccccccaaaaaacccaaaaaaaacccccccaaaaaccccccccccccccccccccccccaaaaaaaaaaaccccccccccchhhpppppppgggoooooooffffaacccccc
34+
abaccccccccccccccccccccccccccaaaaaacccaaaaaaaaccccccaaaaaccccccacccaacccccccccccccaaaaaccccaaccccccccccchhhhhhggggggggfffffffffaaacccccc
35+
abaacccccccccccccccccccccccccaaaaaacccccaaaacccccccccaaaacccaacaacaaacccccccccccccaaaaaaacccccccccccccccchhhhgggggggggffffffffccaacccccc
36+
abcccccccaacccccccccccccccccccaaaccccccaaaaaccccccccaaaaccaaaacaaaaacccccccccccccaaaaaaaaccccccccccccccccchhhggggaaaagffffffcccccccccccc
37+
abcccccccaacccccccccccccaacccccccccccccaaaaaaccaaccccaaaaaaaaacaaaaaacccccccaaaacaaaaaaaacccccccccccaacccccccaaaacaaaacccccccccccccccccc
38+
abccccaaaaaaaacccccccaacaaaccccccccccccaaccaacaaaacccaaaaaaaacaaaaaaaaccccccaaaaccacaaaccaaaccccaaaaaacccccccaacccaaaacccccccccccccaaaaa
39+
abccccaaaaaaaacccccccaaaaaccccccccccccccccccccaaaaccccaaaaaaacaaaaaaaaccccccaaaaccccaaaccaaaaaccaaaaaaaacccccccccccaaaccccccccccccccaaaa
40+
abccccccaaaaccccccccccaaaaaaccccccccccccccccccaaaacccaaaaaaaaaaccaaccccccccccaacccccccccaaaaacccaaaaaaaacccccccccccaaaccccccccccccccaaaa
41+
abcccccaaaaaacccccccaaaaaaaacccccccccccccccccccccccaaaaaaaaaaaaaaaacccccccccccccccccccccaaaaaacccaaaaaaaccccccccccccccccccccccccccaaaaaa

day12/input_test_01.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Sabqponm
2+
abcryxxl
3+
accszExk
4+
acctuvwj
5+
abdefghi

day12/main.go

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"math"
7+
"os"
8+
"sort"
9+
"strings"
10+
"sync"
11+
)
12+
13+
const Alphabet = "abcdefghijklmnopqrstuvwxyz"
14+
15+
type Point struct {
16+
X, Y int
17+
}
18+
19+
func (p Point) String() string { return fmt.Sprintf("(%d, %d)", p.X, p.Y) }
20+
21+
func (p Point) Distance(p2 *Point) int {
22+
return int(math.Abs(float64(p.X-p2.X)) + math.Abs(float64(p.Y-p2.Y)))
23+
}
24+
25+
func main() {
26+
grid, err := CreateGrid(os.Stdin)
27+
if err != nil {
28+
log.Fatal(err)
29+
}
30+
31+
path := GetPathToSignal(grid)
32+
33+
fmt.Printf("Part 1: %d: %+v\n", len(path)-1, path)
34+
}
35+
36+
func GetPathToSignal(grid Grid) (path []*Point) {
37+
PrintGrid(grid)
38+
39+
p := FindPoints(grid, 'S', 'E')
40+
if len(p) != 2 {
41+
log.Fatal("Could not find start and end point")
42+
}
43+
44+
return Walk(grid, p[0], p[1], []string{p[0].String()})
45+
}
46+
47+
func GetHeight(grid Grid, p *Point) int {
48+
r := grid.Get(p.X, p.Y)
49+
if r == 'S' { // Your current position (S) has elevation a.
50+
return 0
51+
} else if r == 'E' { // location that should get the best signal (E) has elevation z.
52+
return 25
53+
}
54+
55+
return strings.IndexRune(Alphabet, r)
56+
}
57+
58+
func Walk(grid Grid, start *Point, end *Point, walked []string) []*Point {
59+
path := []*Point{
60+
start,
61+
}
62+
63+
currentHeight := GetHeight(grid, start)
64+
65+
neighbors := []*Point{
66+
// up
67+
{start.X, start.Y - 1},
68+
// down
69+
{start.X, start.Y + 1},
70+
// left
71+
{start.X - 1, start.Y},
72+
// right
73+
{start.X + 1, start.Y},
74+
}
75+
76+
// sort neighbors by distance to end
77+
sort.Slice(neighbors, func(i, j int) bool {
78+
return neighbors[i].Distance(end) < neighbors[j].Distance(end)
79+
})
80+
81+
directions := map[string][]*Point{}
82+
83+
wg := sync.WaitGroup{}
84+
85+
for _, n := range neighbors {
86+
// Check if we are out of bounds
87+
if n.X < 0 || n.Y < 0 || n.X >= len(grid[0]) || n.Y >= len(grid) {
88+
continue
89+
}
90+
91+
// Check if we have already walked this path
92+
if contains(walked, n.String()) {
93+
continue
94+
}
95+
96+
height := GetHeight(grid, n)
97+
98+
// Check if we can walk to this point
99+
if math.Abs(float64(currentHeight-height)) > 1 {
100+
continue
101+
}
102+
103+
walked = append(walked, n.String())
104+
105+
newWalked := make([]string, len(walked))
106+
copy(newWalked, walked)
107+
108+
wg.Add(1)
109+
110+
go func(p Point) {
111+
// Walk to the next point
112+
directions[p.String()] = Walk(grid, &p, end, newWalked)
113+
114+
defer wg.Done()
115+
}(*n)
116+
}
117+
118+
wg.Wait()
119+
120+
shortest := 0
121+
shortestPath := ""
122+
123+
// Find the shortest path
124+
for n, p := range directions {
125+
// Check if the path is empty
126+
if len(p) == 0 {
127+
continue
128+
}
129+
130+
// has reached end?
131+
if p[len(p)-1].String() != end.String() {
132+
continue
133+
}
134+
135+
// Check if this is the shortest path
136+
if shortest == 0 || len(p) < shortest {
137+
shortest = len(p)
138+
shortestPath = n
139+
}
140+
}
141+
142+
// Add the shortest path to the path
143+
if shortestPath != "" {
144+
path = append(path, directions[shortestPath]...)
145+
}
146+
147+
return path
148+
}

0 commit comments

Comments
 (0)