-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path14.linq
83 lines (73 loc) · 2.61 KB
/
14.linq
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<Query Kind="Program" />
Dictionary<Pair, List<Pair>> _reactions;
void Main()
{
ParseInput();
long p1 = Ore(1);
long targetOre = 1000000000000;
long lowFuel = 1;
long highFuel = 1000000000000;
while ((highFuel - lowFuel) > 1)
{
long midpoint = (highFuel-lowFuel)/2+lowFuel;
long actualFuel = Ore(midpoint);
if (actualFuel > targetOre) { highFuel = midpoint; }
else if (actualFuel < targetOre) { lowFuel = midpoint; }
else { lowFuel = midpoint; highFuel = midpoint; }
}
$"P1: {p1}".Dump();
$"P2: {lowFuel}".Dump();
}
long Ore(long startingFuel)
{
var chemicals = _reactions.SelectMany(c => c.Value).Select(c => c.Chemical).Distinct().ToArray();
Dictionary<string, long> amounts = new Dictionary<string, long>();
foreach (var c in chemicals) { amounts[c] = 0; }
amounts.Add(FUEL, startingFuel);
while (amounts.Where(a => a.Key != ORE).Any(a => a.Value > 0))
{
var nextChemical = amounts.Where(a => a.Value > 0 && a.Key != ORE).First();
var matchingReaction = _reactions.SingleOrDefault(c => c.Key.Chemical == nextChemical.Key);
long multipler = (long)Math.Floor((double)(nextChemical.Value / matchingReaction.Key.Amount));
if (multipler == 0) multipler = 1;
amounts[nextChemical.Key] -= (matchingReaction.Key.Amount * multipler);
foreach (var pair in matchingReaction.Value)
{
amounts[pair.Chemical] += (pair.Amount * multipler);
}
}
long ore = amounts[ORE];
return ore;
}
const string ORE = "ORE";
const string FUEL = "FUEL";
public class Pair
{
public Pair(string e, int n)
{
Chemical = e;
Amount = n;
}
public string Chemical { get; set; }
public long Amount { get; set; }
}
void ParseInput()
{
Directory.SetCurrentDirectory(Path.GetDirectoryName(Util.CurrentQueryPath));
string[] inputLines = File.ReadAllLines("14.txt").ToArray();
_reactions = new Dictionary<Pair, System.Collections.Generic.List<Pair>>();
foreach (var il in inputLines)
{
List<Pair> pairs = new List<Pair>();
string[] parts = il.Split(new[] { " => " }, StringSplitOptions.RemoveEmptyEntries);
foreach (var part in parts[0].Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries))
{
int n = int.Parse(part.Split(' ')[0]);
string e = part.Split(' ')[1];
pairs.Add(new Pair(e, n));
}
int resultN = int.Parse(parts[1].Split(' ')[0]);
string resultE = parts[1].Split(' ')[1];
_reactions.Add(new Pair(resultE, resultN), pairs);
}
}