package main

import (
	"fmt"
	"os"
	"strconv"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: day20 <number>")
		os.Exit(1)
	}
	numPresents := mustAtoi(os.Args[1])

	// 831600 was the lowest for part 1
	// Part 2 won't be lower, so...
	// 884520 for Part 2?
	houseNum := 884500
	k := receivedPresentsPt2(houseNum)
	lastFound := houseNum
	for {
		houseNum = houseNum + 10
		k = receivedPresentsPt2(houseNum)
		if k >= (numPresents / 4 * 3) {
			fmt.Print("O")
		} else if k >= numPresents/2 {
			fmt.Print("o")
		} else if k >= numPresents/4 {
			fmt.Print(".")
		}
		if k >= numPresents {
			fmt.Print(" House number " + strconv.Itoa(houseNum) + " received " + strconv.Itoa(k) + " presents.")
			fmt.Println("(" + strconv.Itoa(lastFound-houseNum) + ")")
			lastFound = houseNum
		}
	}
	/*
		for houseNum > 40000 { //k < numPresents {
			if houseNum%100000 == 0 {
				fmt.Print("o")
			} else if houseNum%1000 == 0 {
				fmt.Print(".")
			}
			houseNum = houseNum - 10 //-- // = houseNum - 360
			k = receivedPresentsPt1(houseNum)
			if k >= numPresents {
				fmt.Print(" House number " + strconv.Itoa(houseNum) + " received " + strconv.Itoa(k) + " presents.")
				fmt.Println("(" + strconv.Itoa(lastFound-houseNum) + ")")
				lastFound = houseNum
			}
		}
	*/
}

func receivedPresentsPt2(house int) int {
	var ret int
	elves := getFactors(house)
	for i := range elves {
		if (house / elves[i]) <= 50 {
			ret += elves[i] * 11
		}
	}
	return ret
}

func receivedPresentsPt1(house int) int {
	var ret int
	elves := getFactors(house)
	for i := range elves {
		ret += elves[i] * 10
	}
	return ret
}

func getFactors(n int) []int {
	var ret []int
	bot := 1
	top := n
	for bot < n/2 {
		if n%bot == 0 {
			top = n / bot
			if top == bot {
				ret = addUnique(ret, bot)
			} else {
				ret = addUnique(ret, bot)
				ret = addUnique(ret, top)
			}
		}
		bot++
	}
	return ret
}

func addUnique(sl []int, n int) []int {
	for i := 0; i < len(sl); i++ {
		if sl[i] == n {
			return sl
		}
	}
	return append(sl, n)
}

func mustAtoi(s string) int {
	var i int
	var err error
	if i, err = strconv.Atoi(s); err != nil {
		fmt.Println("Tried to atoi " + s)
		os.Exit(1)
	}
	return i
}
