about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Day14.cs102
-rw-r--r--Day15.cs102
-rw-r--r--Day16.cs25
-rw-r--r--aoc2019.csproj9
-rw-r--r--input/day14.in61
-rw-r--r--input/day15.in1
-rw-r--r--input/day16.in1
7 files changed, 301 insertions, 0 deletions
diff --git a/Day14.cs b/Day14.cs
new file mode 100644
index 0000000..99e28e0
--- /dev/null
+++ b/Day14.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace aoc2019
+{
+    internal class Day14 : Day
+    {
+        public override int DayNumber => 14;
+
+        private Dictionary<string, long> available;
+        private readonly Dictionary<string, Reaction> reactions;
+
+        private struct Component
+        {
+            public string Name { get; set; }
+            public int Quantity { get; set; }
+        }
+
+        private class Reaction
+        {
+            public Component product;
+            public Component[] reactants;
+
+            public Reaction(Component[] reactants, Component product)
+            {
+                this.reactants = reactants;
+                this.product = product;
+            }
+
+            public static Reaction Parse(string s)
+            {
+                var ss = s.Split(new[] { ", ", " => " }, System.StringSplitOptions.None);
+
+                return new Reaction(
+                    ss.Take(ss.Length - 1).Select(ParseComponent).ToArray(),
+                    ParseComponent(ss[^1])
+                );
+
+                static Component ParseComponent(string s)
+                {
+                    var i = s.IndexOf(' ');
+                    return new Component
+                    {
+                        Name = s[(i + 1)..],
+                        Quantity = int.Parse(s.Substring(i))
+                    };
+                }
+            }
+        }
+
+        private bool Consume(string chem, long quantity)
+        {
+            if (quantity <= 0)
+                throw new ArgumentOutOfRangeException();
+
+            if (!available!.ContainsKey(chem))
+                available[chem] = 0;
+
+            if (available[chem] < quantity && !Produce(chem, quantity - available[chem]))
+                return false;
+
+            available[chem] -= quantity;
+            return true;
+        }
+
+        private bool Produce(string chem, long quantity)
+        {
+            if (chem == "ORE")
+                return false;
+
+            var reaction = reactions[chem];
+            var reactionCount = (long)Math.Ceiling((double)quantity / reaction.product.Quantity);
+
+            foreach (var reactant in reaction.reactants)
+                if (!Consume(reactant.Name, reactionCount * reactant.Quantity))
+                    return false;
+
+            available![chem] = available.GetValueOrDefault(chem) + reactionCount * reaction.product.Quantity;
+            return true;
+        }
+
+        public Day14()
+        {
+            reactions = Input
+                .Select(Reaction.Parse)
+                .ToDictionary(r => r.product.Name);
+        }
+
+        public override string Part1()
+        {
+            available = new Dictionary<string, long> { { "ORE", long.MaxValue } };
+            Consume("FUEL", 1);
+            return $"{long.MaxValue - available["ORE"]}";
+        }
+
+        public override string Part2()
+        {
+            return "";
+        }
+    }
+}
diff --git a/Day15.cs b/Day15.cs
new file mode 100644
index 0000000..96e6f90
--- /dev/null
+++ b/Day15.cs
@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace aoc2019
+{
+    internal class Day15 : Day
+    {
+        public override int DayNumber => 15;
+
+        private Dictionary<string, long>? available;
+        private readonly Dictionary<string, Reaction>? reactions;
+
+        private struct Component
+        {
+            public string Name { get; set; }
+            public int Quantity { get; set; }
+        }
+
+        private class Reaction
+        {
+            public Component product;
+            public Component[] reactants;
+
+            public Reaction(Component[] reactants, Component product)
+            {
+                this.reactants = reactants;
+                this.product = product;
+            }
+
+            public static Reaction Parse(string s)
+            {
+                var ss = s.Split(new[] { ", ", " => " }, System.StringSplitOptions.None);
+
+                return new Reaction(
+                    ss.Take(ss.Length - 1).Select(ParseComponent).ToArray(),
+                    ParseComponent(ss[^1])
+                );
+
+                static Component ParseComponent(string s)
+                {
+                    var i = s.IndexOf(' ');
+                    return new Component
+                    {
+                        Name = s[(i + 1)..],
+                        Quantity = int.Parse(s.Substring(i))
+                    };
+                }
+            }
+        }
+
+        private bool Consume(string chem, long quantity)
+        {
+            if (quantity <= 0)
+                throw new ArgumentOutOfRangeException();
+
+            if (!available!.ContainsKey(chem))
+                available[chem] = 0;
+
+            if (available[chem] < quantity && !Produce(chem, quantity - available[chem]))
+                return false;
+
+            available[chem] -= quantity;
+            return true;
+        }
+
+        private bool Produce(string chem, long quantity)
+        {
+            if (chem == "ORE")
+                return false;
+
+            var reaction = reactions[chem];
+            var reactionCount = (long)Math.Ceiling((double)quantity / reaction.product.Quantity);
+
+            foreach (var reactant in reaction.reactants)
+                if (!Consume(reactant.Name, reactionCount * reactant.Quantity))
+                    return false;
+
+            available![chem] = available.GetValueOrDefault(chem) + reactionCount * reaction.product.Quantity;
+            return true;
+        }
+
+        public Day15()
+        {
+            reactions = Input
+                .Select(Reaction.Parse)
+                .ToDictionary(r => r.product.Name);
+        }
+
+        public override string Part1()
+        {
+            available = new Dictionary<string, long> { { "ORE", long.MaxValue } };
+            Consume("FUEL", 1);
+            return $"{long.MaxValue - available["ORE"]}";
+        }
+
+        public override string Part2()
+        {
+            return "";
+        }
+    }
+}
diff --git a/Day16.cs b/Day16.cs
new file mode 100644
index 0000000..9f5fc8c
--- /dev/null
+++ b/Day16.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace aoc2019
+{
+    internal class Day16 : Day
+    {
+        public override int DayNumber => 16;
+
+        public Day16()
+        {
+        }
+
+        public override string Part1()
+        {
+            return "";
+        }
+
+        public override string Part2()
+        {
+            return "";
+        }
+    }
+}
diff --git a/aoc2019.csproj b/aoc2019.csproj
index f9be1a9..5f2c061 100644
--- a/aoc2019.csproj
+++ b/aoc2019.csproj
@@ -18,6 +18,15 @@
     <None Update="input\day13.in">

       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

     </None>

+    <None Update="input\day14.in">

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+    </None>

+    <None Update="input\day15.in">

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+    </None>

+    <None Update="input\day16.in">

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+    </None>

     <None Update="input\day2.in">

       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

     </None>

diff --git a/input/day14.in b/input/day14.in
new file mode 100644
index 0000000..438d38f
--- /dev/null
+++ b/input/day14.in
@@ -0,0 +1,61 @@
+8 LHFV => 3 PMVMQ
+2 ZXNM, 1 PSVLS, 4 GRDNT, 26 GLZH, 3 VHJX, 16 BGPF, 1 LHVTN => 4 BTQL
+10 NKHSG, 20 FCPC, 11 GRDNT => 5 HDJB
+6 WPZN, 1 LHFV => 7 BGPF
+1 WDXT, 1 PLCNZ => 3 QHFKR
+12 LCHZ => 1 TPXCK
+11 LSNG => 4 XFGH
+195 ORE => 4 GRNC
+8 XFGQ => 1 GRDNT
+1 FBRG => 5 LCHZ
+7 XZBJ, 8 RSZF, 9 SVDX => 9 LWDP
+20 WDXT => 5 RQFRT
+1 LXQWG, 1 GLZH => 6 SDLJ
+4 XFGH => 1 GCZLZ
+1 WPZN => 1 FBRG
+19 XZBJ => 5 WXGV
+1 GDXC => 6 WDXT
+1 WXGV, 1 NKHSG, 2 LWDP => 5 FCNPB
+4 LWDP, 5 BGPF => 9 KLRB
+1 GMRN => 4 GLZH
+1 RQFRT => 5 SVDX
+2 HWKG => 7 LHFV
+2 LCHZ, 13 JTJT, 10 TPXCK => 3 RSZF
+29 MZTVH => 6 TSGR
+9 NRFLK, 1 SVDX => 5 NKHSG
+123 ORE => 9 GDXC
+1 PZPBV, 21 PMVMQ, 1 GCZLZ => 8 SKZGB
+3 GRNC, 5 GDXC => 8 QZVM
+6 VTDQ, 13 TCQW, 3 FCNPB, 48 PSVLS, 3 RLNF, 73 BTQL, 5 MHRVG, 26 BGPF, 26 HDJB, 5 XFGQ, 6 HTFL => 1 FUEL
+5 QZVM, 2 JTJT => 1 PXKHG
+3 LSNG, 1 PMVMQ => 8 VTDQ
+31 XFGH => 1 FCPC
+9 PSVLS => 8 FWGTF
+1 GRNC => 3 WPZN
+16 JBXDX, 4 GRNC => 6 HWKG
+1 SKZGB, 5 RSZF => 4 XZBJ
+134 ORE => 9 CTDRZ
+1 SVDX, 2 TPXCK => 7 JTJT
+6 RQFRT, 4 KBCW => 3 BGNLR
+12 KLRB, 12 LHFV => 4 HTFL
+2 GMRN => 6 XFGQ
+16 WNSW, 12 SKZGB => 8 LXQWG
+2 NRFLK, 2 CTDRZ => 9 JBXDX
+1 PZPBV => 8 RLNF
+2 JTJT, 5 GCZLZ => 3 WNSW
+5 WXGV, 2 LCHZ => 2 SCDS
+1 QHFKR => 3 GMRN
+10 JTJT, 2 HRCG => 8 KBCW
+7 HWKG => 4 PSVLS
+7 WNSW, 1 PXKHG, 3 BGNLR => 9 MZTVH
+15 TPXCK, 11 LHFV => 5 HRCG
+1 LSNG, 1 HWKG => 3 PZPBV
+7 BGPF => 9 PLCNZ
+1 ZGWT => 6 ZXNM
+26 NKHSG, 1 LHFV, 2 JTJT, 26 WXGV, 6 SDLJ, 1 KLRB, 1 TSGR => 8 TCQW
+154 ORE => 4 NRFLK
+1 GMRN => 3 VHJX
+5 QZVM, 3 GDXC => 7 LSNG
+5 WNSW => 5 ZGWT
+6 QHFKR, 8 PZPBV, 10 FBRG, 13 FWGTF, 1 LHVTN, 4 SCDS, 8 VHJX, 7 TSGR => 6 MHRVG
+12 GLZH => 5 LHVTN
\ No newline at end of file
diff --git a/input/day15.in b/input/day15.in
new file mode 100644
index 0000000..79901fe
--- /dev/null
+++ b/input/day15.in
@@ -0,0 +1 @@
+3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,1002,1034,1,1039,1001,1036,0,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,1001,1034,0,1039,102,1,1036,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,101,0,1035,1040,102,1,1038,1043,1001,1037,0,1042,1106,0,124,1001,1034,1,1039,1008,1036,0,1041,1001,1035,0,1040,102,1,1038,1043,1001,1037,0,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,9,1032,1006,1032,165,1008,1040,5,1032,1006,1032,165,1101,0,2,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1102,1,1,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,40,1044,1106,0,224,1101,0,0,1044,1106,0,224,1006,1044,247,102,1,1039,1034,101,0,1040,1035,101,0,1041,1036,1001,1043,0,1038,1001,1042,0,1037,4,1044,1106,0,0,26,29,83,66,1,36,14,44,33,12,3,15,20,56,9,35,51,55,6,20,13,71,15,23,94,38,45,15,47,30,89,39,11,55,5,9,47,29,41,36,78,12,4,65,48,66,36,94,76,30,63,41,32,1,73,1,35,65,87,46,18,90,11,44,30,73,87,8,38,46,17,78,51,34,19,53,37,26,20,24,46,64,17,6,26,41,10,62,14,88,23,94,13,55,5,45,10,39,83,99,32,34,72,30,58,33,71,47,21,38,97,38,46,41,18,39,37,8,86,55,35,4,92,19,21,53,61,6,55,69,16,85,62,26,63,17,80,33,10,53,91,2,37,94,37,93,7,97,18,55,54,36,17,62,89,12,92,32,69,4,46,47,19,89,25,12,51,91,9,1,71,35,56,39,98,48,7,49,24,95,15,45,2,1,93,82,19,7,11,70,30,64,28,27,58,4,39,30,94,72,33,43,90,98,26,32,70,1,81,25,35,47,17,31,92,15,73,13,27,72,65,30,67,2,22,89,77,30,47,12,58,26,79,22,37,74,41,3,42,30,39,67,24,18,62,98,19,59,95,25,6,67,42,35,85,51,48,7,63,17,67,53,45,13,25,43,1,54,4,65,55,20,73,32,70,1,33,39,93,88,19,35,56,21,13,53,73,31,21,44,73,31,13,69,30,42,26,51,25,90,16,49,9,93,50,28,60,24,18,61,23,11,98,19,45,77,12,61,31,3,66,56,4,77,24,59,87,31,38,65,67,7,9,23,71,9,59,35,55,83,22,12,94,17,67,87,96,63,8,29,32,34,15,55,39,60,41,74,39,81,47,51,25,26,57,28,18,60,84,20,16,66,42,14,25,16,94,2,22,74,85,19,63,32,9,19,11,91,44,34,21,1,56,12,87,8,52,18,56,7,90,5,86,81,24,98,21,9,80,59,68,10,80,53,18,75,50,9,14,43,26,29,57,86,39,41,93,3,69,55,16,84,15,22,84,30,72,19,13,15,19,80,97,79,32,68,77,82,30,19,4,71,45,67,14,95,17,54,80,88,25,13,80,41,37,96,15,28,26,33,73,32,45,79,21,52,23,98,82,21,16,13,64,32,39,93,17,33,95,61,36,12,21,3,84,4,88,22,26,59,80,27,82,2,85,79,29,33,52,17,23,95,8,64,16,56,23,42,43,18,41,11,9,84,42,62,4,67,17,98,76,99,1,16,72,72,10,79,19,76,4,54,9,99,34,33,7,97,85,19,76,93,38,6,90,37,90,2,83,61,19,43,39,2,91,17,60,21,79,2,32,94,38,32,7,64,8,14,7,68,23,28,75,24,73,50,29,63,22,89,4,51,66,2,7,33,82,13,23,84,81,23,55,68,15,27,9,97,27,79,42,86,75,56,13,95,74,5,88,25,44,99,33,14,24,29,21,78,4,15,75,32,92,74,11,56,24,57,10,28,73,8,10,90,77,30,96,8,60,3,71,20,41,9,33,89,38,74,95,4,95,35,13,18,55,10,81,9,60,17,67,7,34,48,48,15,54,79,37,66,43,22,64,28,28,4,91,5,9,92,30,64,37,98,66,15,92,2,3,25,70,25,33,61,56,25,70,58,30,41,97,18,54,10,49,45,3,1,30,57,30,46,8,55,79,39,58,46,35,19,38,80,86,4,36,75,29,62,39,71,2,41,6,66,36,99,21,61,39,72,3,48,29,43,31,59,84,71,12,52,61,82,11,56,23,51,30,60,88,65,35,48,24,58,76,49,93,51,33,72,0,0,21,21,1,10,1,0,0,0,0,0,0
diff --git a/input/day16.in b/input/day16.in
new file mode 100644
index 0000000..b8d468b
--- /dev/null
+++ b/input/day16.in
@@ -0,0 +1 @@
+59705379150220188753316412925237003623341873502562165618681895846838956306026981091618902964505317589975353803891340688726319912072762197208600522256226277045196745275925595285843490582257194963750523789260297737947126704668555847149125256177428007606338263660765335434914961324526565730304103857985860308906002394989471031058266433317378346888662323198499387391755140009824186662950694879934582661048464385141787363949242889652092761090657224259182589469166807788651557747631571357207637087168904251987880776566360681108470585488499889044851694035762709053586877815115448849654685763054406911855606283246118699187059424077564037176787976681309870931
\ No newline at end of file