Files
advent-of-code-go/2018/day14/main.go
T

126 lines
2.5 KiB
Go

package main
import (
"flag"
"fmt"
"strconv"
"strings"
"github.com/alexchao26/advent-of-code-go/cast"
"github.com/alexchao26/advent-of-code-go/util"
)
func main() {
var part int
flag.IntVar(&part, "part", 1, "part 1 or 2")
flag.Parse()
fmt.Println("Running part", part)
if part == 1 {
ans := part1(util.ReadFile("./input.txt"))
fmt.Println("Output:", ans)
} else {
ans := part2(util.ReadFile("./input.txt"))
fmt.Println("Output:", ans)
}
}
func part1(input string) int {
recipesWanted := parseInput(input)
recipes := []int{3, 7}
elf1, elf2 := 0, 1
for len(recipes) < recipesWanted+10 {
recipes, elf1, elf2 = step(recipes, elf1, elf2)
// fmt.Println("new recipes", recipes)
// fmt.Println("new elf indices", elf1, elf2)
}
ans := 0
for i := 0; i < 10; i++ {
ans *= 10
ans += recipes[i+recipesWanted]
}
return ans
}
func part2(input string) int {
patternToFind := parseInput(input)
recipes := []int{3, 7}
elf1, elf2 := 0, 1
var recipesToLeft int
for recipesToLeft == 0 {
recipes, elf1, elf2 = step(recipes, elf1, elf2)
// check patterns
recipesToLeft = patternMatch(recipes, patternToFind)
}
return recipesToLeft
}
func parseInput(input string) int {
lines := strings.Split(input, "\n")
return cast.ToInt(lines[0])
}
func step(recipes []int, elf1, elf2 int) ([]int, int, int) {
recipe1, recipe2 := recipes[elf1], recipes[elf2]
newRecipe := recipe1 + recipe2
// add new recipes onto slice
if newRecipe >= 10 {
recipes = append(recipes, 1)
}
recipes = append(recipes, newRecipe%10)
// get new elf indices
elf1 += recipe1 + 1
elf2 += recipe2 + 1
elf1 %= len(recipes)
elf2 %= len(recipes)
return recipes, elf1, elf2
}
func patternMatch(recipes []int, patternToFind int) int {
patternLength := len(strconv.Itoa(patternToFind))
// not enough recipes to compare
if len(recipes) < patternLength {
return 0
}
// check last two recipes in recipes slice (because it will grow by at most
// 2 recipes per step
var pattern int
// get first pattern
for i := len(recipes) - patternLength; i < len(recipes); i++ {
pattern *= 10
pattern += recipes[i]
}
if pattern == patternToFind {
return len(recipes) - patternLength
}
// check second pattern
// removes one's digit
pattern /= 10
// add new 10^6 digit
if index := len(recipes) - patternLength - 1; index >= 0 {
pattern += 100000 * recipes[index]
}
if pattern == patternToFind {
return len(recipes) - patternLength - 1
}
// return zero when no pattern is found
return 0
}