package main

import (
	"fmt"
	"sort"
	"strings"

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

func main() {
	fmt.Println("# Day 13")
	inp := h.StdinToStringSlice()
	if len(inp) != 2 {
		fmt.Println("Invalid input")
		return
	}
	part1(inp)
	part2Rework(inp)
}

func part1(inp []string) {
	me := h.Atoi(inp[0])
	pts := strings.Split(inp[1], ",")
	earliest := h.MAX_INT
	var earliestBus int
	for k := range pts {
		if pts[k] == "x" {
			continue
		}
		bus := h.Atoi(pts[k])
		div := me / bus
		wait := (bus * (div + 1)) - me
		if earliest > wait {
			earliest = wait
			earliestBus = bus
		}
	}
	fmt.Println("## Part 1")
	fmt.Printf("Answer %d\n\n", earliest*earliestBus)
}

// This may not work with all inputs...
func part2Rework(inp []string) {
	pts := strings.Split(inp[1], ",")
	buses := make(map[int]int)
	var keys []int
	for k, v := range pts {
		if v == "x" {
			continue
		}
		keys = append(keys, k)
		buses[k] = h.Atoi(v)
	}
	for _, v := range buses {
		if !h.IsPrime(v) {
			fmt.Println("Not all buses are prime numbers... This solution _may not work_. Or it may still.", h.SHRUG)
			break
		}
	}
	res := 0
	mins := buses[keys[0]]
	for k := 1; k < len(keys); k++ {
		wrk := keys[k]
		bus := buses[wrk]
		for (res+wrk)%bus != 0 {
			res = res + mins
		}
		mins = mins * bus
	}
	fmt.Println("## Part 2")
	fmt.Printf("Answer: %d\n", res)
}

/*
           7      13      59      31      19
1068781    D       .       .       .       .
1068782    .       D       .       .       .
1068783    .       .       .       .       .
1068784    .       .       .       .       .
1068785    .       .       D       .       .
1068786    .       .       .       .       .
1068787    .       .       .       D       .
1068788    D       .       .       .       D

7  = 0
13 = 1
59 = 4
31 = 6
19 = 7

*/

// I think this will get there... Eventually... Maybe...
func part2(inp []string) {
	pts := strings.Split(inp[1], ",")
	wrk := make(map[int]int)
	var keys []int
	var vals []int
	var highK, highV int
	for k := range pts {
		if pts[k] == "x" {
			continue
		}
		keys = append(keys, k)
		vals = append(vals, wrk[k])
		wrk[k] = h.Atoi(pts[k])
		if wrk[k] > highV {
			highK = k
			highV = wrk[k]
		}
	}
	sort.Sort(sort.Reverse(sort.IntSlice(keys)))
	sort.Sort(sort.Reverse(sort.IntSlice(keys)))
	target := highV - highK
	for !checkMap(target, keys, wrk) {
		target = target + highV
	}

	fmt.Println("## Part 2")
	fmt.Printf("Answer: %d\n", target)
}

func checkMap(target int, keys []int, all map[int]int) bool {
	for _, k := range keys {
		if (target+k)%all[k] != 0 {
			return false
		}
	}
	return true
}
