Dennis on technology
On Technology and Business
Advent of code 2018 - Day 1
I’m trying to keep up with the Advent of Code this year in Go.
Day 1 - part 1: Calculating the frequency from a set of plus and minus inputs
Our first exercise doesn’t seem too difficult. We’re given a list with rows like +20
and -14
and are asked to calculate the sum across the full list. My - working but probably not optimal - solution below, which iterates over the file line by line, converts the input to an signed integer, sums the resulting values and provides the total.
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
var v, result int64
// Import inputs file
f, err := os.Open("input")
check(err)
defer f.Close()
// read file line by line
scanner := bufio.NewScanner(f)
for scanner.Scan() {
n := scanner.Text()
// Convert to int and add result
if len(n) > 0 {
v, err = strconv.ParseInt(n, 10, 64)
check(err)
result += v
} else {
break
}
}
// Display frequency
fmt.Println(result)
}
func check(e error) {
if e != nil {
panic(e)
}
}
Day 1 - part 2: Iterate continuously over the list until we find a fequency that we hit twice.
Our next challenge requires us to track which frequencies we’ve already visited before and keep iterating over the list until we hit a frequency twice. The first frequency to hit twice is the correct answer. I think storing the frequencies as keys in a map
makes sense as it allows me to easily check if a frequency was visited before.
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
var input []int64
// Import inputs file
file, err := os.Open("input")
check(err)
defer file.Close()
// read file line by line into a slice
scanner := bufio.NewScanner(file)
for scanner.Scan() {
n := scanner.Text()
// Convert to int and add result to input slice
if len(n) > 0 {
v, err := strconv.ParseInt(n, 10, 64)
check(err)
input = append(input, v)
} else {
break
}
}
// Find first dual visited frequency
r := search(input)
// Display frequency
fmt.Println(r)
}
func search(input []int64) int64 {
var f int64
frequencies := make(map[int64]bool)
// loop indefinitely over the list until we find a
// frequency we already 'visited'
for {
for _, val := range input {
frequencies[f] = true
f += val
if frequencies[f] {
return f
}
}
}
}
func check(e error) {
if e != nil {
panic(e)
}
}