mirror of
https://github.com/Threnklyn/advent-of-code-go.git
synced 2026-05-18 19:13:27 +02:00
126 lines
2.5 KiB
Go
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
|
|
}
|