package main

import (
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

var input string
var recipes []byte
var elfLocations []int

func main() {
	input = "290431"
	if len(os.Args) > 1 {
		input = os.Args[1]
	}
	part1()
	part2()
}

func part1() {
	fmt.Println("= Part 1 =")
	elfLocations = []int{0, 1}
	recipes = []byte{'3', '7'}
	inp := Atoi(input)
	for len(recipes) < inp+10 {
		tick()
		moveElves()
	}
	fmt.Println(string(recipes[inp:]))
	fmt.Println()
}

func part2() {
	fmt.Println("= Part 2 =")
	elfLocations = []int{0, 1}
	recipes = []byte{'3', '7'}

	for i := 0; i < 30000000; i++ {
		tick()
		moveElves()
	}
	fmt.Println(strings.Index(string(recipes), input))
}

func tick() {
	r1, r2 := getElfRecipes()
	sum := []byte(strconv.Itoa(int(r1 - '0' + r2 - '0')))
	recipes = append(recipes, sum...)
}

func getElfRecipes() (byte, byte) {
	lgt := len(recipes)
	if lgt <= elfLocations[0] || lgt <= elfLocations[1] {
		fmt.Println(elfLocations[0], elfLocations[1], len(recipes))
		os.Exit(0)
	}
	return recipes[elfLocations[0]], recipes[elfLocations[1]]
}

func moveElves() {
	for num := range elfLocations {
		newLoc := (elfLocations[num] + int(recipes[elfLocations[num]]-'0') + 1) % len(recipes)
		elfLocations[num] = newLoc
	}
}

func Atoi(i string) int {
	var ret int
	var err error
	if ret, err = strconv.Atoi(i); err != nil {
		log.Fatal("Invalid Atoi")
	}
	return ret
}
