package main

import (
	"fmt"
	"math"
	"strings"

	helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)

func main() {
	inp := helpers.StdinToString()
	part1(inp)
	fmt.Println()
	part2(inp)
}

func part1(inp string) {
	var intinp []int
	for _, v := range inp {
		intinp = append(intinp, int(byte(v)-'0'))
	}
	for i := 0; i < 100; i++ {
		intinp = runFFT(intinp)
	}
	fmt.Println("# Part 1:")
	fmt.Println(intinp[:8])
}

// Well, brute force isn't going to work
// Fortunately, the next instance of each digit is actually just the
// sum of all digits after it (%10)
func part2(inp string) {
	fullInput := strings.Repeat(inp, 10000)
	messageOffset := helpers.Atoi(inp[:7])
	var intinp []int
	for _, v := range fullInput[messageOffset:] {
		intinp = append(intinp, int(byte(v)-'0'))
	}
	for iter := 0; iter < 100; iter++ {
		sum := 0
		for i := len(intinp) - 1; i >= 0; i-- {
			sum += intinp[i]
			intinp[i] = sum % 10
		}
	}

	fmt.Println("# Part 2:")
	for _, c := range intinp[:8] {
		fmt.Print(helpers.Itoa(c))
	}
	fmt.Println()
}

func runFFT(inp []int) []int {
	var result []int
	for k := range inp {
		pattern := getPattern(len(inp), k+1)
		var wrk int
		for k, iv := range inp {
			wrk = wrk + (iv * pattern[k])
		}
		result = append(result, helpers.AbsInt(wrk%10))
	}
	return result
}

func getPattern(length, iter int) []int {
	var ret []int
	pattern := []int{0, 1, 0, -1}
	var idx int
	for len(ret) < length+1 {
		wrkIter := iter
		for ; wrkIter > 0; wrkIter-- {
			ret = append(ret, pattern[idx])
		}
		idx = (idx + 1) % len(pattern)
	}
	return ret[1 : length+1]
}

func intSliceToInt(inp []int) int {
	var ret int
	for k := len(inp) - 1; k >= 0; k-- {
		ret = ret + (inp[k] * int(math.Pow10(len(inp)-k-1)))
	}
	return ret
}