예제 #1
0
        static void Main(string[] args)
        {
            System.Console.WriteLine("Day 14");

            string filename = @"Datasets\day14.txt";
            Dictionary <string, Reaction> reaction = new Dictionary <string, Reaction>();

            reaction.Add("ORE", new Reaction("ORE"));

            using (StreamReader sr = new StreamReader(filename))
            {
                string[] data = sr.ReadToEnd().Trim().Split("\n");
                foreach (string line in data)
                {
                    string[] formula = line.Split("=>");

                    // result
                    string[] item = formula[1].Trim().Split(" ");
                    if (!reaction.ContainsKey(item[1]))
                    {
                        reaction.Add(item[1], new Reaction(item[1], Int64.Parse(item[0])));
                    }
                    Reaction result = reaction[item[1]];
                    result.Output = Int64.Parse(item[0]);

                    // sources
                    foreach (string s in formula[0].Split(","))
                    {
                        item = s.Trim().Split(" ");
                        result.AddSource(item[1], Int64.Parse(item[0]));
                        if (!reaction.ContainsKey(item[1]))
                        {
                            reaction.Add(item[1], new Reaction(item[1], 0));    // Skeleton reaction, to add product to
                        }
                        reaction[item[1]].AddProduct(result.Name, result.Output);
                    }
                }
            }

            // Part 1
            long requiredOre = GetRequiredOre(reaction);

            System.Console.WriteLine($"1. {requiredOre}");

            // Part 2
            long target = 1_000_000_000_000;
            long lower  = (target / requiredOre) - 1_000;
            long higher = (target / requiredOre) + 1_000_000_000;

            while (lower < higher)
            {
                long mid   = (lower + higher) / 2;
                long guess = GetRequiredOre(reaction, mid);
                if (guess > target)
                {
                    // System.Console.WriteLine($"MORE: {guess}");
                    higher = mid;
                }
                else if (guess < target)
                {
                    // System.Console.WriteLine($"LESS: {guess}");
                    if (mid == lower)
                    {
                        break;
                    }
                    lower = mid;
                }
                else
                {
                    lower = mid;
                    break;
                }
            }
            System.Console.WriteLine($"2. {lower}");
        }