﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Day20
{
    public class DeliverPresents
    {
        public static int Deliver(int threashold)
        {
            Dictionary<int, int> houses = new Dictionary<int, int>();
            int lowestHouseNumber = int.MaxValue;
            for (int n = 1; n < lowestHouseNumber; n++)
            {
                lowestHouseNumber = Math.Min(lowestHouseNumber, Deliver(houses, n, Math.Min(threashold, lowestHouseNumber), threashold));
            }

            int min = houses.Where(x => x.Value >= threashold).Min(x => x.Key);
            if (lowestHouseNumber != min)
            {
                throw new Exception(lowestHouseNumber + " vs " + min);
            }

            return lowestHouseNumber;
        }

        public static int Deliver11(int threashold)
        {
            Dictionary<int, int> houses = new Dictionary<int, int>();
            int lowestHouseNumber = int.MaxValue;
            for (int n = 1; n < lowestHouseNumber; n++)
            {
                lowestHouseNumber = Math.Min(lowestHouseNumber, Deliver11(houses, n, Math.Min(threashold, lowestHouseNumber), threashold));
            }

            int min = houses.Where(x => x.Value >= threashold).Min(x => x.Key);
            if (lowestHouseNumber != min)
            {
                throw new Exception(lowestHouseNumber + " vs " + min);
            }

            return lowestHouseNumber;
        }

        public static int Deliver(Dictionary<int, int> houses, int elfNumber, int lowestKnown, int threashold = int.MaxValue)
        {
            int lowestHouseNumber = int.MaxValue;
            for (int n = 1; n <= lowestKnown / elfNumber; n++)
            {
                int houseNumber = n * elfNumber;
                if (!houses.TryGetValue(houseNumber, out var existing))
                {
                    existing = 0;
                }
                int totalPresents = existing + elfNumber * 10;
                houses[houseNumber] = totalPresents;
                if(totalPresents >= threashold)
                {
                    lowestHouseNumber = Math.Min(lowestHouseNumber, houseNumber);
                }
            }

            return lowestHouseNumber;
        }

        public static int Deliver11(Dictionary<int, int> houses, int elfNumber, int lowestKnown, int threashold = int.MaxValue)
        {
            int lowestHouseNumber = int.MaxValue;
            for (int n = 1; n <= 50; n++)
            {
                int houseNumber = n * elfNumber;
                if (!houses.TryGetValue(houseNumber, out var existing))
                {
                    existing = 0;
                }
                int totalPresents = existing + elfNumber * 11;
                houses[houseNumber] = totalPresents;
                if (totalPresents >= threashold)
                {
                    lowestHouseNumber = Math.Min(lowestHouseNumber, houseNumber);
                }
            }

            return lowestHouseNumber;
        }

    }
}
