# jlelse’s Blog

Thoughts, stories and ideas

# Advent of Code 2020 in Go: Week 1 and Week 2

Published on in 👨‍💻 Dev

Instead of making a post every other day with all the solutions, here are my approaches for the rest of week 1 and week 2 of Advent of Code 2020.

## Day 5

Here I had to fiddle a bit, but finally found a way to convert a string with the letters for the halfs into a number. (Full solution)

``````func partition(input string, min, max int, lower, upper rune) int {
for _, c := range input {
if c == lower {
max -= (max - min + 1) / 2
} else if c == upper {
min += (max - min + 1) / 2
}
}
return min
}
``````

## Day 6

Day 6 I found relatively easy, it was mostly just parsing. (Full solution)

## Day 7

On day 7 I was able to use quite a bit of recursion and regular expressions in my solution, which was fun. My regular expressions for parsing: (Full solution)

``````mainColorRe := regexp.MustCompile(`^(?P<color>\w+ \w+) bags contain (?P<contents>.*)\.\$`)
contentRe := regexp.MustCompile(`(?P<amount>\d+) (?P<color>\w+ \w+) bags?`)
``````

## Day 8

And also on day 8 I could use a regular expression. You had to write some kind of interpreter and fix broken code in part 2. (Full solution)

## Day 9

Day 9 was about number sequences and checking them. A case for quite a few loops. Particularly helpful here were the ease of dealing with slices in Go and the method for sorting int slices built into the standard library. (Full solution)

## Day 10

Part 1 of day 10 was well doable. In Part 2 you had to calculate possible paths, which was a bit tricky. In the end I found a quite efficient recursive method: (Full solution)

``````func countPaths(current int, joltages []int, memory map[int]int) (total int) {
if len(joltages) == 0 {
return 1
}
for _, next := range joltages {
if next-current > 3 {
break
}
if _, exists := memory[next]; !exists {
memory[next] = countPaths(next, joltages[1:], memory)
}
total += memory[next]
}
return
}
``````

## Day 11

Day 11 was about occupied seats and how the status of those changes. Part 1 was only about the adjacent seats, part 2 was about the seats that can be seen. Again, I opted for lots of recursion. My solution to check if an occupied seat can be seen: (Full solution)

``````var dirs = []position{
{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1},
}

func canSee(seats [][]rune, p, dir position) bool {
return isSafe(seats, p) && seats[p.row][p.pos] != 'L' && (seats[p.row][p.pos] == '#' || canSee(seats, direction(p, dir), dir))
}

func canSeeAdjacent(seats [][]rune, pos position) (o int) {
for _, dir := range dirs {
if canSee(seats, direction(pos, dir), dir) {
o++
}
}
return
}
``````

## Day 12

The task on day 12 was a bit easier again, I think. For part 2 I didn’t bother with any complicated mathematical formulas to turn the waypoint, but used this function: (Full solution)

``````var rotateWaypoint func(int)
rotateWaypoint = func(degree int) {
switch degree {
case 90, -270:
newWpNorth, newWpEast := -wpEast, wpNorth
wpNorth = newWpNorth
wpEast = newWpEast
case 180, -180:
rotateWaypoint(90)
rotateWaypoint(90)
case 270, -90:
rotateWaypoint(90)
rotateWaypoint(90)
rotateWaypoint(90)
}
}
``````

## Day 13

Day 13, today, was about bus lines. For part 2, I wanted to try normal loops first, but that seemed very inefficient and took too long. I saw solutions online with the Chinese remainder theorem, but finally got inspired to the following solution: (Full solution)

``````t, step := 0, 1
for i, l := range buslines {
if l == -1 { // x
continue
}
for (t+i)%l != 0 {
t += step
}
step *= l
}
``````

Tags: