package main

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

func play(input []int, endAt int, debug bool) int {
	seen := make(map[int][2]int)
	for i := 0; i < len(input); i++ {
		seen[input[i]] = [2]int{i + 1, 0}
	}
	last := input[len(input)-1]
	for i := len(input); i < endAt; i++ {
		if debug {
			fmt.Printf("Turn %d: [%d]", i+1, last)
		}
		when, ok := seen[last]
		if !ok || when[1] == 0 {
			v := seen[0]
			v[0], v[1] = i+1, v[0]
			seen[0] = v
			last = 0
			if debug {
				fmt.Printf("speak zero @%+v\n", v)
			}
		} else {
			val := when[0] - when[1]
			v := seen[val]
			v[0], v[1] = i+1, v[0]
			seen[val] = v
			last = val
			if debug {
				fmt.Printf("speak %d @%+v\n", val, v)
			}
		}
	}
	return last
}

// Task1 ...
func Task1(input []int) int {
	return play(input, 2020, true)
}

// Task2 ...
func Task2(input []int) int {
	return play(input, 30000000, false)
}

func main() {
	file, _ := os.Open("input.txt")
	scanner := bufio.NewScanner(file)
	scanner.Scan()
	nums := strings.Split(scanner.Text(), ",")
	input := make([]int, len(nums))
	for i := range nums {
		input[i], _ = strconv.Atoi(nums[i])
	}
	file.Close()

	result := Task1(input)
	fmt.Printf("Task 1: %d\n", result)

	result = Task2(input)
	fmt.Printf("Task 2: %d\n", result)
}