about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Harris <ben@tilde.team>2019-12-12 02:19:21 -0500
committerBen Harris <ben@tilde.team>2019-12-12 02:19:21 -0500
commita0b13e3276a44e722a9c16ef018f04e05fe2e6b4 (patch)
tree618f0e3b4a0c6d859105eeb86e4031394a349c31
parentc40a820aa87e96ccdca0efe477febcaf939e1f1c (diff)
day 12
-rw-r--r--Day12.cs148
-rw-r--r--aoc2019.csproj3
-rw-r--r--input/day12.in4
-rw-r--r--lib/Extensions.cs3
4 files changed, 157 insertions, 1 deletions
diff --git a/Day12.cs b/Day12.cs
new file mode 100644
index 0000000..43682c1
--- /dev/null
+++ b/Day12.cs
@@ -0,0 +1,148 @@
+using aoc2019.lib;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace aoc2019
+{
+    internal class Day12 : Day
+    {
+        public override int DayNumber => 12;
+
+        private List<Position> moons;
+        private readonly List<Position> startingPositions;
+        private int step;
+
+        public Day12()
+        {
+            moons = Input
+                .Select(moon => 
+                    moon
+                    .TrimStart('<')
+                    .TrimEnd('>')
+                    .Split(",")
+                    .Select(val => int.Parse(val.Split("=").Last()))
+                )
+                .Select(moon => new Position(moon.ToList()))
+                .ToList();
+
+            foreach (var moon in moons)
+                moon.SetSiblings(moons);
+
+            startingPositions = moons;
+        }
+
+        public class Position
+        {
+            public int x, y, z;
+            public int dx, dy, dz;
+            List<Position> siblings;
+
+            public Position(IList<int> moon)
+            {
+                x = moon[0];
+                y = moon[1];
+                z = moon[2];
+                dx = 0; dy = 0; dz = 0;
+            }
+
+            public void SetSiblings(List<Position> positions)
+            {
+                siblings = positions.Where(p => p != this).ToList();
+            }
+
+            public override string ToString() =>
+                $"pos=<x={x}, y={y}, z={z}> vel=<x={dx}, y={dy}, z={dz}>";
+
+            internal void Gravitate()
+            {
+                foreach (var m in siblings)
+                {
+                    if (x != m.x) dx += x > m.x ? -1 : 1;
+                    if (y != m.y) dy += y > m.y ? -1 : 1;
+                    if (z != m.z) dz += z > m.z ? -1 : 1;
+                }
+            }
+
+            internal void Move()
+            {
+                x += dx;
+                y += dy;
+                z += dz;
+            }
+
+            internal int KineticEnergy =>
+                Math.Abs(x) + Math.Abs(y) + Math.Abs(z);
+            internal int PotentialEnergy =>
+                Math.Abs(dx) + Math.Abs(dy) + Math.Abs(dz);
+            internal int TotalEnergy =>
+                KineticEnergy * PotentialEnergy;
+        }
+
+        public static long LCM(long a, long b)
+        {
+            return (a * b) / GCD(a, b);
+        }
+
+        public static long GCD(long a, long b)
+        {
+            if (b == 0) return a;
+            return GCD(b, a % b);
+        }
+
+        private void Step()
+        {
+            foreach (var moon in moons)
+                moon.Gravitate();
+
+            foreach (var moon in moons)
+                moon.Move();
+        }
+
+        public override string Part1()
+        {
+            for (step = 0; step < 1000; step++)
+                Step();
+
+            return $"{moons.Sum(p => p.TotalEnergy)}";
+        }
+
+        public override string Part2()
+        {
+            moons = startingPositions;
+            step = 0;
+            var seenX = new HashSet<string>();
+            var seenY = new HashSet<string>();
+            var seenZ = new HashSet<string>();
+            int repX = 0, repY = 0, repZ = 0;
+
+            while (true)
+            {
+                if (repX != 0 && repY != 0 && repZ != 0) break;
+                Step();
+
+                if (repX == 0)
+                {
+                    var xcoords = moons.Select(m => (m.x, m.dx)).ToDelimitedString();
+                    if (seenX.Contains(xcoords)) repX = step;
+                    seenX.Add(xcoords);
+                }
+                if (repY == 0)
+                {
+                    var ycoords = moons.Select(m => (m.y, m.dy)).ToDelimitedString();
+                    if (seenY.Contains(ycoords)) repY = step;
+                    seenY.Add(ycoords);
+                }
+                if (repZ == 0)
+                {
+                    var zcoords = moons.Select(m => (m.z, m.dz)).ToDelimitedString();
+                    if (seenZ.Contains(zcoords)) repZ = step;
+                    seenZ.Add(zcoords);
+                }
+                step++;
+            }
+
+            return $"{LCM(repX, LCM(repY, repZ))}";
+        }
+    }
+}
diff --git a/aoc2019.csproj b/aoc2019.csproj
index 8a9bb28..ef2fdc5 100644
--- a/aoc2019.csproj
+++ b/aoc2019.csproj
@@ -12,6 +12,9 @@
     <None Update="input\day11.in">

       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

     </None>

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

+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

+    </None>

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

       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

     </None>

diff --git a/input/day12.in b/input/day12.in
new file mode 100644
index 0000000..071ed71
--- /dev/null
+++ b/input/day12.in
@@ -0,0 +1,4 @@
+<x=1, y=4, z=4>
+<x=-4, y=-1, z=19>
+<x=-15, y=-14, z=12>
+<x=-17, y=1, z=10>
\ No newline at end of file
diff --git a/lib/Extensions.cs b/lib/Extensions.cs
index 312af5d..3c81f17 100644
--- a/lib/Extensions.cs
+++ b/lib/Extensions.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
 using System.Linq;
 
 namespace aoc2019.lib