refactor to two-digit day names and add puzzlename
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Ben Harris 2020-12-16 17:17:35 -05:00
parent c66d1d6b33
commit 837527d487
28 changed files with 84 additions and 95 deletions

32
Day.cs
View File

@ -2,32 +2,44 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using aoc2019.lib;
namespace aoc2019
{
public abstract class Day
{
public abstract int DayNumber { get; }
protected Day(int dayNumber, string puzzleName)
{
DayNumber = dayNumber;
PuzzleName = puzzleName;
}
public int DayNumber { get; }
public string PuzzleName { get; }
protected virtual IEnumerable<string> Input =>
File.ReadLines($"input/day{DayNumber}.in");
File.ReadLines(FileName);
public virtual void AllParts(bool verbose = false)
protected string FileName =>
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"input/day{DayNumber,2:00}.in");
public void AllParts(bool verbose = true)
{
Console.WriteLine($"Day {DayNumber}:");
var s = new Stopwatch();
s.Start();
Console.WriteLine($"Day {DayNumber,2}: {PuzzleName}");
var s = Stopwatch.StartNew();
var part1 = Part1();
s.Stop();
if (verbose) Console.WriteLine($"part 1 elapsed ticks: {s.ElapsedTicks}");
Console.WriteLine(part1);
Console.Write($"Part1: {part1,-15} ");
Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
s.Reset();
s.Start();
var part2 = Part2();
s.Stop();
if (verbose) Console.WriteLine($"part 2 elapsed ticks: {s.ElapsedTicks}");
Console.WriteLine(part2);
Console.Write($"Part2: {part2,-15} ");
Console.WriteLine(verbose ? $"{s.ScaleMilliseconds()}ms elapsed" : "");
Console.WriteLine();
}

View File

@ -3,17 +3,15 @@ using System.Linq;
namespace aoc2019
{
internal sealed class Day1 : Day
internal sealed class Day01 : Day
{
private readonly IEnumerable<int> masses;
public Day1()
public Day01() : base(1, "The Tyranny of the Rocket Equation")
{
masses = Input.Select(int.Parse);
}
public override int DayNumber => 1;
private static int FuelCost(int weight)
{
return weight / 3 - 2;

View File

@ -3,17 +3,15 @@ using System.Linq;
namespace aoc2019
{
internal sealed class Day2 : Day
internal sealed class Day02 : Day
{
private readonly IEnumerable<int> input;
public Day2()
public Day02() : base(2, "1202 Program Alarm")
{
input = Input.First().Split(',').Select(int.Parse);
}
public override int DayNumber => 2;
public int RunIntCode(int noun, int verb)
{
var v = input.ToList();

View File

@ -4,19 +4,17 @@ using System.Linq;
namespace aoc2019
{
internal sealed class Day3 : Day
internal sealed class Day03 : Day
{
private readonly IEnumerable<(int, int)> intersections;
private readonly List<Dictionary<(int, int), int>> wires;
public Day3()
public Day03() : base(3, "Crossed Wires")
{
wires = Input.Select(ParseWire).ToList();
intersections = wires[0].Keys.Intersect(wires[1].Keys);
}
public override int DayNumber => 3;
protected override string Part1()
{
return $"{intersections.Min(x => Math.Abs(x.Item1) + Math.Abs(x.Item2))}";

View File

@ -2,21 +2,19 @@
namespace aoc2019
{
internal sealed class Day4 : Day
internal sealed class Day04 : Day
{
private readonly int end;
private readonly int start;
public Day4()
public Day04() : base(4, "Secure Container")
{
var range = Input.First().Split('-').Select(int.Parse).ToList();
start = range[0];
end = range[1];
}
public override int DayNumber => 4;
private bool IsValid(int i)
{
var prev = 0;

View File

@ -3,19 +3,17 @@ using System.Linq;
namespace aoc2019
{
internal sealed class Day5 : Day
internal sealed class Day05 : Day
{
private readonly IEnumerable<int> tape;
private int output;
public Day5()
public Day05() : base(5, "Sunny with a Chance of Asteroids")
{
tape = Input.First().Split(',').Select(int.Parse);
}
public override int DayNumber => 5;
public void RunIntCode(List<int> v, int input)
{
var i = 0;

View File

@ -3,17 +3,15 @@ using System.Linq;
namespace aoc2019
{
internal sealed class Day6 : Day
internal sealed class Day06 : Day
{
private readonly Dictionary<string, string> input;
public Day6()
public Day06() : base(6, "Universal Orbit Map")
{
input = Input.ToDictionary(i => i.Split(')')[1], i => i.Split(')')[0]);
}
public override int DayNumber => 6;
private List<string> GetParents(string obj)
{
var res = new List<string>();

View File

@ -4,18 +4,15 @@ using aoc2019.lib;
namespace aoc2019
{
internal sealed class Day7 : Day
internal sealed class Day07 : Day
{
private readonly IntCodeVM[] Amplifiers = new IntCodeVM[5];
public Day7()
public Day07() : base(7, "Amplification Circuit")
{
for (var i = 0; i < 5; i++) Amplifiers[i] = new IntCodeVM(Input.First());
}
public override int DayNumber => 7;
protected override string Part1()
{
long i, largest = 0;

View File

@ -5,17 +5,15 @@ using aoc2019.lib;
namespace aoc2019
{
internal sealed class Day8 : Day
internal sealed class Day08 : Day
{
private readonly List<List<char>> photo;
public Day8()
public Day08() : base(8, "Space Image Format")
{
photo = Input.First().Chunk(25 * 6).Select(s => s.ToList()).ToList();
}
public override int DayNumber => 8;
protected override string Part1()
{
var l = photo.OrderBy(layer => layer.Count(pixel => pixel == '0')).First();

View File

@ -3,17 +3,15 @@ using aoc2019.lib;
namespace aoc2019
{
internal sealed class Day9 : Day
internal sealed class Day09 : Day
{
private readonly IntCodeVM vm;
public Day9()
public Day09() : base(9, "Sensor Boost")
{
vm = new IntCodeVM(Input.First());
}
public override int DayNumber => 9;
protected override string Part1()
{
vm.Reset();

View File

@ -7,11 +7,11 @@ namespace aoc2019
{
internal sealed class Day10 : Day
{
private readonly HashSet<(int x, int y)> asteroids = new HashSet<(int x, int y)>();
private readonly HashSet<(int x, int y)> asteroids;
private (int x, int y) best = (x: -1, y: -1);
private int bestcansee;
private int bestCanSee;
public Day10()
public Day10() : base(10, "Monitoring Station")
{
asteroids = Input
.Select((r, y) => r.Select((c, x) => (x, y, isAsteroid: c == '#')).ToArray())
@ -21,26 +21,24 @@ namespace aoc2019
.ToHashSet();
}
public override int DayNumber => 10;
protected override string Part1()
{
foreach (var asteroid in asteroids)
{
var cansee = 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)
if (canSee > bestCanSee)
{
best = asteroid;
bestcansee = cansee;
bestCanSee = canSee;
}
}
return $"{bestcansee}";
return $"{bestCanSee}";
}
protected override string Part2()
@ -55,10 +53,10 @@ namespace aoc2019
.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));
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)

View File

@ -11,13 +11,11 @@ namespace aoc2019
private Direction heading;
private long x, y;
public Day11()
public Day11() : base(11, "Space Police")
{
vm = new IntCodeVM(Input.First());
}
public override int DayNumber => 11;
private void Move()
{
switch (heading)

View File

@ -7,10 +7,9 @@ namespace aoc2019
internal sealed class Day12 : Day
{
private readonly List<Position> moons;
private readonly List<Position> startingPositions;
private int step;
public Day12()
public Day12() : base(12, "The N-Body Problem")
{
moons = Input
.Select(moon =>
@ -25,12 +24,8 @@ namespace aoc2019
foreach (var moon in moons)
moon.SetSiblings(moons);
startingPositions = moons;
}
public override int DayNumber => 12;
public static long LCM(long a, long b)
{
return a * b / GCD(a, b);

View File

@ -11,14 +11,12 @@ namespace aoc2019
private readonly IntCodeVM vm;
public Day13()
public Day13() : base(13, "Care Package")
{
vm = new IntCodeVM(Input.First());
board = new Dictionary<(int, int), int>();
}
public override int DayNumber => 13;
private void UpdateTiles(IEnumerable<long> queue)
{
var input = queue.Select(i => (int) i).ToList();
@ -65,9 +63,9 @@ namespace aoc2019
{
vm.Reset();
vm.memory[0] = 2;
var printboard = false;
var printBoard = false;
var gameTicks = 0;
if (printboard) Console.Clear();
if (printBoard) Console.Clear();
var haltType = IntCodeVM.HaltType.Waiting;
while (haltType == IntCodeVM.HaltType.Waiting)
@ -80,7 +78,7 @@ namespace aoc2019
vm.AddInput(ball > paddle ? 1 : ball < paddle ? -1 : 0);
gameTicks++;
if (printboard) PrintBoard();
if (printBoard) PrintBoard();
}
return $"after {gameTicks} moves, the score is: {board[(-1, 0)]}";

View File

@ -10,15 +10,13 @@ namespace aoc2019
private Dictionary<string, long> available;
public Day14()
public Day14() : base(14, "Space Stoichiometry")
{
reactions = Input
.Select(Reaction.Parse)
.ToDictionary(r => r.product.Name);
}
public override int DayNumber => 14;
private bool Consume(string chem, long quantity)
{
if (quantity <= 0)

View File

@ -10,13 +10,11 @@ namespace aoc2019
private readonly bool verbose = false;
private readonly IntCodeVM vm;
public Day15()
public Day15() : base(15, "Oxygen System")
{
vm = new IntCodeVM(Input.First());
}
public override int DayNumber => 15;
protected override string Part1()
{
vm.Reset();

View File

@ -10,13 +10,11 @@ namespace aoc2019
private static readonly int[] BasePattern = {0, 1, 0, -1};
private readonly int[] initialList;
public Day16()
public Day16() : base(16, "Flawed Frequency Transmission")
{
initialList = Input.First().Select(c => int.Parse($"{c}")).ToArray();
}
public override int DayNumber => 16;
protected override string Part1()
{
const int phaseCount = 100;

View File

@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using aoc2019.lib;
@ -12,13 +11,11 @@ namespace aoc2019
private readonly IntCodeVM vm;
public Day17()
public Day17() : base(17, "Set and Forget")
{
vm = new IntCodeVM(Input.First());
}
public override int DayNumber => 17;
protected override string Part1()
{
vm.Reset();
@ -44,13 +41,13 @@ namespace aoc2019
protected override string Part2()
{
vm.Reset();
vm.memory[0] = 2;
var halt = IntCodeVM.HaltType.Waiting;
while (halt == IntCodeVM.HaltType.Waiting)
{
halt = vm.Run();
}
//vm.Reset();
//vm.memory[0] = 2;
//var halt = IntCodeVM.HaltType.Waiting;
//while (halt == IntCodeVM.HaltType.Waiting)
//{
// halt = vm.Run();
//}
return "";
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace aoc2019.lib
@ -28,5 +29,20 @@ namespace aoc2019.lib
foreach (var item in sequence)
yield return item;
}
/// <summary>
/// increased accuracy for stopwatch based on frequency.
/// <see
/// href="http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks.aspx">
/// blog
/// details here
/// </see>
/// </summary>
/// <param name="stopwatch"></param>
/// <returns></returns>
public static double ScaleMilliseconds(this Stopwatch stopwatch)
{
return 1_000 * stopwatch.ElapsedTicks / (double) Stopwatch.Frequency;
}
}
}