diff --git a/.drone.yml b/.drone.yml
index 09bd08f..1502452 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -4,7 +4,7 @@ name: run
steps:
- name: run
- image: mcr.microsoft.com/dotnet/sdk:latest
+ image: mcr.microsoft.com/dotnet/sdk:6.0
commands:
- dotnet test
- dotnet run --project aoc2019/aoc2019.csproj
diff --git a/aoc2019.test/Tests.cs b/aoc2019.test/Tests.cs
index acfb08d..22566e0 100644
--- a/aoc2019.test/Tests.cs
+++ b/aoc2019.test/Tests.cs
@@ -1,60 +1,58 @@
using System;
using System.Diagnostics;
-using aoc2019.lib;
using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace aoc2019.test
+namespace aoc2019.test;
+
+[TestClass]
+public class Tests
{
- [TestClass]
- public class Tests
+ [DataTestMethod]
+ [DataRow(typeof(Day01), "3394106", "5088280")]
+ [DataRow(typeof(Day02), "3085697", "9425")]
+ [DataRow(typeof(Day03), "1195", "91518")]
+ [DataRow(typeof(Day04), "1079", "699")]
+ [DataRow(typeof(Day05), "7692125", "14340395")]
+ [DataRow(typeof(Day06), "145250", "274")]
+ [DataRow(typeof(Day07), "19650", "35961106")]
+ [DataRow(typeof(Day08), "2413",
+ "\nxxx xx xxx xxxx xxx \nx x x x x x x x x \nxxx x x x x xxx \nx x x xxx x x x \nx x x x x x x x \nxxx xx x xxxx xxx ")]
+ [DataRow(typeof(Day09), "3409270027", "82760")]
+ [DataRow(typeof(Day10), "260", "608")]
+ [DataRow(typeof(Day11), "2054",
+ "\n # # ### #### #### ## ## # # ### \n # # # # # # # # # # # # # \n ## # # # ### # # # #### ### \n # # ### # # #### # # # # # \n # # # # # # # # # # # # # # \n # # # # #### #### # # ## # # ### ")]
+ [DataRow(typeof(Day12), "10635", "583523031727256")]
+ //[DataRow(typeof(Day13), "361", "after 7133 moves, the score is: 17590")]
+ [DataRow(typeof(Day14), "397771", "3126714")]
+ [DataRow(typeof(Day15), "280", "400")]
+ [DataRow(typeof(Day16), "90744714", "82994322")]
+ [DataRow(typeof(Day17), "2804", "")]
+ [DataRow(typeof(Day19), "114", "10671712")]
+ [DataRow(typeof(Day21), "", "")]
+ [DataRow(typeof(Day23), "23626", "19019")]
+ public void TestAllDays(Type dayType, string part1, string part2)
{
- [DataTestMethod]
- [DataRow(typeof(Day01), "3394106", "5088280")]
- [DataRow(typeof(Day02), "3085697", "9425")]
- [DataRow(typeof(Day03), "1195", "91518")]
- [DataRow(typeof(Day04), "1079", "699")]
- [DataRow(typeof(Day05), "7692125", "14340395")]
- [DataRow(typeof(Day06), "145250", "274")]
- [DataRow(typeof(Day07), "19650", "35961106")]
- [DataRow(typeof(Day08), "2413",
- "\nxxx xx xxx xxxx xxx \nx x x x x x x x x \nxxx x x x x xxx \nx x x xxx x x x \nx x x x x x x x \nxxx xx x xxxx xxx ")]
- [DataRow(typeof(Day09), "3409270027", "82760")]
- [DataRow(typeof(Day10), "260", "608")]
- [DataRow(typeof(Day11), "2054",
- "\n # # ### #### #### ## ## # # ### \n # # # # # # # # # # # # # \n ## # # # ### # # # #### ### \n # # ### # # #### # # # # # \n # # # # # # # # # # # # # # \n # # # # #### #### # # ## # # ### ")]
- [DataRow(typeof(Day12), "10635", "583523031727256")]
- //[DataRow(typeof(Day13), "361", "after 7133 moves, the score is: 17590")]
- [DataRow(typeof(Day14), "397771", "3126714")]
- [DataRow(typeof(Day15), "280", "400")]
- [DataRow(typeof(Day16), "90744714", "82994322")]
- [DataRow(typeof(Day17), "2804", "")]
- [DataRow(typeof(Day19), "114", "10671712")]
- [DataRow(typeof(Day21), "", "")]
- [DataRow(typeof(Day23), "23626", "19019")]
- public void TestAllDays(Type dayType, string part1, string part2)
- {
- // create day instance
- var s = Stopwatch.StartNew();
- var day = (Day) Activator.CreateInstance(dayType);
- s.Stop();
- Assert.IsNotNull(day, "failed to create day object");
- Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in constructor");
+ // create day instance
+ var s = Stopwatch.StartNew();
+ var day = (Day)Activator.CreateInstance(dayType);
+ s.Stop();
+ Assert.IsNotNull(day, "failed to create day object");
+ Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in constructor");
- // part 1
- s.Reset();
- s.Start();
- var part1Actual = day.Part1();
- s.Stop();
- Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in part1");
- Assert.AreEqual(part1, part1Actual, $"Incorrect answer for Day {day.DayNumber} Part1");
+ // part 1
+ s.Reset();
+ s.Start();
+ var part1Actual = day.Part1();
+ s.Stop();
+ Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in part1");
+ Assert.AreEqual(part1, part1Actual, $"Incorrect answer for Day {day.DayNumber} Part1");
- // part 2
- s.Reset();
- s.Start();
- var part2Actual = day.Part2();
- s.Stop();
- Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in part2");
- Assert.AreEqual(part2, part2Actual, $"Incorrect answer for Day {day.DayNumber} Part2");
- }
+ // part 2
+ s.Reset();
+ s.Start();
+ var part2Actual = day.Part2();
+ s.Stop();
+ Console.WriteLine($"{s.ScaleMilliseconds()}ms elapsed in part2");
+ Assert.AreEqual(part2, part2Actual, $"Incorrect answer for Day {day.DayNumber} Part2");
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019.test/aoc2019.test.csproj b/aoc2019.test/aoc2019.test.csproj
index f3b9de8..656cbb3 100644
--- a/aoc2019.test/aoc2019.test.csproj
+++ b/aoc2019.test/aoc2019.test.csproj
@@ -1,7 +1,7 @@
- net5.0
+ net6.0
false
diff --git a/aoc2019/Day.cs b/aoc2019/Day.cs
index e1bdb25..6bff284 100644
--- a/aoc2019/Day.cs
+++ b/aoc2019/Day.cs
@@ -1,49 +1,44 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using aoc2019.lib;
+using System.Diagnostics;
-namespace aoc2019
+namespace aoc2019;
+
+public abstract class Day
{
- public abstract class Day
+ protected Day(int dayNumber, string puzzleName)
{
- protected Day(int dayNumber, string puzzleName)
- {
- DayNumber = dayNumber;
- PuzzleName = puzzleName;
- }
-
- public int DayNumber { get; }
- public string PuzzleName { get; }
-
- protected virtual IEnumerable Input =>
- File.ReadLines(FileName);
-
- protected string FileName =>
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"input/day{DayNumber,2:00}.in");
-
- public void AllParts(bool verbose = true)
- {
- Console.WriteLine($"Day {DayNumber,2}: {PuzzleName}");
- var s = Stopwatch.StartNew();
- var part1 = Part1();
- s.Stop();
- Console.Write($"Part1: {part1,-15} ");
- Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
-
- s.Reset();
-
- s.Start();
- var part2 = Part2();
- s.Stop();
- Console.Write($"Part2: {part2,-15} ");
- Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
-
- Console.WriteLine();
- }
-
- public abstract string Part1();
- public abstract string Part2();
+ DayNumber = dayNumber;
+ PuzzleName = puzzleName;
}
-}
\ No newline at end of file
+
+ public int DayNumber { get; }
+ public string PuzzleName { get; }
+
+ protected virtual IEnumerable Input =>
+ File.ReadLines(FileName);
+
+ protected string FileName =>
+ Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"input/day{DayNumber,2:00}.in");
+
+ public void AllParts(bool verbose = true)
+ {
+ Console.WriteLine($"Day {DayNumber,2}: {PuzzleName}");
+ var s = Stopwatch.StartNew();
+ var part1 = Part1();
+ s.Stop();
+ Console.Write($"Part1: {part1,-15} ");
+ Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
+
+ s.Reset();
+
+ s.Start();
+ var part2 = Part2();
+ s.Stop();
+ Console.Write($"Part2: {part2,-15} ");
+ Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
+
+ Console.WriteLine();
+ }
+
+ public abstract string Part1();
+ public abstract string Part2();
+}
diff --git a/aoc2019/Day01.cs b/aoc2019/Day01.cs
index 6ebdce5..aa2bc8e 100644
--- a/aoc2019/Day01.cs
+++ b/aoc2019/Day01.cs
@@ -1,43 +1,39 @@
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day01 : Day
{
- public sealed class Day01 : Day
+ private readonly IEnumerable masses;
+
+ public Day01() : base(1, "The Tyranny of the Rocket Equation")
{
- private readonly IEnumerable masses;
-
- public Day01() : base(1, "The Tyranny of the Rocket Equation")
- {
- masses = Input.Select(int.Parse);
- }
-
- private static int FuelCost(int weight)
- {
- return weight / 3 - 2;
- }
-
- private static int FullCost(int cost)
- {
- int total = 0, newcost, tmp = cost;
-
- while ((newcost = FuelCost(tmp)) >= 0)
- {
- total += newcost;
- tmp = newcost;
- }
-
- return total;
- }
-
- public override string Part1()
- {
- return $"{masses.Sum(FuelCost)}";
- }
-
- public override string Part2()
- {
- return $"{masses.Sum(FullCost)}";
- }
+ masses = Input.Select(int.Parse);
}
-}
\ No newline at end of file
+
+ private static int FuelCost(int weight)
+ {
+ return weight / 3 - 2;
+ }
+
+ private static int FullCost(int cost)
+ {
+ int total = 0, newcost, tmp = cost;
+
+ while ((newcost = FuelCost(tmp)) >= 0)
+ {
+ total += newcost;
+ tmp = newcost;
+ }
+
+ return total;
+ }
+
+ public override string Part1()
+ {
+ return $"{masses.Sum(FuelCost)}";
+ }
+
+ public override string Part2()
+ {
+ return $"{masses.Sum(FullCost)}";
+ }
+}
diff --git a/aoc2019/Day02.cs b/aoc2019/Day02.cs
index ce99a0a..89d349e 100644
--- a/aoc2019/Day02.cs
+++ b/aoc2019/Day02.cs
@@ -1,46 +1,42 @@
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day02 : Day
{
- public sealed class Day02 : Day
+ private readonly IEnumerable input;
+
+ public Day02() : base(2, "1202 Program Alarm")
{
- private readonly IEnumerable input;
+ input = Input.First().Split(',').Select(int.Parse);
+ }
- public Day02() : base(2, "1202 Program Alarm")
- {
- input = Input.First().Split(',').Select(int.Parse);
- }
+ public int RunIntCode(int noun, int verb)
+ {
+ var v = input.ToList();
+ v[1] = noun;
+ v[2] = verb;
- public int RunIntCode(int noun, int verb)
- {
- var v = input.ToList();
- v[1] = noun;
- v[2] = verb;
+ for (var i = 0; v[i] != 99; i += 4)
+ v[v[i + 3]] = v[i] switch
+ {
+ 1 => v[v[i + 1]] + v[v[i + 2]],
+ 2 => v[v[i + 1]] * v[v[i + 2]]
+ };
- for (var i = 0; v[i] != 99; i += 4)
- v[v[i + 3]] = v[i] switch
- {
- 1 => v[v[i + 1]] + v[v[i + 2]],
- 2 => v[v[i + 1]] * v[v[i + 2]]
- };
+ return v[0];
+ }
- return v[0];
- }
+ public override string Part1()
+ {
+ return $"{RunIntCode(12, 2)}";
+ }
- public override string Part1()
- {
- return $"{RunIntCode(12, 2)}";
- }
-
- public override string Part2()
- {
- for (var i = 0; i < 100; i++)
+ public override string Part2()
+ {
+ for (var i = 0; i < 100; i++)
for (var j = 0; j < 100; j++)
if (RunIntCode(i, j) == 19690720)
return $"{100 * i + j}";
- return string.Empty;
- }
+ return string.Empty;
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day03.cs b/aoc2019/Day03.cs
index bf32fb3..8b997f5 100644
--- a/aoc2019/Day03.cs
+++ b/aoc2019/Day03.cs
@@ -1,57 +1,52 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day03 : Day
{
- public sealed class Day03 : Day
+ private readonly IEnumerable<(int, int)> intersections;
+ private readonly List> wires;
+
+ public Day03() : base(3, "Crossed Wires")
{
- private readonly IEnumerable<(int, int)> intersections;
- private readonly List> wires;
-
- public Day03() : base(3, "Crossed Wires")
- {
- wires = Input.Select(ParseWire).ToList();
- intersections = wires[0].Keys.Intersect(wires[1].Keys);
- }
-
- public override string Part1()
- {
- return $"{intersections.Min(x => Math.Abs(x.Item1) + Math.Abs(x.Item2))}";
- }
-
- public override string Part2()
- {
- // add 2 to count (0, 0) on both lines
- return $"{intersections.Min(x => wires[0][x] + wires[1][x]) + 2}";
- }
-
- private static Dictionary<(int, int), int> ParseWire(string line)
- {
- var r = new Dictionary<(int, int), int>();
- int x = 0, y = 0, c = 0, i;
-
- foreach (var step in line.Split(','))
- {
- var d = int.Parse(step.Substring(1));
- switch (step[0])
- {
- case 'U':
- for (i = 0; i < d; i++) r.TryAdd((x, ++y), c++);
- break;
- case 'D':
- for (i = 0; i < d; i++) r.TryAdd((x, --y), c++);
- break;
- case 'R':
- for (i = 0; i < d; i++) r.TryAdd((++x, y), c++);
- break;
- case 'L':
- for (i = 0; i < d; i++) r.TryAdd((--x, y), c++);
- break;
- }
- }
-
- return r;
- }
+ wires = Input.Select(ParseWire).ToList();
+ intersections = wires[0].Keys.Intersect(wires[1].Keys);
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ return $"{intersections.Min(x => Math.Abs(x.Item1) + Math.Abs(x.Item2))}";
+ }
+
+ public override string Part2()
+ {
+ // add 2 to count (0, 0) on both lines
+ return $"{intersections.Min(x => wires[0][x] + wires[1][x]) + 2}";
+ }
+
+ private static Dictionary<(int, int), int> ParseWire(string line)
+ {
+ var r = new Dictionary<(int, int), int>();
+ int x = 0, y = 0, c = 0, i;
+
+ foreach (var step in line.Split(','))
+ {
+ var d = int.Parse(step.Substring(1));
+ switch (step[0])
+ {
+ case 'U':
+ for (i = 0; i < d; i++) r.TryAdd((x, ++y), c++);
+ break;
+ case 'D':
+ for (i = 0; i < d; i++) r.TryAdd((x, --y), c++);
+ break;
+ case 'R':
+ for (i = 0; i < d; i++) r.TryAdd((++x, y), c++);
+ break;
+ case 'L':
+ for (i = 0; i < d; i++) r.TryAdd((--x, y), c++);
+ break;
+ }
+ }
+
+ return r;
+ }
+}
diff --git a/aoc2019/Day04.cs b/aoc2019/Day04.cs
index 808eb64..dcf6eb7 100644
--- a/aoc2019/Day04.cs
+++ b/aoc2019/Day04.cs
@@ -1,49 +1,46 @@
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day04 : Day
{
- public sealed class Day04 : Day
+ private readonly int end;
+
+ private readonly int start;
+
+ public Day04() : base(4, "Secure Container")
{
- private readonly int end;
-
- private readonly int start;
-
- public Day04() : base(4, "Secure Container")
- {
- var range = Input.First().Split('-').Select(int.Parse).ToList();
- start = range[0];
- end = range[1];
- }
-
- private bool IsValid(int i)
- {
- var prev = 0;
- var hasDup = false;
- foreach (var c in i.ToString())
- {
- var curr = c - '0';
- if (curr < prev) return false;
- if (curr == prev) hasDup = true;
- prev = curr;
- }
-
- return i >= start && i <= end && hasDup;
- }
-
- private bool HasOnePair(int i)
- {
- var s = i.ToString();
- return IsValid(i) && s.Select(c => s.Count(j => j == c)).Any(c => c == 2);
- }
-
- public override string Part1()
- {
- return $"{Enumerable.Range(start, end).Count(IsValid)}";
- }
-
- public override string Part2()
- {
- return $"{Enumerable.Range(start, end).Count(HasOnePair)}";
- }
+ var range = Input.First().Split('-').Select(int.Parse).ToList();
+ start = range[0];
+ end = range[1];
}
-}
\ No newline at end of file
+
+ private bool IsValid(int i)
+ {
+ var prev = 0;
+ var hasDup = false;
+ foreach (var c in i.ToString())
+ {
+ var curr = c - '0';
+ if (curr < prev) return false;
+ if (curr == prev) hasDup = true;
+ prev = curr;
+ }
+
+ return i >= start && i <= end && hasDup;
+ }
+
+ private bool HasOnePair(int i)
+ {
+ var s = i.ToString();
+ return IsValid(i) && s.Select(c => s.Count(j => j == c)).Any(c => c == 2);
+ }
+
+ public override string Part1()
+ {
+ return $"{Enumerable.Range(start, end).Count(IsValid)}";
+ }
+
+ public override string Part2()
+ {
+ return $"{Enumerable.Range(start, end).Count(HasOnePair)}";
+ }
+}
diff --git a/aoc2019/Day05.cs b/aoc2019/Day05.cs
index 2020627..b91089e 100644
--- a/aoc2019/Day05.cs
+++ b/aoc2019/Day05.cs
@@ -1,78 +1,74 @@
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day05 : Day
{
- public sealed class Day05 : Day
+ private readonly IEnumerable tape;
+
+ private int output;
+
+ public Day05() : base(5, "Sunny with a Chance of Asteroids")
{
- private readonly IEnumerable tape;
+ tape = Input.First().Split(',').Select(int.Parse);
+ }
- private int output;
-
- public Day05() : base(5, "Sunny with a Chance of Asteroids")
+ public void RunIntCode(List v, int input)
+ {
+ var i = 0;
+ while (i < v.Count && v[i] != 99)
{
- tape = Input.First().Split(',').Select(int.Parse);
- }
-
- public void RunIntCode(List v, int input)
- {
- var i = 0;
- while (i < v.Count && v[i] != 99)
+ int Val(int mode, int val)
{
- int Val(int mode, int val)
- {
- return mode != 0 ? val : v[val];
- }
+ return mode != 0 ? val : v[val];
+ }
- var mode1 = v[i] / 100 % 10;
- var mode2 = v[i] / 1000;
+ var mode1 = v[i] / 100 % 10;
+ var mode2 = v[i] / 1000;
- switch (v[i] % 100)
- {
- case 1:
- v[v[i + 3]] = Val(mode1, v[i + 1]) + Val(mode2, v[i + 2]);
- i += 4;
- break;
- case 2:
- v[v[i + 3]] = Val(mode1, v[i + 1]) * Val(mode2, v[i + 2]);
- i += 4;
- break;
- case 3:
- v[v[i + 1]] = input;
- i += 2;
- break;
- case 4:
- output = Val(mode1, v[i + 1]);
- i += 2;
- break;
- case 5:
- i = Val(mode1, v[i + 1]) == 0 ? i + 3 : Val(mode2, v[i + 2]);
- break;
- case 6:
- i = Val(mode1, v[i + 1]) != 0 ? i + 3 : Val(mode2, v[i + 2]);
- break;
- case 7:
- v[v[i + 3]] = Val(mode1, v[i + 1]) < Val(mode2, v[i + 2]) ? 1 : 0;
- i += 4;
- break;
- case 8:
- v[v[i + 3]] = Val(mode1, v[i + 1]) == Val(mode2, v[i + 2]) ? 1 : 0;
- i += 4;
- break;
- }
+ switch (v[i] % 100)
+ {
+ case 1:
+ v[v[i + 3]] = Val(mode1, v[i + 1]) + Val(mode2, v[i + 2]);
+ i += 4;
+ break;
+ case 2:
+ v[v[i + 3]] = Val(mode1, v[i + 1]) * Val(mode2, v[i + 2]);
+ i += 4;
+ break;
+ case 3:
+ v[v[i + 1]] = input;
+ i += 2;
+ break;
+ case 4:
+ output = Val(mode1, v[i + 1]);
+ i += 2;
+ break;
+ case 5:
+ i = Val(mode1, v[i + 1]) == 0 ? i + 3 : Val(mode2, v[i + 2]);
+ break;
+ case 6:
+ i = Val(mode1, v[i + 1]) != 0 ? i + 3 : Val(mode2, v[i + 2]);
+ break;
+ case 7:
+ v[v[i + 3]] = Val(mode1, v[i + 1]) < Val(mode2, v[i + 2]) ? 1 : 0;
+ i += 4;
+ break;
+ case 8:
+ v[v[i + 3]] = Val(mode1, v[i + 1]) == Val(mode2, v[i + 2]) ? 1 : 0;
+ i += 4;
+ break;
}
}
-
- public override string Part1()
- {
- RunIntCode(tape.ToList(), 1);
- return $"{output}";
- }
-
- public override string Part2()
- {
- RunIntCode(tape.ToList(), 5);
- return $"{output}";
- }
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ RunIntCode(tape.ToList(), 1);
+ return $"{output}";
+ }
+
+ public override string Part2()
+ {
+ RunIntCode(tape.ToList(), 5);
+ return $"{output}";
+ }
+}
diff --git a/aoc2019/Day06.cs b/aoc2019/Day06.cs
index ede02da..1e7e3be 100644
--- a/aoc2019/Day06.cs
+++ b/aoc2019/Day06.cs
@@ -1,38 +1,34 @@
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day06 : Day
{
- public sealed class Day06 : Day
+ private readonly Dictionary input;
+
+ public Day06() : base(6, "Universal Orbit Map")
{
- private readonly Dictionary input;
-
- public Day06() : base(6, "Universal Orbit Map")
- {
- input = Input.ToDictionary(i => i.Split(')')[1], i => i.Split(')')[0]);
- }
-
- private List GetParents(string obj)
- {
- var res = new List();
- for (var curr = obj; curr != "COM"; curr = input[curr])
- res.Add(curr);
- res.Add("COM");
- return res;
- }
-
- public override string Part1()
- {
- return $"{input.Keys.Sum(o => GetParents(o).Count - 1)}";
- }
-
- public override string Part2()
- {
- var you = GetParents("YOU");
- var san = GetParents("SAN");
- var common = 1;
- for (; you[^common] == san[^common]; common++) ;
- return $"{you.Count + san.Count - common * 2}";
- }
+ input = Input.ToDictionary(i => i.Split(')')[1], i => i.Split(')')[0]);
}
-}
\ No newline at end of file
+
+ private List GetParents(string obj)
+ {
+ var res = new List();
+ for (var curr = obj; curr != "COM"; curr = input[curr])
+ res.Add(curr);
+ res.Add("COM");
+ return res;
+ }
+
+ public override string Part1()
+ {
+ return $"{input.Keys.Sum(o => GetParents(o).Count - 1)}";
+ }
+
+ public override string Part2()
+ {
+ var you = GetParents("YOU");
+ var san = GetParents("SAN");
+ var common = 1;
+ for (; you[^common] == san[^common]; common++) ;
+ return $"{you.Count + san.Count - common * 2}";
+ }
+}
diff --git a/aoc2019/Day07.cs b/aoc2019/Day07.cs
index 10684b9..4a45842 100644
--- a/aoc2019/Day07.cs
+++ b/aoc2019/Day07.cs
@@ -1,67 +1,62 @@
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day07 : Day
{
- public sealed class Day07 : Day
+ private readonly IntCodeVM[] Amplifiers = new IntCodeVM[5];
+
+ public Day07() : base(7, "Amplification Circuit")
{
- private readonly IntCodeVM[] Amplifiers = new IntCodeVM[5];
-
- public Day07() : base(7, "Amplification Circuit")
- {
- for (var i = 0; i < 5; i++) Amplifiers[i] = new IntCodeVM(Input.First());
- }
-
- public override string Part1()
- {
- long i, largest = 0;
-
- foreach (var phaseSeq in Enumerable.Range(0, 5).Permute())
- {
- i = 0;
- foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq))
- {
- vm.Reset();
- vm.Run(phase, i);
- i = vm.Result;
- }
-
- if (i > largest)
- largest = i;
- }
-
- return $"{largest}";
- }
-
- public override string Part2()
- {
- long i, largest = 0;
-
- foreach (var phaseSeq in Enumerable.Range(5, 5).Permute())
- {
- i = 0;
- foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq))
- {
- vm.Reset();
- vm.AddInput(phase);
- }
-
- var vms = new Queue(Amplifiers);
- while (vms.Count > 0)
- {
- var vm = vms.Dequeue();
- var haltType = vm.Run(i);
- if (haltType == IntCodeVM.HaltType.Waiting)
- vms.Enqueue(vm);
- i = vm.Result;
- }
-
- if (i > largest)
- largest = i;
- }
-
- return $"{largest}";
- }
+ for (var i = 0; i < 5; i++) Amplifiers[i] = new IntCodeVM(Input.First());
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ long i, largest = 0;
+
+ foreach (var phaseSeq in Enumerable.Range(0, 5).Permute())
+ {
+ i = 0;
+ foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq))
+ {
+ vm.Reset();
+ vm.Run(phase, i);
+ i = vm.Result;
+ }
+
+ if (i > largest)
+ largest = i;
+ }
+
+ return $"{largest}";
+ }
+
+ public override string Part2()
+ {
+ long i, largest = 0;
+
+ foreach (var phaseSeq in Enumerable.Range(5, 5).Permute())
+ {
+ i = 0;
+ foreach (var (vm, phase) in Amplifiers.Zip(phaseSeq))
+ {
+ vm.Reset();
+ vm.AddInput(phase);
+ }
+
+ var vms = new Queue(Amplifiers);
+ while (vms.Count > 0)
+ {
+ var vm = vms.Dequeue();
+ var haltType = vm.Run(i);
+ if (haltType == IntCodeVM.HaltType.Waiting)
+ vms.Enqueue(vm);
+ i = vm.Result;
+ }
+
+ if (i > largest)
+ largest = i;
+ }
+
+ return $"{largest}";
+ }
+}
diff --git a/aoc2019/Day08.cs b/aoc2019/Day08.cs
index 6a7bba4..9ca3321 100644
--- a/aoc2019/Day08.cs
+++ b/aoc2019/Day08.cs
@@ -1,37 +1,32 @@
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day08 : Day
{
- public sealed class Day08 : Day
+ private readonly List> photo;
+
+ public Day08() : base(8, "Space Image Format")
{
- private readonly List> photo;
-
- public Day08() : base(8, "Space Image Format")
- {
- photo = Input.First().Chunk(25 * 6).Select(s => s.ToList()).ToList();
- }
-
- public override string Part1()
- {
- var l = photo.OrderBy(layer => layer.Count(pixel => pixel == '0')).First();
- return $"{l.Count(p => p == '1') * l.Count(p => p == '2')}";
- }
-
- public override string Part2()
- {
- return "\n" + Enumerable.Range(0, 25 * 6)
- .Select(p => Enumerable.Range(0, photo.Count)
- .Select(l => photo[l][p])
- .Aggregate('2', (acc, next) =>
- acc != '2' ? acc : next == '0' ? ' ' : next
- )
- )
- .ToDelimitedString()
- .Chunk(25)
- .ToDelimitedString("\n")
- .Replace('1', 'x');
- }
+ photo = Input.First().Chunk(25 * 6).Select(s => s.ToList()).ToList();
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ var l = photo.OrderBy(layer => layer.Count(pixel => pixel == '0')).First();
+ return $"{l.Count(p => p == '1') * l.Count(p => p == '2')}";
+ }
+
+ public override string Part2()
+ {
+ return "\n" + Enumerable.Range(0, 25 * 6)
+ .Select(p => Enumerable.Range(0, photo.Count)
+ .Select(l => photo[l][p])
+ .Aggregate('2', (acc, next) =>
+ acc != '2' ? acc : next == '0' ? ' ' : next
+ )
+ )
+ .ToDelimitedString()
+ .Chunk(25)
+ .ToDelimitedString("\n")
+ .Replace('1', 'x');
+ }
+}
diff --git a/aoc2019/Day09.cs b/aoc2019/Day09.cs
index d5edd0a..9e57ab2 100644
--- a/aoc2019/Day09.cs
+++ b/aoc2019/Day09.cs
@@ -1,29 +1,25 @@
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day09 : Day
{
- public sealed class Day09 : Day
+ private readonly IntCodeVM vm;
+
+ public Day09() : base(9, "Sensor Boost")
{
- private readonly IntCodeVM vm;
-
- public Day09() : base(9, "Sensor Boost")
- {
- vm = new IntCodeVM(Input.First());
- }
-
- public override string Part1()
- {
- vm.Reset();
- vm.Run(1);
- return $"{vm.output.ToDelimitedString(",")}";
- }
-
- public override string Part2()
- {
- vm.Reset();
- vm.Run(2);
- return $"{vm.output.ToDelimitedString(",")}";
- }
+ vm = new IntCodeVM(Input.First());
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ vm.Reset();
+ vm.Run(1);
+ return $"{vm.output.ToDelimitedString(",")}";
+ }
+
+ public override string Part2()
+ {
+ vm.Reset();
+ vm.Run(2);
+ return $"{vm.output.ToDelimitedString(",")}";
+ }
+}
diff --git a/aoc2019/Day10.cs b/aoc2019/Day10.cs
index 6151e54..b12c551 100644
--- a/aoc2019/Day10.cs
+++ b/aoc2019/Day10.cs
@@ -1,73 +1,67 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day10 : Day
{
- public sealed class Day10 : Day
+ private readonly HashSet<(int x, int y)> asteroids;
+ private (int x, int y) best = (x: -1, y: -1);
+ private int bestCanSee;
+
+ public Day10() : base(10, "Monitoring Station")
{
- private readonly HashSet<(int x, int y)> asteroids;
- private (int x, int y) best = (x: -1, y: -1);
- private int bestCanSee;
-
- public Day10() : base(10, "Monitoring Station")
- {
- asteroids = Input
- .Select((r, y) => r.Select((c, x) => (x, y, isAsteroid: c == '#')).ToArray())
- .SelectMany(r => r)
- .Where(a => a.isAsteroid)
- .Select(a => (a.x, a.y))
- .ToHashSet();
- }
-
- public override string Part1()
- {
- foreach (var asteroid in asteroids)
- {
- var canSee = asteroids
- .Except(new[] {asteroid})
- .Select(a => (x: a.x - asteroid.x, y: a.y - asteroid.y))
- .GroupBy(a => Math.Atan2(a.y, a.x))
- .Count();
-
- if (canSee > bestCanSee)
- {
- best = asteroid;
- bestCanSee = canSee;
- }
- }
-
- return $"{bestCanSee}";
- }
-
- public override string Part2()
- {
- static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
- Queue<(int x, int y, double angle, double dist)> q)
- {
- if (q.Count > 0) yield return q.Dequeue();
- }
-
- return asteroids
- .Where(a => a != best)
- .Select(a =>
- {
- var xDist = a.x - best.x;
- var yDist = a.y - best.y;
- var angle = Math.Atan2(xDist, yDist);
- return (a.x, a.y, angle, dist: Math.Sqrt(xDist * xDist + yDist * yDist));
- })
- .ToLookup(a => a.angle)
- .OrderByDescending(a => a.Key)
- .Select(a => new Queue<(int x, int y, double angle, double dist)>(a.OrderBy(b => b.dist)))
- .Repeat()
- .SelectMany(GetValue)
- .Skip(199)
- .Take(1)
- .Select(a => a.x * 100 + a.y)
- .Single()
- .ToString();
- }
+ asteroids = Input
+ .Select((r, y) => r.Select((c, x) => (x, y, isAsteroid: c == '#')).ToArray())
+ .SelectMany(r => r)
+ .Where(a => a.isAsteroid)
+ .Select(a => (a.x, a.y))
+ .ToHashSet();
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ foreach (var asteroid in asteroids)
+ {
+ var canSee = asteroids
+ .Except(new[] { asteroid })
+ .Select(a => (x: a.x - asteroid.x, y: a.y - asteroid.y))
+ .GroupBy(a => Math.Atan2(a.y, a.x))
+ .Count();
+
+ if (canSee > bestCanSee)
+ {
+ best = asteroid;
+ bestCanSee = canSee;
+ }
+ }
+
+ return $"{bestCanSee}";
+ }
+
+ public override string Part2()
+ {
+ static IEnumerable<(int x, int y, double angle, double dist)> GetValue(
+ Queue<(int x, int y, double angle, double dist)> q)
+ {
+ if (q.Count > 0) yield return q.Dequeue();
+ }
+
+ return asteroids
+ .Where(a => a != best)
+ .Select(a =>
+ {
+ var xDist = a.x - best.x;
+ var yDist = a.y - best.y;
+ var angle = Math.Atan2(xDist, yDist);
+ return (a.x, a.y, angle, dist: Math.Sqrt(xDist * xDist + yDist * yDist));
+ })
+ .ToLookup(a => a.angle)
+ .OrderByDescending(a => a.Key)
+ .Select(a => new Queue<(int x, int y, double angle, double dist)>(a.OrderBy(b => b.dist)))
+ .Repeat()
+ .SelectMany(GetValue)
+ .Skip(199)
+ .Take(1)
+ .Select(a => a.x * 100 + a.y)
+ .Single()
+ .ToString();
+ }
+}
diff --git a/aoc2019/Day11.cs b/aoc2019/Day11.cs
index 2a299cb..fe86a4c 100644
--- a/aoc2019/Day11.cs
+++ b/aoc2019/Day11.cs
@@ -1,111 +1,106 @@
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day11 : Day
{
- public sealed class Day11 : Day
+ private readonly IntCodeVM vm;
+ private Direction heading;
+ private long x, y;
+
+ public Day11() : base(11, "Space Police")
{
- private readonly IntCodeVM vm;
- private Direction heading;
- private long x, y;
-
- public Day11() : base(11, "Space Police")
- {
- vm = new IntCodeVM(Input.First());
- }
-
- private void Move()
- {
- switch (heading)
- {
- case Direction.Up:
- y++;
- break;
- case Direction.Down:
- y--;
- break;
- case Direction.Left:
- x--;
- break;
- case Direction.Right:
- x++;
- break;
- }
-
- ;
- }
-
- private void Turn(long direction)
- {
- switch (heading)
- {
- case Direction.Up:
- heading = direction == 0 ? Direction.Left : Direction.Right;
- break;
- case Direction.Down:
- heading = direction == 0 ? Direction.Right : Direction.Left;
- break;
- case Direction.Left:
- heading = direction == 0 ? Direction.Down : Direction.Up;
- break;
- case Direction.Right:
- heading = direction == 0 ? Direction.Up : Direction.Down;
- break;
- }
-
- Move();
- }
-
- private Dictionary<(long x, long y), long> PaintShip(int initialVal)
- {
- var map = new Dictionary<(long, long), long>();
- vm.Reset();
- heading = Direction.Up;
- x = 0;
- y = 0;
- map[(x, y)] = initialVal;
-
- var haltType = IntCodeVM.HaltType.Waiting;
- while (haltType == IntCodeVM.HaltType.Waiting)
- {
- haltType = vm.Run(map.GetValueOrDefault((x, y)));
- map[(x, y)] = vm.Result;
- Turn(vm.Result);
- }
-
- return map;
- }
-
- public override string Part1()
- {
- return $"{PaintShip(0).Count}";
- }
-
- public override string Part2()
- {
- var map = PaintShip(1);
- var minX = (int) map.Keys.Select(i => i.x).Min();
- var maxX = (int) map.Keys.Select(i => i.x).Max();
- var minY = (int) map.Keys.Select(i => i.y).Min();
- var maxY = (int) map.Keys.Select(i => i.y).Max();
-
- return "\n" + Enumerable.Range(minY, maxY - minY + 1)
- .Select(j =>
- Enumerable.Range(minX, maxX - minX + 1)
- .Select(i => map.GetValueOrDefault((x: i, y: j)) == 0 ? ' ' : '#')
- .ToDelimitedString()
- )
- .Reverse()
- .ToDelimitedString("\n");
- }
-
- private enum Direction
- {
- Up,
- Down,
- Left,
- Right
- }
+ vm = new IntCodeVM(Input.First());
}
-}
\ No newline at end of file
+
+ private void Move()
+ {
+ switch (heading)
+ {
+ case Direction.Up:
+ y++;
+ break;
+ case Direction.Down:
+ y--;
+ break;
+ case Direction.Left:
+ x--;
+ break;
+ case Direction.Right:
+ x++;
+ break;
+ }
+
+ ;
+ }
+
+ private void Turn(long direction)
+ {
+ switch (heading)
+ {
+ case Direction.Up:
+ heading = direction == 0 ? Direction.Left : Direction.Right;
+ break;
+ case Direction.Down:
+ heading = direction == 0 ? Direction.Right : Direction.Left;
+ break;
+ case Direction.Left:
+ heading = direction == 0 ? Direction.Down : Direction.Up;
+ break;
+ case Direction.Right:
+ heading = direction == 0 ? Direction.Up : Direction.Down;
+ break;
+ }
+
+ Move();
+ }
+
+ private Dictionary<(long x, long y), long> PaintShip(int initialVal)
+ {
+ var map = new Dictionary<(long, long), long>();
+ vm.Reset();
+ heading = Direction.Up;
+ x = 0;
+ y = 0;
+ map[(x, y)] = initialVal;
+
+ var haltType = IntCodeVM.HaltType.Waiting;
+ while (haltType == IntCodeVM.HaltType.Waiting)
+ {
+ haltType = vm.Run(map.GetValueOrDefault((x, y)));
+ map[(x, y)] = vm.Result;
+ Turn(vm.Result);
+ }
+
+ return map;
+ }
+
+ public override string Part1()
+ {
+ return $"{PaintShip(0).Count}";
+ }
+
+ public override string Part2()
+ {
+ var map = PaintShip(1);
+ var minX = (int)map.Keys.Select(i => i.x).Min();
+ var maxX = (int)map.Keys.Select(i => i.x).Max();
+ var minY = (int)map.Keys.Select(i => i.y).Min();
+ var maxY = (int)map.Keys.Select(i => i.y).Max();
+
+ return "\n" + Enumerable.Range(minY, maxY - minY + 1)
+ .Select(j =>
+ Enumerable.Range(minX, maxX - minX + 1)
+ .Select(i => map.GetValueOrDefault((x: i, y: j)) == 0 ? ' ' : '#')
+ .ToDelimitedString()
+ )
+ .Reverse()
+ .ToDelimitedString("\n");
+ }
+
+ private enum Direction
+ {
+ Up,
+ Down,
+ Left,
+ Right
+ }
+}
diff --git a/aoc2019/Day12.cs b/aoc2019/Day12.cs
index 04e215e..79b6a11 100644
--- a/aoc2019/Day12.cs
+++ b/aoc2019/Day12.cs
@@ -1,127 +1,123 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day12 : Day
{
- public sealed class Day12 : Day
+ private readonly List moons;
+ private int step;
+
+ public Day12() : base(12, "The N-Body Problem")
{
- private readonly List moons;
- private int step;
+ moons = Input
+ .Select(moon =>
+ moon
+ .TrimStart('<')
+ .TrimEnd('>')
+ .Split(",")
+ .Select(val => int.Parse(val.Split("=").Last()))
+ )
+ .Select(moon => new Position(moon.ToList()))
+ .ToList();
- public Day12() : base(12, "The N-Body Problem")
+ foreach (var moon in moons)
+ moon.SetSiblings(moons);
+ }
+
+ 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();
+
+ step++;
+ }
+
+ public override string Part1()
+ {
+ while (step < 1000)
+ Step();
+
+ return $"{moons.Sum(p => p.TotalEnergy)}";
+ }
+
+ public override string Part2()
+ {
+ int cycleX = 0, cycleY = 0, cycleZ = 0;
+
+ while (cycleX == 0 || cycleY == 0 || cycleZ == 0)
{
- 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);
+ Step();
+ if (cycleX == 0 && moons.All(m => m.dx == 0)) cycleX = step * 2;
+ if (cycleY == 0 && moons.All(m => m.dy == 0)) cycleY = step * 2;
+ if (cycleZ == 0 && moons.All(m => m.dz == 0)) cycleZ = step * 2;
}
- public static long LCM(long a, long b)
+ return $"{LCM(cycleX, LCM(cycleY, cycleZ))}";
+ }
+
+ public class Position
+ {
+ public int dx, dy, dz;
+ private List siblings;
+ public int x, y, z;
+
+ public Position(IList moon)
{
- return a * b / GCD(a, b);
+ x = moon[0];
+ y = moon[1];
+ z = moon[2];
+ dx = 0;
+ dy = 0;
+ dz = 0;
+ siblings = new();
}
- public static long GCD(long a, long b)
+ 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 void SetSiblings(List positions)
{
- if (b == 0) return a;
- return GCD(b, a % b);
+ siblings = positions.Where(p => p != this).ToList();
}
- private void Step()
+ public override string ToString()
{
- foreach (var moon in moons)
- moon.Gravitate();
-
- foreach (var moon in moons)
- moon.Move();
-
- step++;
+ return $"pos= vel=";
}
- public override string Part1()
+ internal void Gravitate()
{
- while (step < 1000)
- Step();
-
- return $"{moons.Sum(p => p.TotalEnergy)}";
+ 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;
+ }
}
- public override string Part2()
+ internal void Move()
{
- int cycleX = 0, cycleY = 0, cycleZ = 0;
-
- while (cycleX == 0 || cycleY == 0 || cycleZ == 0)
- {
- Step();
- if (cycleX == 0 && moons.All(m => m.dx == 0)) cycleX = step * 2;
- if (cycleY == 0 && moons.All(m => m.dy == 0)) cycleY = step * 2;
- if (cycleZ == 0 && moons.All(m => m.dz == 0)) cycleZ = step * 2;
- }
-
- return $"{LCM(cycleX, LCM(cycleY, cycleZ))}";
- }
-
- public class Position
- {
- public int dx, dy, dz;
- private List siblings;
- public int x, y, z;
-
- public Position(IList moon)
- {
- x = moon[0];
- y = moon[1];
- z = moon[2];
- dx = 0;
- dy = 0;
- dz = 0;
- }
-
- 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 void SetSiblings(List positions)
- {
- siblings = positions.Where(p => p != this).ToList();
- }
-
- public override string ToString()
- {
- return $"pos= vel=";
- }
-
- 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;
- }
+ x += dx;
+ y += dy;
+ z += dz;
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day13.cs b/aoc2019/Day13.cs
index 4d919e7..11af0a3 100644
--- a/aoc2019/Day13.cs
+++ b/aoc2019/Day13.cs
@@ -1,87 +1,81 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day13 : Day
{
- public sealed class Day13 : Day
+ private readonly Dictionary<(int x, int y), int> board;
+
+ private readonly IntCodeVM vm;
+
+ public Day13() : base(13, "Care Package")
{
- private readonly Dictionary<(int x, int y), int> board;
+ vm = new IntCodeVM(Input.First());
+ board = new Dictionary<(int, int), int>();
+ }
- private readonly IntCodeVM vm;
+ private void UpdateTiles(IEnumerable queue)
+ {
+ var input = queue.Select(i => (int)i).ToList();
- public Day13() : base(13, "Care Package")
+ for (var i = 0; i < input.Count - 2; i += 3)
{
- vm = new IntCodeVM(Input.First());
- board = new Dictionary<(int, int), int>();
- }
+ var x = input[i];
+ var y = input[i + 1];
+ var val = input[i + 2];
- private void UpdateTiles(IEnumerable queue)
- {
- var input = queue.Select(i => (int) i).ToList();
-
- for (var i = 0; i < input.Count - 2; i += 3)
- {
- var x = input[i];
- var y = input[i + 1];
- var val = input[i + 2];
-
- if (board.ContainsKey((x, y)))
- board[(x, y)] = val;
- else
- board.Add((x, y), val);
- }
- }
-
- private void PrintBoard()
- {
- foreach (var ((x, y), value) in board)
- {
- if (x < 0 || y < 0) continue;
- Console.SetCursorPosition(x, y);
- Console.Write(value switch
- {
- 0 => " ",
- 1 => "|",
- 2 => "B",
- 3 => "_",
- 4 => ".",
- _ => value
- });
- }
- }
-
- public override string Part1()
- {
- vm.Reset();
- vm.Run();
- return $"{vm.output.Where((v, i) => (i + 1) % 3 == 0 && v == 2).Count()}";
- }
-
- public override string Part2()
- {
- vm.Reset();
- vm.memory[0] = 2;
- var printBoard = false;
- var gameTicks = 0;
- if (printBoard) Console.Clear();
-
- var haltType = IntCodeVM.HaltType.Waiting;
- while (haltType == IntCodeVM.HaltType.Waiting)
- {
- haltType = vm.Run();
- UpdateTiles(vm.output);
-
- var (ball, _) = board.First(t => t.Value == 4).Key;
- var (paddle, _) = board.First(t => t.Value == 3).Key;
- vm.AddInput(ball > paddle ? 1 : ball < paddle ? -1 : 0);
-
- gameTicks++;
- if (printBoard) PrintBoard();
- }
-
- return $"after {gameTicks} moves, the score is: {board[(-1, 0)]}";
+ if (board.ContainsKey((x, y)))
+ board[(x, y)] = val;
+ else
+ board.Add((x, y), val);
}
}
-}
\ No newline at end of file
+
+ private void PrintBoard()
+ {
+ foreach (var ((x, y), value) in board)
+ {
+ if (x < 0 || y < 0) continue;
+ Console.SetCursorPosition(x, y);
+ Console.Write(value switch
+ {
+ 0 => " ",
+ 1 => "|",
+ 2 => "B",
+ 3 => "_",
+ 4 => ".",
+ _ => value
+ });
+ }
+ }
+
+ public override string Part1()
+ {
+ vm.Reset();
+ vm.Run();
+ return $"{vm.output.Where((v, i) => (i + 1) % 3 == 0 && v == 2).Count()}";
+ }
+
+ public override string Part2()
+ {
+ vm.Reset();
+ vm.memory[0] = 2;
+ var printBoard = false;
+ var gameTicks = 0;
+ if (printBoard) Console.Clear();
+
+ var haltType = IntCodeVM.HaltType.Waiting;
+ while (haltType == IntCodeVM.HaltType.Waiting)
+ {
+ haltType = vm.Run();
+ UpdateTiles(vm.output);
+
+ var (ball, _) = board.First(t => t.Value == 4).Key;
+ var (paddle, _) = board.First(t => t.Value == 3).Key;
+ vm.AddInput(ball > paddle ? 1 : ball < paddle ? -1 : 0);
+
+ gameTicks++;
+ if (printBoard) PrintBoard();
+ }
+
+ return $"after {gameTicks} moves, the score is: {board[(-1, 0)]}";
+ }
+}
diff --git a/aoc2019/Day14.cs b/aoc2019/Day14.cs
index af7af42..9a34702 100644
--- a/aoc2019/Day14.cs
+++ b/aoc2019/Day14.cs
@@ -1,110 +1,107 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day14 : Day
{
- public sealed class Day14 : Day
+ private readonly Dictionary reactions;
+
+ private Dictionary available;
+
+ public Day14() : base(14, "Space Stoichiometry")
{
- private readonly Dictionary reactions;
+ reactions = Input
+ .Select(Reaction.Parse)
+ .ToDictionary(r => r.product.Name);
+
+ available = new();
+ }
- private Dictionary available;
+ private bool Consume(string chem, long quantity)
+ {
+ if (quantity <= 0)
+ throw new ArgumentOutOfRangeException(nameof(quantity));
- public Day14() : base(14, "Space Stoichiometry")
- {
- reactions = Input
- .Select(Reaction.Parse)
- .ToDictionary(r => r.product.Name);
- }
+ if (!available.ContainsKey(chem))
+ available[chem] = 0;
- private bool Consume(string chem, long quantity)
- {
- if (quantity <= 0)
- throw new ArgumentOutOfRangeException(nameof(quantity));
+ if (available[chem] < quantity && !Produce(chem, quantity - available[chem]))
+ return false;
- if (!available.ContainsKey(chem))
- available[chem] = 0;
+ available[chem] -= quantity;
+ return true;
+ }
- if (available[chem] < quantity && !Produce(chem, quantity - available[chem]))
+ 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] -= quantity;
- return true;
+ available[chem] = available.GetValueOrDefault(chem) + reactionCount * reaction.product.Quantity;
+ return true;
+ }
+
+ public override string Part1()
+ {
+ available = new Dictionary { { "ORE", long.MaxValue } };
+ Consume("FUEL", 1);
+ return $"{long.MaxValue - available["ORE"]}";
+ }
+
+ public override string Part2()
+ {
+ const long capacity = 1_000_000_000_000;
+ available = new Dictionary { { "ORE", capacity } };
+ Consume("FUEL", 1);
+
+ var oreConsumed = capacity - available["ORE"];
+ while (Produce("FUEL", Math.Max(1, available["ORE"] / oreConsumed)))
+ {
}
- private bool Produce(string chem, long quantity)
+ return $"{available["FUEL"] + 1}";
+ }
+
+ private struct Component
+ {
+ public string Name { get; set; }
+ public int Quantity { get; set; }
+ }
+
+ private class Reaction
+ {
+ public readonly Component product;
+ public readonly Component[] reactants;
+
+ private Reaction(Component[] reactants, Component product)
{
- 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;
+ this.reactants = reactants;
+ this.product = product;
}
- public override string Part1()
+ public static Reaction Parse(string s)
{
- available = new Dictionary {{"ORE", long.MaxValue}};
- Consume("FUEL", 1);
- return $"{long.MaxValue - available["ORE"]}";
- }
+ var ss = s.Split(new[] { ", ", " => " }, StringSplitOptions.None);
- public override string Part2()
- {
- const long capacity = 1_000_000_000_000;
- available = new Dictionary {{"ORE", capacity}};
- Consume("FUEL", 1);
+ return new Reaction(
+ ss.Take(ss.Length - 1).Select(ParseComponent).ToArray(),
+ ParseComponent(ss[^1])
+ );
- var oreConsumed = capacity - available["ORE"];
- while (Produce("FUEL", Math.Max(1, available["ORE"] / oreConsumed)))
+ static Component ParseComponent(string s)
{
- }
-
- return $"{available["FUEL"] + 1}";
- }
-
- private struct Component
- {
- public string Name { get; set; }
- public int Quantity { get; set; }
- }
-
- private class Reaction
- {
- public readonly Component product;
- public readonly Component[] reactants;
-
- private Reaction(Component[] reactants, Component product)
- {
- this.reactants = reactants;
- this.product = product;
- }
-
- public static Reaction Parse(string s)
- {
- var ss = s.Split(new[] {", ", " => "}, StringSplitOptions.None);
-
- return new Reaction(
- ss.Take(ss.Length - 1).Select(ParseComponent).ToArray(),
- ParseComponent(ss[^1])
- );
-
- static Component ParseComponent(string s)
+ var spl = s.Split(' ', 2);
+ return new Component
{
- var spl = s.Split(' ', 2);
- return new Component
- {
- Quantity = int.Parse(spl[0]),
- Name = spl[1]
- };
- }
+ Quantity = int.Parse(spl[0]),
+ Name = spl[1]
+ };
}
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day15.cs b/aoc2019/Day15.cs
index 59d720c..046f52f 100644
--- a/aoc2019/Day15.cs
+++ b/aoc2019/Day15.cs
@@ -1,224 +1,206 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day15 : Day
{
- public sealed class Day15 : Day
+ private readonly bool verbose = false;
+ private readonly IntCodeVM vm;
+
+ public Day15() : base(15, "Oxygen System")
{
- private readonly bool verbose = false;
- private readonly IntCodeVM vm;
+ vm = new IntCodeVM(Input.First());
+ }
- public Day15() : base(15, "Oxygen System")
+ public override string Part1()
+ {
+ vm.Reset();
+ var currentLocation = new Location(0, 0);
+ var halt = IntCodeVM.HaltType.Waiting;
+ while (halt == IntCodeVM.HaltType.Waiting)
{
- vm = new IntCodeVM(Input.First());
- }
-
- public override string Part1()
- {
- vm.Reset();
- var currentLocation = new Location(0, 0);
- var halt = IntCodeVM.HaltType.Waiting;
- while (halt == IntCodeVM.HaltType.Waiting)
+ var direction = currentLocation!.NextDirection();
+ if (direction <= 4)
{
- var direction = currentLocation.NextDirection();
- if (direction <= 4)
+ var (x, y) = currentLocation.Neighbor(direction);
+ if (Location.GetLocation(x, y) == null)
{
- var (x, y) = currentLocation.Neighbor(direction);
- if (Location.GetLocation(x, y) == null)
+ halt = vm.Run(direction);
+ currentLocation = vm.Result switch
{
- halt = vm.Run(direction);
- switch (vm.Result)
- {
- case Location.Wall:
- new Location(x, y, Location.Opposites[direction], Location.Wall);
- break;
- case Location.Empty:
- currentLocation = new Location(x, y, Location.Opposites[direction]);
- break;
- case Location.System:
- currentLocation = new Location(x, y, Location.Opposites[direction], Location.System);
- break;
- default:
- throw new Exception($"Unknown IntCodeVM response: {vm.Result}");
- }
- }
+ Location.Wall => new Location(x, y, Location.Opposites[direction], Location.Wall),
+ Location.Empty => new Location(x, y, Location.Opposites[direction]),
+ Location.System => new Location(x, y, Location.Opposites[direction], Location.System),
+ _ => throw new Exception($"Unknown IntCodeVM response: {vm.Result}"),
+ };
+ }
+ }
+ else
+ {
+ direction = currentLocation.PreviousDirection;
+ if (direction > 0)
+ {
+ halt = vm.Run(direction);
+ currentLocation = vm.Result switch
+ {
+ Location.Empty or Location.System => Location.GetLocation(currentLocation.Neighbor(direction)),
+ _ => throw new Exception($"Unknown or unexpected response for previous room: {vm.Result}"),
+ };
}
else
{
- direction = currentLocation.PreviousDirection;
- if (direction > 0)
+ if (verbose)
{
- halt = vm.Run(direction);
- switch (vm.Result)
+ // find extents of canvas
+ int xMin, xMax, yMin, yMax;
+ xMin = yMin = int.MaxValue;
+ xMax = yMax = int.MinValue;
+ foreach (var (x, y) in Location.AllLocations.Keys)
{
- case Location.Empty:
- case Location.System:
- currentLocation = Location.GetLocation(currentLocation.Neighbor(direction));
- break;
- default:
- throw new Exception($"Unknown or unexpected response for previous room: {vm.Result}");
+ if (x < xMin) xMin = x;
+ if (x > xMax) xMax = x;
+ if (y < yMin) yMin = y;
+ if (y > yMax) yMax = y;
+ }
+
+ Console.WriteLine($"Canvas extends from ({xMin}, {yMin}) to ({xMax}, {yMax})");
+
+ // print board
+ for (var y = yMin; y <= yMax; y++)
+ {
+ var line = "";
+ for (var x = xMin; x <= xMax; x++)
+ if (Location.AllLocations.ContainsKey((x, y)))
+ line += Location.AllLocations[(x, y)].Image();
+ else
+ line += "@";
+
+ Console.WriteLine(line);
}
}
- else
+
+ currentLocation = Location.OxygenLocation;
+ var distance = 0;
+ while (currentLocation?.PreviousDirection != 0)
{
- if (verbose)
- {
- // find extents of canvas
- int xMin, xMax, yMin, yMax;
- xMin = yMin = int.MaxValue;
- xMax = yMax = int.MinValue;
- foreach (var (x, y) in Location.AllLocations.Keys)
- {
- if (x < xMin) xMin = x;
- if (x > xMax) xMax = x;
- if (y < yMin) yMin = y;
- if (y > yMax) yMax = y;
- }
-
- Console.WriteLine($"Canvas extends from ({xMin}, {yMin}) to ({xMax}, {yMax})");
-
- // print board
- for (var y = yMin; y <= yMax; y++)
- {
- var line = "";
- for (var x = xMin; x <= xMax; x++)
- if (Location.AllLocations.ContainsKey((x, y)))
- line += Location.AllLocations[(x, y)].Image();
- else
- line += "@";
-
- Console.WriteLine(line);
- }
- }
-
- currentLocation = Location.OxygenLocation;
- var distance = 0;
- while (currentLocation.PreviousDirection != 0)
- {
- distance++;
- currentLocation = Location.GetLocation(currentLocation.PreviousLocation());
- }
-
- return $"{distance}";
+ distance++;
+ currentLocation = Location.GetLocation(currentLocation!.PreviousLocation());
}
+
+ return $"{distance}";
}
}
-
- return "";
}
- public override string Part2()
- {
- var changed = true;
- while (changed)
- {
- changed = false;
- foreach (var location in Location.AllLocations.Values)
- changed = location.UpdateDistanceToOxygenSystem() || changed;
- }
+ return "";
+ }
- return Location.AllLocations.Values
- .Where(l => !l.IsWall)
- .Max(l => l.DistanceToOxygenSystem)
- .ToString();
+ public override string Part2()
+ {
+ var changed = true;
+ while (changed)
+ {
+ changed = false;
+ foreach (var location in Location.AllLocations.Values)
+ changed = location.UpdateDistanceToOxygenSystem() || changed;
}
- private class Location
+ return Location.AllLocations.Values
+ .Where(l => !l.IsWall)
+ .Max(l => l.DistanceToOxygenSystem)
+ .ToString();
+ }
+
+ private class Location
+ {
+ public const int Wall = 0;
+ public const int Empty = 1;
+ public const int System = 2;
+
+ private static readonly int[] Dx = { 0, 0, 0, 1, -1 };
+ private static readonly int[] Dy = { 0, 1, -1, 0, 0 };
+ public static readonly int[] Opposites = { 0, 2, 1, 4, 3 };
+
+ public static readonly Dictionary<(int x, int y), Location> AllLocations = new();
+
+ private readonly int currentType;
+ public int DistanceToOxygenSystem = int.MaxValue - 1;
+
+ private int searchDirection = 1;
+
+ public Location(int x, int y, int prev = 0, int type = Empty)
{
- public const int Wall = 0;
- public const int Empty = 1;
- public const int System = 2;
+ PreviousDirection = prev;
+ currentType = type;
+ X = x;
+ Y = y;
- private static readonly int[] Dx = {0, 0, 0, 1, -1};
- private static readonly int[] Dy = {0, 1, -1, 0, 0};
- public static readonly int[] Opposites = {0, 2, 1, 4, 3};
-
- public static readonly Dictionary<(int x, int y), Location>
- AllLocations = new Dictionary<(int x, int y), Location>();
-
- private readonly int currentType;
- public int DistanceToOxygenSystem = int.MaxValue - 1;
-
- private int searchDirection = 1;
-
- public Location(int x, int y, int prev = 0, int type = Empty)
+ if (type == System)
{
- PreviousDirection = prev;
- currentType = type;
- X = x;
- Y = y;
+ OxygenLocation = this;
+ DistanceToOxygenSystem = 0;
+ // Console.WriteLine($"Found Oxygen System at ({x}, {y})");
+ }
- if (type == System)
+ AllLocations.Add((x, y), this);
+ }
+
+ public static Location? OxygenLocation { get; private set; }
+ public int PreviousDirection { get; }
+ private int X { get; }
+ private int Y { get; }
+
+ public bool IsWall => currentType == Wall;
+
+ public string Image()
+ {
+ return currentType switch
+ {
+ Wall => "\u2587",
+ Empty => X == 0 && Y == 0 ? "S" : " ",
+ System => "O",
+ _ => "?"
+ };
+ }
+
+ public bool UpdateDistanceToOxygenSystem()
+ {
+ if (currentType != Empty) return false;
+
+ foreach (var direction in Enumerable.Range(1, 4))
+ {
+ var distance = GetLocation(Neighbor(direction))?.DistanceToOxygenSystem ?? int.MaxValue;
+ if (distance + 1 < DistanceToOxygenSystem)
{
- OxygenLocation = this;
- DistanceToOxygenSystem = 0;
- // Console.WriteLine($"Found Oxygen System at ({x}, {y})");
+ DistanceToOxygenSystem = distance + 1;
+ return true;
}
-
- AllLocations.Add((x, y), this);
}
- public static Location OxygenLocation { get; private set; }
- public int PreviousDirection { get; }
- private int X { get; }
- private int Y { get; }
+ return false;
+ }
- public bool IsWall => currentType == Wall;
+ public (int, int) Neighbor(int direction)
+ {
+ return (X + Dx[direction], Y + Dy[direction]);
+ }
- public string Image()
- {
- return currentType switch
- {
- Wall => "\u2587",
- Empty => X == 0 && Y == 0 ? "S" : " ",
- System => "O",
- _ => "?"
- };
- }
+ public (int, int) PreviousLocation()
+ {
+ return Neighbor(PreviousDirection);
+ }
- public bool UpdateDistanceToOxygenSystem()
- {
- if (currentType != Empty) return false;
+ public int NextDirection()
+ {
+ return searchDirection++;
+ }
- foreach (var direction in Enumerable.Range(1, 4))
- {
- var distance = GetLocation(Neighbor(direction))?.DistanceToOxygenSystem ?? int.MaxValue;
- if (distance + 1 < DistanceToOxygenSystem)
- {
- DistanceToOxygenSystem = distance + 1;
- return true;
- }
- }
+ public static Location? GetLocation(int x, int y)
+ {
+ return AllLocations.ContainsKey((x, y)) ? AllLocations[(x, y)] : null;
+ }
- return false;
- }
-
- public (int, int) Neighbor(int direction)
- {
- return (X + Dx[direction], Y + Dy[direction]);
- }
-
- public (int, int) PreviousLocation()
- {
- return Neighbor(PreviousDirection);
- }
-
- public int NextDirection()
- {
- return searchDirection++;
- }
-
- public static Location GetLocation(int x, int y)
- {
- return AllLocations.ContainsKey((x, y)) ? AllLocations[(x, y)] : null;
- }
-
- public static Location GetLocation((int x, int y) coords)
- {
- return GetLocation(coords.x, coords.y);
- }
+ public static Location? GetLocation((int x, int y) coords)
+ {
+ return GetLocation(coords.x, coords.y);
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day16.cs b/aoc2019/Day16.cs
index 310363a..1c5481e 100644
--- a/aoc2019/Day16.cs
+++ b/aoc2019/Day16.cs
@@ -1,64 +1,58 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day16 : Day
{
- public sealed class Day16 : Day
+ private static readonly int[] BasePattern = { 0, 1, 0, -1 };
+ private readonly int[] initialList;
+
+ public Day16() : base(16, "Flawed Frequency Transmission")
{
- private static readonly int[] BasePattern = {0, 1, 0, -1};
- private readonly int[] initialList;
-
- public Day16() : base(16, "Flawed Frequency Transmission")
- {
- initialList = Input.First().Select(c => int.Parse($"{c}")).ToArray();
- }
-
- public override string Part1()
- {
- const int phaseCount = 100;
- var signal0 = initialList.ToArray();
- var signal1 = new int[signal0.Length];
-
- for (var i = 0; i < phaseCount; i++)
- CalculateSignal(i % 2 == 0 ? signal0 : signal1, i % 2 == 0 ? signal1 : signal0);
-
- return new string(
- signal0.Take(8).Select(c => (char) (c + '0'))
- .ToArray());
- }
-
- public override string Part2()
- {
- const int phaseCount = 100;
- var messageOffset = initialList.Take(7).Aggregate((n, i) => n * 10 + i);
- var signal = initialList.Repeat(10_000).Skip(messageOffset).ToArray();
-
- for (var p = 0; p < phaseCount; p++)
- {
- signal[^1] %= 10;
- for (var i = signal.Length - 2; i >= 0; i--)
- signal[i] = (signal[i + 1] + signal[i]) % 10;
- }
-
- return new string(signal.Take(8).Select(c => (char) (c + '0')).ToArray());
- }
-
- private static void CalculateSignal(IReadOnlyList input, IList output)
- {
- for (var outputIndex = 0; outputIndex < output.Count; outputIndex++)
- output[outputIndex] =
- Math.Abs(PatternValues(outputIndex, input.Count).Select((pv, i) => pv * input[i] % 10).Sum()) % 10;
- }
-
- private static IEnumerable PatternValues(int index, int count)
- {
- return BasePattern
- .SelectMany(v => Enumerable.Repeat(v, index + 1))
- .Repeat(int.MaxValue)
- .Skip(1)
- .Take(count);
- }
+ initialList = Input.First().Select(c => int.Parse($"{c}")).ToArray();
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ const int phaseCount = 100;
+ var signal0 = initialList.ToArray();
+ var signal1 = new int[signal0.Length];
+
+ for (var i = 0; i < phaseCount; i++)
+ CalculateSignal(i % 2 == 0 ? signal0 : signal1, i % 2 == 0 ? signal1 : signal0);
+
+ return new string(
+ signal0.Take(8).Select(c => (char)(c + '0'))
+ .ToArray());
+ }
+
+ public override string Part2()
+ {
+ const int phaseCount = 100;
+ var messageOffset = initialList.Take(7).Aggregate((n, i) => n * 10 + i);
+ var signal = initialList.Repeat(10_000).Skip(messageOffset).ToArray();
+
+ for (var p = 0; p < phaseCount; p++)
+ {
+ signal[^1] %= 10;
+ for (var i = signal.Length - 2; i >= 0; i--)
+ signal[i] = (signal[i + 1] + signal[i]) % 10;
+ }
+
+ return new string(signal.Take(8).Select(c => (char)(c + '0')).ToArray());
+ }
+
+ private static void CalculateSignal(IReadOnlyList input, IList output)
+ {
+ for (var outputIndex = 0; outputIndex < output.Count; outputIndex++)
+ output[outputIndex] =
+ Math.Abs(PatternValues(outputIndex, input.Count).Select((pv, i) => pv * input[i] % 10).Sum()) % 10;
+ }
+
+ private static IEnumerable PatternValues(int index, int count)
+ {
+ return BasePattern
+ .SelectMany(v => Enumerable.Repeat(v, index + 1))
+ .Repeat(int.MaxValue)
+ .Skip(1)
+ .Take(count);
+ }
+}
diff --git a/aoc2019/Day17.cs b/aoc2019/Day17.cs
index 0a3b550..376a80f 100644
--- a/aoc2019/Day17.cs
+++ b/aoc2019/Day17.cs
@@ -1,32 +1,27 @@
-using System;
-using System.Linq;
-using System.Text;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day17 : Day
{
- public sealed class Day17 : Day
+ private readonly bool Verbose = false;
+ private readonly IntCodeVM vm;
+
+ public Day17() : base(17, "Set and Forget")
{
- private readonly bool Verbose = false;
- private readonly IntCodeVM vm;
+ vm = new IntCodeVM(Input.First());
+ }
- public Day17() : base(17, "Set and Forget")
- {
- vm = new IntCodeVM(Input.First());
- }
+ public override string Part1()
+ {
+ vm.Reset();
+ vm.Run();
+ var sb = new StringBuilder();
+ while (vm.output.Any())
+ sb.Append((char)vm.Result);
+ if (Verbose) Console.Write(sb);
+ var grid = sb.ToString().Trim().Split().Select(s => s.ToCharArray()).ToArray();
- public override string Part1()
- {
- vm.Reset();
- vm.Run();
- var sb = new StringBuilder();
- while (vm.output.Any())
- sb.Append((char) vm.Result);
- if (Verbose) Console.Write(sb);
- var grid = sb.ToString().Trim().Split().Select(s => s.ToCharArray()).ToArray();
-
- var sum = 0;
- for (var y = 1; y < grid.Length - 1; y++)
+ var sum = 0;
+ for (var y = 1; y < grid.Length - 1; y++)
for (var x = 1; x < grid[y].Length - 1; x++)
if (grid[y][x] == '#' &&
grid[y - 1][x] == '#' &&
@@ -35,19 +30,18 @@ namespace aoc2019
grid[y][x + 1] == '#')
sum += x * y;
- return $"{sum}";
- }
-
- public override string Part2()
- {
- //vm.Reset();
- //vm.memory[0] = 2;
- //var halt = IntCodeVM.HaltType.Waiting;
- //while (halt == IntCodeVM.HaltType.Waiting)
- //{
- // halt = vm.Run();
- //}
- return "";
- }
+ return $"{sum}";
}
-}
\ No newline at end of file
+
+ public override string Part2()
+ {
+ //vm.Reset();
+ //vm.memory[0] = 2;
+ //var halt = IntCodeVM.HaltType.Waiting;
+ //while (halt == IntCodeVM.HaltType.Waiting)
+ //{
+ // halt = vm.Run();
+ //}
+ return "";
+ }
+}
diff --git a/aoc2019/Day18.cs b/aoc2019/Day18.cs
new file mode 100644
index 0000000..0760cd7
--- /dev/null
+++ b/aoc2019/Day18.cs
@@ -0,0 +1,18 @@
+namespace aoc2019;
+
+public sealed class Day18 : Day
+{
+ public Day18() : base(18, "Many-Worlds Interpretation")
+ {
+ }
+
+ public override string Part1()
+ {
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Day19.cs b/aoc2019/Day19.cs
index fe6b435..2136bcb 100644
--- a/aoc2019/Day19.cs
+++ b/aoc2019/Day19.cs
@@ -1,22 +1,19 @@
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day19 : Day
{
- public sealed class Day19 : Day
+ private readonly long[,] grid;
+ private readonly IntCodeVM vm;
+
+ public Day19() : base(19, "Tractor Beam")
{
- private readonly long[,] grid;
- private readonly IntCodeVM vm;
+ vm = new IntCodeVM(Input.First());
+ grid = new long[50, 50];
+ }
- public Day19() : base(19, "Tractor Beam")
- {
- vm = new IntCodeVM(Input.First());
- grid = new long[50, 50];
- }
-
- public override string Part1()
- {
- for (var x = 0; x < 50; x++)
+ public override string Part1()
+ {
+ for (var x = 0; x < 50; x++)
for (var y = 0; y < 50; y++)
{
vm.Reset();
@@ -24,26 +21,25 @@ namespace aoc2019
grid[x, y] = vm.Result;
}
- return $"{grid.Cast().Sum()}";
- }
+ return $"{grid.Cast().Sum()}";
+ }
- public override string Part2()
+ public override string Part2()
+ {
+ for (int x = 101, y = 0; ; x++)
{
- for (int x = 101, y = 0;; x++)
+ while (true)
{
- while (true)
- {
- vm.Reset();
- vm.Run(x, y);
- if (vm.Result == 1) break;
- y++;
- }
-
vm.Reset();
- vm.Run(x - 99, y + 99);
- if (vm.Result == 1)
- return $"{(x - 99) * 1e4 + y}";
+ vm.Run(x, y);
+ if (vm.Result == 1) break;
+ y++;
}
+
+ vm.Reset();
+ vm.Run(x - 99, y + 99);
+ if (vm.Result == 1)
+ return $"{(x - 99) * 1e4 + y}";
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day20.cs b/aoc2019/Day20.cs
new file mode 100644
index 0000000..a8a521a
--- /dev/null
+++ b/aoc2019/Day20.cs
@@ -0,0 +1,18 @@
+namespace aoc2019;
+
+public sealed class Day20 : Day
+{
+ public Day20() : base(20, "Donut Maze")
+ {
+ }
+
+ public override string Part1()
+ {
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Day21.cs b/aoc2019/Day21.cs
index e2bc3fb..d81c114 100644
--- a/aoc2019/Day21.cs
+++ b/aoc2019/Day21.cs
@@ -1,27 +1,23 @@
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day21 : Day
{
- public sealed class Day21 : Day
+ private readonly IntCodeVM vm;
+
+ public Day21() : base(21, "Springdroid Adventure")
{
- private readonly IntCodeVM vm;
-
- public Day21() : base(21, "Springdroid Adventure")
- {
- vm = new IntCodeVM(Input.First());
- }
-
- public override string Part1()
- {
- vm.Reset();
- var halt = vm.Run();
- return "";
- }
-
- public override string Part2()
- {
- return "";
- }
+ vm = new IntCodeVM(Input.First());
}
-}
\ No newline at end of file
+
+ public override string Part1()
+ {
+ vm.Reset();
+ var halt = vm.Run();
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Day22.cs b/aoc2019/Day22.cs
new file mode 100644
index 0000000..eaa3488
--- /dev/null
+++ b/aoc2019/Day22.cs
@@ -0,0 +1,18 @@
+namespace aoc2019;
+
+public sealed class Day22 : Day
+{
+ public Day22() : base(22, "Slam Shuffle")
+ {
+ }
+
+ public override string Part1()
+ {
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Day23.cs b/aoc2019/Day23.cs
index 53c840c..29da6a7 100644
--- a/aoc2019/Day23.cs
+++ b/aoc2019/Day23.cs
@@ -1,90 +1,86 @@
-using System.Linq;
-using aoc2019.lib;
+namespace aoc2019;
-namespace aoc2019
+public sealed class Day23 : Day
{
- public sealed class Day23 : Day
+ public Day23() : base(23, "Category Six")
{
- public Day23() : base(23, "Category Six")
- {
- }
+ }
- public override string Part1()
- {
- var vms = Enumerable.Range(0, 50)
- .Select((s, i) =>
- {
- var vm = new IntCodeVM(Input.First());
- vm.Run(i);
- return vm;
- }).ToList();
+ public override string Part1()
+ {
+ var vms = Enumerable.Range(0, 50)
+ .Select((s, i) =>
+ {
+ var vm = new IntCodeVM(Input.First());
+ vm.Run(i);
+ return vm;
+ }).ToList();
- while (true)
- foreach (var vm in vms)
+ while (true)
+ foreach (var vm in vms)
+ {
+ while (vm.output.Count > 0)
{
- while (vm.output.Count > 0)
+ var destination = (int)vm.Result;
+ var x = vm.Result;
+ var y = vm.Result;
+
+ if (destination == 255) return $"{y}";
+
+ vms[destination].Run(x, y);
+ }
+
+ vm.Run(-1);
+ }
+ }
+
+ public override string Part2()
+ {
+ var vms = Enumerable.Range(0, 50)
+ .Select((s, i) =>
+ {
+ var vm = new IntCodeVM(Input.First());
+ vm.Run(i);
+ return vm;
+ }).ToList();
+
+ long natX = 0, natY = 0, lastYSent = -1;
+
+ while (true)
+ {
+ var numIdle = 0;
+ foreach (var vm in vms)
+ {
+ var isIdle = true;
+ while (vm.output.Count > 0)
+ {
+ var destination = (int)vm.Result;
+ var x = vm.Result;
+ var y = vm.Result;
+
+ if (destination == 255)
+ {
+ natX = x;
+ natY = y;
+ }
+ else
{
- var destination = (int) vm.Result;
- var x = vm.Result;
- var y = vm.Result;
-
- if (destination == 255) return $"{y}";
-
vms[destination].Run(x, y);
}
- vm.Run(-1);
+ isIdle = false;
}
- }
- public override string Part2()
- {
- var vms = Enumerable.Range(0, 50)
- .Select((s, i) =>
- {
- var vm = new IntCodeVM(Input.First());
- vm.Run(i);
- return vm;
- }).ToList();
+ vm.Run(-1);
+ if (isIdle) numIdle++;
+ }
- long natX = 0, natY = 0, lastYSent = -1;
-
- while (true)
+ if (numIdle == 50)
{
- var numIdle = 0;
- foreach (var vm in vms)
- {
- var isIdle = true;
- while (vm.output.Count > 0)
- {
- var destination = (int) vm.Result;
- var x = vm.Result;
- var y = vm.Result;
-
- if (destination == 255)
- {
- natX = x;
- natY = y;
- }
- else
- {
- vms[destination].Run(x, y);
- }
-
- isIdle = false;
- }
-
- vm.Run(-1);
- if (isIdle) numIdle++;
- }
-
- if (numIdle == 50)
- {
- if (natY == lastYSent) return $"{natY}";
- vms[0].Run(natX, natY);
- lastYSent = natY;
- }
+ if (natY == lastYSent) return $"{natY}";
+ vms[0].Run(natX, natY);
+ lastYSent = natY;
}
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/Day24.cs b/aoc2019/Day24.cs
new file mode 100644
index 0000000..fee2339
--- /dev/null
+++ b/aoc2019/Day24.cs
@@ -0,0 +1,18 @@
+namespace aoc2019;
+
+public sealed class Day24 : Day
+{
+ public Day24() : base(24, "Planet of Discord")
+ {
+ }
+
+ public override string Part1()
+ {
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Day25.cs b/aoc2019/Day25.cs
new file mode 100644
index 0000000..5d45cdc
--- /dev/null
+++ b/aoc2019/Day25.cs
@@ -0,0 +1,18 @@
+namespace aoc2019;
+
+public sealed class Day25 : Day
+{
+ public Day25() : base(25, "Cryostasis")
+ {
+ }
+
+ public override string Part1()
+ {
+ return "";
+ }
+
+ public override string Part2()
+ {
+ return "";
+ }
+}
diff --git a/aoc2019/Extensions.cs b/aoc2019/Extensions.cs
new file mode 100644
index 0000000..76588c2
--- /dev/null
+++ b/aoc2019/Extensions.cs
@@ -0,0 +1,45 @@
+using System.Diagnostics;
+
+namespace aoc2019;
+
+public static class Extensions
+{
+ public static IEnumerable> Permute(this IEnumerable list)
+ {
+ if (list.Count() == 1) return new[] { list };
+ return list.SelectMany(t => Permute(list.Where(x => !x!.Equals(t))), (v, p) => p.Prepend(v));
+ }
+
+ public static IEnumerable Chunk(this string str, int chunkSize)
+ {
+ for (var i = 0; i < str.Length; i += chunkSize)
+ yield return str.Substring(i, chunkSize);
+ }
+
+ public static string ToDelimitedString(this IEnumerable enumerable, string delimiter = "")
+ {
+ return string.Join(delimiter, enumerable);
+ }
+
+ public static IEnumerable Repeat(this IEnumerable sequence, int? count = null)
+ {
+ while (count == null || count-- > 0)
+ foreach (var item in sequence)
+ yield return item;
+ }
+
+ ///
+ /// increased accuracy for stopwatch based on frequency.
+ ///
+ /// blog
+ /// details here
+ ///
+ ///
+ ///
+ ///
+ public static double ScaleMilliseconds(this Stopwatch stopwatch)
+ {
+ return 1_000 * stopwatch.ElapsedTicks / (double)Stopwatch.Frequency;
+ }
+}
diff --git a/aoc2019/IntCodeVM.cs b/aoc2019/IntCodeVM.cs
new file mode 100644
index 0000000..d6f1214
--- /dev/null
+++ b/aoc2019/IntCodeVM.cs
@@ -0,0 +1,155 @@
+namespace aoc2019;
+
+public class IntCodeVM
+{
+ public enum HaltType
+ {
+ Terminate,
+ Waiting
+ }
+
+ private readonly long[] program;
+ private long i;
+ public Queue input, output;
+ public long[] memory;
+ private long relativeBase;
+
+ public IntCodeVM(string tape)
+ {
+ i = 0;
+ relativeBase = 0;
+ program = tape.Split(',').Select(long.Parse).ToArray();
+ memory = program;
+ input = new Queue();
+ output = new Queue();
+ }
+
+ public long Result => output.Dequeue();
+
+ public void Reset()
+ {
+ i = 0;
+ relativeBase = 0;
+ memory = program;
+ input.Clear();
+ output.Clear();
+ }
+
+ public void AddInput(params long[] values)
+ {
+ foreach (var v in values) AddInput(v);
+ }
+
+ public void AddInput(long value)
+ {
+ input.Enqueue(value);
+ }
+
+ private long MemGet(long addr)
+ {
+ return addr < memory.Length ? memory[addr] : 0;
+ }
+
+ private void MemSet(long addr, long value)
+ {
+ if (addr < 0) addr = 0;
+ if (addr >= memory.Length)
+ Array.Resize(ref memory, (int)addr + 1);
+ memory[addr] = value;
+ }
+
+ private long Mode(long idx)
+ {
+ var mode = MemGet(i) / 100;
+ for (var s = 1; s < idx; s++)
+ mode /= 10;
+ return mode % 10;
+ }
+
+ private long Get(long idx)
+ {
+ var param = MemGet(i + idx);
+ return Mode(idx) switch
+ {
+ 0 => MemGet(param),
+ 1 => param,
+ 2 => MemGet(relativeBase + param),
+ _ => throw new Exception("invalid parameter mode"),
+ };
+ }
+
+ private void Set(long idx, long val)
+ {
+ var param = MemGet(i + idx);
+ switch (Mode(idx))
+ {
+ case 0:
+ MemSet(param, val);
+ break;
+ case 1: throw new Exception("cannot set in immediate mode");
+ case 2:
+ MemSet(relativeBase + param, val);
+ break;
+ default: throw new Exception("invalid parameter mode");
+ }
+ }
+
+ public HaltType Run(params long[] additionalInput)
+ {
+ foreach (var s in additionalInput) AddInput(s);
+ return Run();
+ }
+
+ public HaltType Run()
+ {
+ while (i < memory.Length)
+ {
+ var op = MemGet(i) % 100;
+ switch (op)
+ {
+ case 1:
+ Set(3, Get(1) + Get(2));
+ i += 4;
+ break;
+ case 2:
+ Set(3, Get(1) * Get(2));
+ i += 4;
+ break;
+ case 3:
+ if (!input.Any())
+ return HaltType.Waiting;
+ Set(1, input.Dequeue());
+ i += 2;
+ break;
+ case 4:
+ output.Enqueue(Get(1));
+ i += 2;
+ break;
+ case 5:
+ i = Get(1) == 0 ? i + 3 : Get(2);
+ break;
+ case 6:
+ i = Get(1) != 0 ? i + 3 : Get(2);
+ break;
+ case 7:
+ Set(3, Get(1) < Get(2) ? 1 : 0);
+ i += 4;
+ break;
+ case 8:
+ Set(3, Get(1) == Get(2) ? 1 : 0);
+ i += 4;
+ break;
+ case 9:
+ relativeBase += Get(1);
+ i += 2;
+ break;
+ case 99:
+ return HaltType.Terminate;
+ default:
+ throw new Exception($"unknown op {op} at {i}");
+ }
+ }
+
+ return HaltType.Terminate;
+ }
+}
diff --git a/aoc2019/Program.cs b/aoc2019/Program.cs
index c523439..ca7eec7 100644
--- a/aoc2019/Program.cs
+++ b/aoc2019/Program.cs
@@ -1,32 +1,29 @@
-using System;
-using System.Linq;
-using System.Reflection;
+using System.Reflection;
-namespace aoc2019
+namespace aoc2019;
+
+internal static class Program
{
- internal static class Program
+ private static void Main(string[] args)
{
- private static void Main(string[] args)
+ var days =
+ Assembly.GetExecutingAssembly().GetTypes()
+ .Where(t => t.BaseType == typeof(Day))
+ .Select(t => Activator.CreateInstance(t) as Day)
+ .OrderBy(d => d?.DayNumber);
+
+ if (args.Length == 1 && int.TryParse(args[0], out var dayNum))
{
- var days =
- Assembly.GetExecutingAssembly().GetTypes()
- .Where(t => t.BaseType == typeof(Day))
- .Select(t => (Day) Activator.CreateInstance(t))
- .OrderBy(d => d.DayNumber);
+ var day = days.FirstOrDefault(d => d?.DayNumber == dayNum);
- if (args.Length == 1 && int.TryParse(args[0], out var dayNum))
- {
- var day = days.FirstOrDefault(d => d.DayNumber == dayNum);
-
- if (day != null)
- day.AllParts();
- else
- Console.WriteLine($"{dayNum} invalid or not yet implemented");
- }
+ if (day != null)
+ day.AllParts();
else
- {
- foreach (var d in days) d.AllParts();
- }
+ Console.WriteLine($"{dayNum} invalid or not yet implemented");
+ }
+ else
+ {
+ foreach (var d in days) d?.AllParts();
}
}
-}
\ No newline at end of file
+}
diff --git a/aoc2019/aoc2019.csproj b/aoc2019/aoc2019.csproj
index 494194f..fe5d9a6 100644
--- a/aoc2019/aoc2019.csproj
+++ b/aoc2019/aoc2019.csproj
@@ -2,7 +2,9 @@
Exe
- net5.0
+ net6.0
+ enable
+ enable
@@ -11,4 +13,11 @@
+
+
+
+
+
+
+
diff --git a/aoc2019/lib/Extensions.cs b/aoc2019/lib/Extensions.cs
deleted file mode 100644
index eb8c3cb..0000000
--- a/aoc2019/lib/Extensions.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-
-namespace aoc2019.lib
-{
- public static class Extensions
- {
- public static IEnumerable> Permute(this IEnumerable list)
- {
- if (list.Count() == 1) return new[] {list};
- return list.SelectMany(t => Permute(list.Where(x => !x.Equals(t))), (v, p) => p.Prepend(v));
- }
-
- public static IEnumerable Chunk(this string str, int chunkSize)
- {
- for (var i = 0; i < str.Length; i += chunkSize)
- yield return str.Substring(i, chunkSize);
- }
-
- public static string ToDelimitedString(this IEnumerable enumerable, string delimiter = "")
- {
- return string.Join(delimiter, enumerable);
- }
-
- public static IEnumerable Repeat(this IEnumerable sequence, int? count = null)
- {
- while (count == null || count-- > 0)
- foreach (var item in sequence)
- yield return item;
- }
-
- ///
- /// increased accuracy for stopwatch based on frequency.
- ///
- /// blog
- /// details here
- ///
- ///
- ///
- ///
- public static double ScaleMilliseconds(this Stopwatch stopwatch)
- {
- return 1_000 * stopwatch.ElapsedTicks / (double) Stopwatch.Frequency;
- }
- }
-}
\ No newline at end of file
diff --git a/aoc2019/lib/IntCodeVM.cs b/aoc2019/lib/IntCodeVM.cs
deleted file mode 100644
index 4fb196f..0000000
--- a/aoc2019/lib/IntCodeVM.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace aoc2019.lib
-{
- public class IntCodeVM
- {
- public enum HaltType
- {
- Terminate,
- Waiting
- }
-
- private readonly long[] program;
- private long i;
- public Queue input, output;
- public long[] memory;
- private long relativeBase;
-
- public IntCodeVM(string tape)
- {
- i = 0;
- relativeBase = 0;
- program = tape.Split(',').Select(long.Parse).ToArray();
- memory = program;
- input = new Queue();
- output = new Queue();
- }
-
- public long Result => output.Dequeue();
-
- public void Reset()
- {
- i = 0;
- relativeBase = 0;
- memory = program;
- input.Clear();
- output.Clear();
- }
-
- public void AddInput(params long[] values)
- {
- foreach (var v in values) AddInput(v);
- }
-
- public void AddInput(long value)
- {
- input.Enqueue(value);
- }
-
- private long MemGet(long addr)
- {
- return addr < memory.Length ? memory[addr] : 0;
- }
-
- private void MemSet(long addr, long value)
- {
- if (addr < 0) addr = 0;
- if (addr >= memory.Length)
- Array.Resize(ref memory, (int) addr + 1);
- memory[addr] = value;
- }
-
- private long Mode(long idx)
- {
- var mode = MemGet(i) / 100;
- for (var s = 1; s < idx; s++)
- mode /= 10;
- return mode % 10;
- }
-
- private long Get(long idx)
- {
- var param = MemGet(i + idx);
- switch (Mode(idx))
- {
- case 0: return MemGet(param);
- case 1: return param;
- case 2: return MemGet(relativeBase + param);
- default: throw new Exception("invalid parameter mode");
- }
- }
-
- private void Set(long idx, long val)
- {
- var param = MemGet(i + idx);
- switch (Mode(idx))
- {
- case 0:
- MemSet(param, val);
- break;
- case 1: throw new Exception("cannot set in immediate mode");
- case 2:
- MemSet(relativeBase + param, val);
- break;
- default: throw new Exception("invalid parameter mode");
- }
- }
-
- public HaltType Run(params long[] additionalInput)
- {
- foreach (var s in additionalInput) AddInput(s);
- return Run();
- }
-
- public HaltType Run()
- {
- while (i < memory.Length)
- {
- var op = MemGet(i) % 100;
- switch (op)
- {
- case 1:
- Set(3, Get(1) + Get(2));
- i += 4;
- break;
- case 2:
- Set(3, Get(1) * Get(2));
- i += 4;
- break;
- case 3:
- if (!input.Any())
- return HaltType.Waiting;
- Set(1, input.Dequeue());
- i += 2;
- break;
- case 4:
- output.Enqueue(Get(1));
- i += 2;
- break;
- case 5:
- i = Get(1) == 0 ? i + 3 : Get(2);
- break;
- case 6:
- i = Get(1) != 0 ? i + 3 : Get(2);
- break;
- case 7:
- Set(3, Get(1) < Get(2) ? 1 : 0);
- i += 4;
- break;
- case 8:
- Set(3, Get(1) == Get(2) ? 1 : 0);
- i += 4;
- break;
- case 9:
- relativeBase += Get(1);
- i += 2;
- break;
- case 99:
- return HaltType.Terminate;
- default:
- throw new Exception($"unknown op {op} at {i}");
- }
- }
-
- return HaltType.Terminate;
- }
- }
-}
\ No newline at end of file