Updates to Runner

Added Previous years of AOC
This commit is contained in:
2022-12-04 13:57:15 -05:00
parent e9ccc06320
commit dbdd716f05
42 changed files with 6875 additions and 25 deletions

View File

@@ -14,10 +14,24 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Problems\*\*\*.csv">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Remove="Problems\AOC2022\Day3\input.txt" /> <None Remove="Problems\AOC2022\Day3\input.txt" />
<None Remove="Problems\AOC2022\Day3\test.txt" /> <None Remove="Problems\AOC2022\Day3\test.txt" />
<None Remove="Problems\AOC2022\Day4\input.txt" />
<None Remove="Problems\AOC2022\Day4\test.txt" />
</ItemGroup>
<ItemGroup>
<Folder Include="Problems\AOC2015\" />
<Folder Include="Problems\AOC2021\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,62 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2015.Day10;
[ProblemInfo(2015, 10, "Evles Look, Elves Say")]
internal class LookAndSay : Problem<int, int>
{
private string _input = string.Empty;
public override void CalculatePart1()
{
Part1 = Run(40);
}
public override void CalculatePart2()
{
Part2 = Run(50);
}
public override void LoadInput()
{
_input = "3113322113";
}
public int Run(int iter)
{
var value = new StringBuilder(_input);
for (int i = 0; i < iter; i++)
CalculateNext(ref value);
return value.Length;
}
private static void CalculateNext(ref StringBuilder input)
{
var next = new StringBuilder();
var len = input.Length;
var curCount = 1;
var curChar = input[0];
for (int i = 1; i < len; i++)
{
var c = input[i];
if (c != curChar)
{
next.Append(curCount).Append(curChar);
curChar = c;
curCount = 1;
continue;
}
curCount++;
}
next.Append(curCount).Append(curChar);
input = next;
}
}

View File

@@ -0,0 +1,109 @@
using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2015.Day5;
[ProblemInfo(2015, 5, "Doesn't He Have Intern-Elves For This?")]
public class NiceList : Problem<int, int>
{
private string[] _inputData = Array.Empty<string>();
public override void LoadInput()
{
_inputData = ReadInputLines();
}
public override void CalculatePart1()
{
for (int i = 0; i < _inputData.Length; i++)
{
if (IsNice(_inputData[i]))
Part1++;
}
}
public override void CalculatePart2()
{
for (int i = 0; i < _inputData.Length; i++)
{
if (IsNice2(_inputData[i]))
{
Part2++;
}
}
}
private static bool IsNice2(string value)
{
var pairs = new Dictionary<string, List<int>>();
var separatedPair = false;
for (int i = 1; i < value.Length; i++)
{
var c = value[i];
var curIndex = i - 1;
var pair = value[curIndex..(i + 1)];
if (pairs.ContainsKey(pair))
{
if (pairs[pair].Contains(curIndex - 1))
continue;
pairs[pair].Add(curIndex);
}
else
{
pairs.Add(pair, new List<int>() { curIndex });
}
if (i == 1)
continue;
if (value[i - 2] == c)
separatedPair = true;
}
return separatedPair && pairs.Any(p => p.Value.Count >= 2);
}
private static bool IsNice(string value)
{
var vowelCount = 0;
var doubleLetters = false;
for (int i = 0; i < value.Length; i++)
{
char c = value[i];
if (IsVowel(c))
vowelCount++;
if (i == 0)
continue;
var lastChar = value[i - 1];
if (IsIllegal(c, lastChar))
return false;
if (IsDouble(c, lastChar))
doubleLetters = true;
}
return doubleLetters && vowelCount >= 3;
}
private static bool IsVowel(char c)
{
return c switch
{
'a' or 'e' or 'i' or 'o' or 'u' => true,
_ => false
};
}
private static bool IsDouble(char c, char lastChar)
{
return c == lastChar;
}
private static bool IsIllegal(char c, char lastChar)
{
return (lastChar, c) switch
{
('a', 'b') => true,
('c', 'd') => true,
('p', 'q') => true,
('x', 'y') => true,
_ => false
};
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace AdventOfCode.Problems.AOC2019.Day1
{
[ProblemInfo(2019, 1, "The Tyranny of the Rocket Equation")]
public class FuelCaluclation : Problem<int, int>
{
private int[] _input = Array.Empty<int>();
public static int GetFuelRequirement(int[] input)
{
var curFuel = input.Sum(i => GetFuelCost(i));
return curFuel;
}
public static int GetFuelCost(int mass)
{
var curCost = mass / 3 - 2;
if (curCost <= 0)
return 0;
return curCost + GetFuelCost(curCost);
}
public static int GetCost(int mass) => mass/ 3 - 2;
public override void LoadInput()
{
_input = InputParsing.ParseIntArray(GetInputFile());
}
public override void CalculatePart1()
{
Part1 = _input.Sum(i => GetCost(i));
}
public override void CalculatePart2()
{
Part2 = GetFuelRequirement(_input);
}
}
}

View File

@@ -0,0 +1,100 @@
102480
121446
118935
54155
102510
142419
73274
57571
123916
99176
143124
141318
72224
145479
97027
126427
94990
100521
105589
123009
77143
142861
92366
66478
102195
128373
128447
120178
99122
98671
89541
125720
107984
126544
145231
110241
123926
72793
76705
128338
74262
68845
65297
112536
59892
57115
73230
80569
146118
108843
59221
140492
122616
140652
64404
99782
104375
86926
143145
114969
108948
77236
143655
71406
97588
64892
105345
104393
93442
54525
94116
123606
106813
59904
149253
81620
80892
66309
142604
97984
79743
79448
123756
64927
139703
71448
135964
86083
94767
116856
73786
141083
122581
82239
122282
96092
80029
52957
72062
52124

View File

@@ -0,0 +1,72 @@
using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2019.Day2
{
[ProblemInfo(2019, 2, "Program Alarm")]
public class IntCode : Problem<int, int>
{
private int[] _inputPart1 = Array.Empty<int>();
private int[] _inputPart2 = Array.Empty<int>();
public static int ExecuteCode(int[] code, int noun, int verb)
{
int[] memory = code;
memory[1] = noun;
memory[2] = verb;
var curAddr = 0;
while (true)
{
var opCode = memory[curAddr];
if (opCode == 99) //Halt
return memory[0];
//Working Adresses
int a = memory[curAddr + 1], b = memory[curAddr + 2], c = memory[curAddr + 3];
if (a > memory.Length || b > memory.Length || c > memory.Length)
{
Console.WriteLine("ERROR: Out of Bounds");
return 0;
}
if (opCode == 1) //Add
memory[c] = memory[a] + memory[b];
if (opCode == 2) //Multiply
memory[c] = memory[a] * memory[b];
curAddr += 4;
}
}
public override void LoadInput()
{
_inputPart1 = InputParsing.ParseIntCsv(GetInputFile("input.csv"));
_inputPart2 = InputParsing.ParseIntCsv(GetInputFile("input.csv"));
}
public override void CalculatePart1()
{
Part1 = ExecuteCode(_inputPart1, 12, 2);
}
public override void CalculatePart2()
{
int targetOutput = 19690720;
for (int n = 0; n < 100; n++)
{
for (int v = 0; v < 100; v++)
{
var curInput = new int[_inputPart2.Length];
Array.Copy(_inputPart2, curInput, _inputPart2.Length);
if (ExecuteCode(curInput, n, v) == targetOutput)
{
Part2 = 100 * n + v;
return;
}
}
}
}
}
}

View File

@@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,10,19,1,19,5,23,2,23,9,27,1,5,27,31,1,9,31,35,1,35,10,39,2,13,39,43,1,43,9,47,1,47,9,51,1,6,51,55,1,13,55,59,1,59,13,63,1,13,63,67,1,6,67,71,1,71,13,75,2,10,75,79,1,13,79,83,1,83,10,87,2,9,87,91,1,6,91,95,1,9,95,99,2,99,10,103,1,103,5,107,2,6,107,111,1,111,6,115,1,9,115,119,1,9,119,123,2,10,123,127,1,127,5,131,2,6,131,135,1,135,5,139,1,9,139,143,2,143,13,147,1,9,147,151,1,151,2,155,1,9,155,0,99,2,0,14,0
1 1 0 0 3 1 1 2 3 1 3 4 3 1 5 0 3 2 1 10 19 1 19 5 23 2 23 9 27 1 5 27 31 1 9 31 35 1 35 10 39 2 13 39 43 1 43 9 47 1 47 9 51 1 6 51 55 1 13 55 59 1 59 13 63 1 13 63 67 1 6 67 71 1 71 13 75 2 10 75 79 1 13 79 83 1 83 10 87 2 9 87 91 1 6 91 95 1 9 95 99 2 99 10 103 1 103 5 107 2 6 107 111 1 111 6 115 1 9 115 119 1 9 119 123 2 10 123 127 1 127 5 131 2 6 131 135 1 135 5 139 1 9 139 143 2 143 13 147 1 9 147 151 1 151 2 155 1 9 155 0 99 2 0 14 0

View File

@@ -0,0 +1,328 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
namespace AdventOfCode.Problems.AOC2019.Day3
{
[ProblemInfo(2019, 3, "Crossed Wires")]
public class CrossedWires : Problem<int, int>
{
private string[] _inputLines = Array.Empty<string>();
public struct WireSegment
{
public Point min, max;
public Point start, end;
public int Length;
public bool Vertical => min.X == max.X;
public WireSegment(Point a, Point b)
{
start = a;
end = b;
if (a.X == b.X) //Vertical
{
if (a.Y < b.Y)
{
min = a;
max = b;
}
else
{
min = b;
max = a;
}
Length = Math.Abs(b.Y - a.Y);
}
else
{
if (a.X < b.X)
{
min = a;
max = b;
}
else
{
min = b;
max = a;
}
Length = Math.Abs(b.X - a.X);
}
}
public WireSegment CreateRelative(Point offset)
{
return new WireSegment(end, new Point(end.X + offset.X, end.Y + offset.Y));
}
public bool ContainsPoint(Point point)
{
if (Vertical)
{
if (min.X == point.X)
{
return min.Y <= point.Y && max.Y >= point.Y;
}
else
return false;
}
else
{
if (min.Y == point.Y)
{
return min.X <= point.X && max.X >= point.X;
}
else
return false;
}
}
public bool Contains(WireSegment other)
{
if (Vertical != other.Vertical)
return false;
if (Vertical)
{
return min.Y <= other.min.Y && max.Y >= other.max.Y;
}
else
{
return min.X <= other.min.X && max.X >= other.max.X;
}
}
public WireSegment GetOverlap(WireSegment other)
{
if (Vertical)
{
if (other.Contains(this))
return this;
else if (Contains(other))
return other;
if (max.Y >= other.min.Y && min.Y <= other.min.Y && max.Y <= other.max.Y)
{
return new WireSegment(other.min, max);
}
else if (max.Y >= other.max.Y && min.Y >= other.min.Y && min.Y <= other.max.Y)
return new WireSegment(min, other.max);
else
throw new Exception("No Overlap");
}
else
{
if (other.Contains(this))
return this;
else if (Contains(other))
return other;
if (max.X >= other.min.X && min.X <= other.min.X && max.X <= other.max.X)
{
return new WireSegment(other.min, max);
}
else if (max.X >= other.max.X && min.X >= other.min.X && min.X <= other.max.X)
return new WireSegment(min, other.max);
else
throw new Exception("No Overlap");
}
}
public bool Intersect(WireSegment other, out Point intersection)
{
if (Vertical)
{
if (!other.Vertical)//Other Horizontal
{
var potInt = new Point(min.X, other.min.Y);
if (potInt == default)
{
intersection = default;
return false;
}
if (ContainsPoint(potInt) && other.ContainsPoint(potInt))
{
intersection = potInt;
return true;
}
else
{
intersection = default;
return false;
}
}
else //Both
{
if (min.X != other.min.X)
{
intersection = default;
return false;
}
else
{
var overlap = GetOverlap(other);
if (ManhattanMagnitude(overlap.min) < ManhattanMagnitude(overlap.max))
intersection = overlap.min == default ? overlap.max : overlap.min;
else
intersection = overlap.max == default ? overlap.min : overlap.max;
if (intersection == default)
return false;
return true;
}
}
}
else
{
if (!other.Vertical) //Other Horizontal
{
if (min.Y != other.min.Y)
{
intersection = default;
return false;
}
var overlap = GetOverlap(other);
if (ManhattanMagnitude(overlap.min) < ManhattanMagnitude(overlap.max))
intersection = overlap.min == default ? overlap.max : overlap.min;
else
intersection = overlap.max == default ? overlap.min : overlap.max;
if (intersection == default)
return false;
return true;
}
else
return other.Intersect(this, out intersection);
}
}
public override string ToString()
{
return $"{start} > {end}";
}
}
public static int StepsToPoint(List<WireSegment> wires, Point p)
{
var steps = 0;
for (int i = 0; i < wires.Count; i++)
{
if (wires[i].ContainsPoint(p))
{
if (wires[i].Vertical)
steps += Math.Abs(wires[i].start.Y - p.Y);
else
steps += Math.Abs(wires[i].start.X - p.X);
break;
}
else
steps += wires[i].Length;
}
return steps;
}
public static int SolveWires(string[] wires)
{
var (wireSegmentsA, wireSegmentsB) = CreateWirePair(wires);
int shortestWire = int.MaxValue;
for (int i = 0; i < wireSegmentsA.Count; i++)
{
for (int j = 0; j < wireSegmentsB.Count; j++)
{
if (wireSegmentsA[i].Intersect(wireSegmentsB[j], out var intersection))
{
var len = StepsToPoint(wireSegmentsA, intersection) + StepsToPoint(wireSegmentsB, intersection);
if (len < shortestWire)
shortestWire = len;
}
}
}
return shortestWire;
}
public static int SolveClosestDistane(string[] wires)
{
var (wireSegmentsA, wireSegmentsB) = CreateWirePair(wires);
int lastIntersection = int.MaxValue;
for (int i = 0; i < wireSegmentsA.Count; i++)
{
for (int j = 0; j < wireSegmentsB.Count; j++)
{
if (wireSegmentsA[i].Intersect(wireSegmentsB[j], out var intersection))
{
var dist = ManhattanMagnitude(intersection);
if (dist < lastIntersection)
lastIntersection = dist;
}
}
}
return lastIntersection;
}
private static (List<WireSegment> A, List<WireSegment> B) CreateWirePair(string[] wires)
{
var wireA = wires[0].Split(',');
var wireSegmentsA = CreateWire(wireA);
var wireB = wires[1].Split(',');
var wireSegmentsB = CreateWire(wireB);
return (wireSegmentsA, wireSegmentsB);
}
private static List<WireSegment> CreateWire(string[] wires)
{
var wireSegments = new List<WireSegment>();
for (int i = 0; i < wires.Length; i++)
{
var curSegment = wires[i];
var offset = GetOffset(curSegment);
if (i == 0)
wireSegments.Add(new WireSegment(new Point(0, 0), offset));
else
wireSegments.Add(wireSegments.Last().CreateRelative(offset));
}
return wireSegments;
}
public static int ManhattanMagnitude(Point point) => Math.Abs(point.X) + Math.Abs(point.Y);
public static Point GetOffset(string move)
{
int x = 0, y = 0;
if (move[0] == 'R')
x = int.Parse(move.Remove(0, 1));
else if (move[0] == 'L')
x = -int.Parse(move.Remove(0, 1));
else if (move[0] == 'U')
y = int.Parse(move.Remove(0, 1));
else if (move[0] == 'D')
y = -int.Parse(move.Remove(0, 1));
return new Point(x, y);
}
public override void LoadInput()
{
_inputLines = ReadInputLines();
}
public override void CalculatePart1()
{
Part1 = SolveClosestDistane(_inputLines);
}
public override void CalculatePart2()
{
Part2 = SolveWires(_inputLines);
}
}
}

View File

@@ -0,0 +1,2 @@
R1000,U573,L25,U468,L833,D867,R515,D941,L513,D1,L380,U335,L661,D725,L506,U365,L103,D987,L425,U756,R129,D153,R326,U297,L456,D632,L142,U666,R864,D255,R85,D661,L566,D125,R445,U293,R295,D14,R181,D772,R376,U151,L146,D344,L947,D519,L455,D232,L873,U617,R143,D600,R654,D14,R813,U176,L443,U712,R230,U629,L554,U886,L931,D591,R716,U904,R605,D176,R801,U911,L746,D316,R30,U240,R975,D929,L879,U295,L56,U662,R429,U117,R282,D716,R57,D445,L7,D486,R147,D991,R750,D252,R134,U43,L410,D757,R252,U595,R986,U978,L883,D664,R267,D718,R28,U727,R926,U395,L81,D70,L67,D92,R209,D633,L253,D798,R820,U816,R754,U646,R846,D863,L868,U911,L678,D893,R686,D466,L153,D884,L589,U960,L924,U603,R93,D518,L291,D324,L67,D40,R722,U384,R195,D916,R64,D666,R896,D860,R388,D833,L662,D192,R567,U551,L558,U11,L674,U19,L669,U110,R681,D882,L997,U535,R683,U313,L904,U674,L476,D969,L464,D342,R574,D981,R405,D352,R431,U429,L329,D160,L573,U978,R930,U683,R592,D877,L88,D512,R676,U436,R708,U187,L664,U614,L734,D480,L242,U489,R732,U876,L416,D524,R181,U846,L396,D974,L620,D282,L124,D206,R119,U179,L171,D528,R469,U516,L708,D599,R913,U63,R922,D300,L856,U700,L396,D185,R933,D453,L234,D385,R426,D189,L25,U599,L715,U355,L574,D857,R662,D504,R746,U386,R389,U751,R85,U499,R255,D150,R998,U804,L832,D642,R102,U202,R972,U312,L265,D484,R314,D591,L250,U791,L120,D536,L808,D972,L808,D46,L626,D284,R60,D155,L849,D501,L206,U445,L765,U770,L67,U780,R876,D409,R603,U713,L459,D81,L294,D471,R656,U603,R55,D650,L211,D333,L44,D168,L187,D52,R60,D574,R54
L1004,U110,R738,D383,R606,U840,L123,D756,L234,D585,R475,U429,L585,D615,L859,D669,L812,U672,L415,D114,L538,D899,R444,D379,L886,D276,R268,D90,R200,D247,L704,D802,L10,U313,R437,D854,R899,U21,L553,D352,L736,U604,R162,D504,R509,D471,R501,D472,L117,U796,L828,U906,R450,U697,R831,D302,R879,U730,R381,U788,L654,U927,R971,D355,L712,D959,L104,D169,L297,U898,R82,D673,R21,D608,L813,U754,L554,U239,L1,U834,R456,D671,L692,D855,L784,U664,R832,U446,L673,D898,R146,U507,L934,D569,R249,D755,L212,D475,R970,U122,R418,U820,L754,U313,L843,D608,R165,D881,L293,U628,R492,D37,L120,U659,L471,D275,R790,U372,L736,U318,L353,U439,L669,U18,R683,U768,R518,U300,L478,U601,R14,U233,L33,U765,L910,U591,R304,D528,R637,D376,L704,U27,L226,U384,R870,U318,L975,U876,R576,U500,R880,D108,L670,U171,R561,U873,L391,U717,L455,D909,L34,U211,R919,U376,L228,D632,L91,U408,R354,U454,L81,D547,L624,U464,R480,D630,L596,D57,L206,U736,R255,U185,L236,U705,L221,D511,L461,U718,R351,D59,L142,U236,R623,D124,R736,D758,L368,D605,L417,U990,R228,D207,L792,U150,L353,U612,R269,D459,L855,U808,L852,U168,R838,D794,R478,U281,L453,D134,L643,D862,L299,D590,L570,D782,L294,U935,R835,U849,R842,U997,R890,U20,L370,D157,R89,U203,L243,U71,R987,D812,R595,U664,L926,D359,L915,D382,R190,D443,R360,U253,R230,D879,L606,D755,R859,U232,R771,U465,R858,D823,R405,D499,L737,U846,R241,D976,R415,U541,L746,D569,L563,D410,L409,D39,R117,U638,R824,D215,R232,U578,R790,U535,R873,D477,R805,U94,L313,U570,L500,U783,L556,U663,L335,U152,L524,D583,L462,U710,R741,U641,L135

View File

@@ -0,0 +1,157 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace AdventOfCode.Problems.AOC2019.Day4
{
[ProblemInfo(2019, 4, "Secure Container")]
public class SecureContainer : Problem<int, int>
{
public static bool IsValidPassword(int[] password)
{
if (password.Length != 6)
return false;
return HasRepeating(password) && IsAssending(password);
}
public static bool HasRepeating(int[] password)
{
for (int i = 0; i < password.Length - 1; i++)
{
if (password[i] == password[i + 1])
return true;
}
return false;
}
public static bool HasDoubles(int[] password)
{
bool foundDouble = false;
for (int i = 0; i < 6; i++)
{
int c = 0;
for (int j = 0; j < 6; j++)
{
if (password[j] == password[i])
c++;
else
{
if (c != 0)
{
if (c == 2)
foundDouble = true;
c = 0;
}
}
}
if (c == 2)
foundDouble = true;
}
return foundDouble;
}
public static bool IsAssending(int[] password)
{
for (int i = 1; i < 6; i++)
{
if (password[i] < password[i - 1])
{
return false;
}
}
return true;
}
public static int CountPasswordsPart1(int lower, int upper)
{
int passwordCount = 0;
int[] curPassword = lower.ToIntArray();
CleanPassword(ref curPassword);
while (curPassword.ToInt() <= upper)
{
if (IsValidPassword(curPassword))
{
passwordCount++;
}
curPassword[^1]++;
Propagate(ref curPassword, curPassword.Length - 1);
CleanPassword(ref curPassword);
}
return passwordCount;
}
public static int CountPasswordsPart2(int lower, int upper)
{
int passwordCount = 0;
int[] curPassword = lower.ToIntArray();
CleanPassword(ref curPassword);
while (curPassword.ToInt() <= upper)
{
if (HasDoubles(curPassword))
{
passwordCount++;
}
curPassword[^1]++;
Propagate(ref curPassword, curPassword.Length - 1);
CleanPassword(ref curPassword);
}
return passwordCount;
}
public static void CleanPassword(ref int[] password)
{
for (int i = 1; i < 6; i++)
{
if (password[i] < password[i - 1])
{
password[i] += password[i - 1] - password[i];
if (password[i] == 10)
{
Propagate(ref password, i);
password[i] = password[i - 1];
}
}
}
}
public static void Propagate(ref int[] password, int digit)
{
for (int i = digit; i >= 0; i--)
{
if (i == 0 && password[i] == 10)
{
password[i] = 9;
break;
}
if (password[i] == 10)
{
password[i] = 0;
password[i - 1]++;
}
}
}
public override void LoadInput()
{
}
public override void CalculatePart1()
{
Part1 = CountPasswordsPart1(147981, 691423);
}
public override void CalculatePart2()
{
Part2 = CountPasswordsPart2(147981, 691423);
}
}
}

View File

@@ -0,0 +1,36 @@
using AdventOfCode.Day_5;
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2019.Day5;
[ProblemInfo(2019, 5, "Sunny with a Chance of Asteroids")]
internal class ChanceOfAsteroids : Problem<int, int>
{
private IntCodeV2 _cpu = new IntCodeV2();
private int[] _baseInput = Array.Empty<int>();
public override void CalculatePart1()
{
var output = new int[1];
_cpu.ExecuteCode(_baseInput, new int[] { 1 }, output);
Part1 = output[0];
}
public override void CalculatePart2()
{
var output = new int[1];
_cpu.ExecuteCode(_baseInput, new int[] { 5 }, output);
Part2 = output[0];
}
public override void LoadInput()
{
_baseInput = InputParsing.ParseIntCsv(GetInputFile("input.csv"));
}
}

View File

@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace AdventOfCode.Day_5
{
public class IntCodeV2
{
public struct Instruction
{
public int opcode;
public int paramCount;
public Func<int[], int[], int, int, int, bool> action;
public Instruction(int opcode, int paramCount, Func<int[], int[], int, int, int, bool> action)
{
this.opcode = opcode;
this.paramCount = paramCount;
this.action = action;
}
}
public bool IsHalted { get; private set; }
public bool IsRunning { get; private set; }
public bool PersistentMode { get; private set; }
public bool SuspendOnWrite { get; private set; }
private Dictionary<int, Instruction> _instructions;
private int _instructionPointer;
private int[]? _inputBuffer;
private int _inputCounter = 0;
private int[]? _outputBuffer;
private int _outputCounter = 0;
private int[] memory = Array.Empty<int>();
public IntCodeV2(bool persistentMode = false, bool suspendOnOutput = false)
{
_instructions = new Dictionary<int, Instruction>();
PersistentMode = persistentMode;
SuspendOnWrite = suspendOnOutput;
IsHalted = false;
//Add
_instructions.Add(1, new Instruction(1, 3, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
var v3 = mode[0] == 1 ? mem[p3] : p3;
mem[v3] = v1 + v2;
return true;
}));
//Multiply
_instructions.Add(2, new Instruction(2, 3, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
var v3 = mode[0] == 1 ? mem[p3] : p3;
mem[v3] = v1 * v2;
return true;
}));
//Halt
_instructions.Add(99, new Instruction(99, 0, (mem, mode, p1, p2, p3) =>
{
IsHalted = true;
IsRunning = false;
return false;
}));
//Read Input
_instructions.Add(3, new Instruction(3, 1, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? mem[p1] : p1;
mem[v1] = ReadInput();
//Console.WriteLine($"Input Read: {mem[v1]}");
return true;
}));
//Write Output
_instructions.Add(4, new Instruction(4, 1, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
WriteOutput(v1);
if (SuspendOnWrite)
IsRunning = false;
return true;
}));
//Jump if True
_instructions.Add(5, new Instruction(5, 2, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
if (v1 != 0)
{
_instructionPointer = v2;
return false;
}
return true;
}));
//Jump if False
_instructions.Add(6, new Instruction(6, 2, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
if (v1 == 0)
{
_instructionPointer = v2;
return false;
}
return true;
}));
//Less than
_instructions.Add(7, new Instruction(7, 3, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
var v3 = mode[0] == 1 ? mem[p3] : p3;
if (v1 < v2)
mem[v3] = 1;
else
mem[v3] = 0;
return true;
}));
//Equals
_instructions.Add(8, new Instruction(8, 3, (mem, mode, p1, p2, p3) =>
{
var v1 = mode[2] == 1 ? p1 : mem[p1];
var v2 = mode[1] == 1 ? p2 : mem[p2];
var v3 = mode[0] == 1 ? mem[p3] : p3;
if (v1 == v2)
mem[v3] = 1;
else
mem[v3] = 0;
return true;
}));
}
private int ReadInput()
{
_inputCounter = Math.Min(_inputCounter, (_inputBuffer?.Length ?? 1) - 1);
if (_inputBuffer != null && _inputCounter < _inputBuffer.Length)
return _inputBuffer[_inputCounter++];
else
{
Console.Write("Input: ");
return int.Parse(Console.ReadLine()!);
}
}
private void WriteOutput(int output)
{
_outputCounter = Math.Min(_outputCounter, (_outputBuffer?.Length ?? 1) - 1);
if (_outputBuffer != null && _outputCounter < _outputBuffer.Length)
_outputBuffer[_outputCounter++] = output;
else
Console.WriteLine(output);
}
public void ExecuteCode(int[] code, int[]? input = null, int[]? output = null)
{
LoadCode(code);
SetIO(input, output);
IsHalted = false;
Run();
}
public static (int[] opModes, int opcode) ParseInstruction(int instruction)
{
var opModes = new int[3];
var arr = instruction.ToIntArray();
switch(arr.Length)
{
case 1:
return (opModes, arr[0]);
case 2:
return (opModes, (arr[^2] * 10) + arr[^1]);
}
var opcode = (arr[^2] * 10) + arr[^1];
for (int i = 1; i <= 3; i++)
{
if (arr.Length < i + 2)
opModes[^i] = 0;
else
opModes[^i] = arr[^(i + 2)];
}
return (opModes, opcode);
}
public void ResetIO()
{
_inputCounter = _outputCounter = 0;
}
public void SetInputIndex(int index)
{
_inputCounter = index;
}
public void SetIO(int[]? inputBuffer, int[]? outputBuffer)
{
ResetIO();
_inputBuffer = inputBuffer ?? Array.Empty<int>();
_outputBuffer = outputBuffer ?? Array.Empty<int>();
}
public void Run()
{
IsRunning = true;
while (IsRunning)
{
var (modes, opcode) = ParseInstruction(memory[_instructionPointer]);
var curInstruction = _instructions[opcode];
int[] parameters = new int[3];
for (int i = 0; i < 3; i++)
{
if (i >= curInstruction.paramCount)
parameters[i] = 0;
else
parameters[i] = memory[_instructionPointer + i + 1];
}
if (curInstruction.action(memory, modes, parameters[0], parameters[1], parameters[2]))
_instructionPointer += curInstruction.paramCount + 1;
if (IsHalted)
IsRunning = false;
}
}
public IntCodeV2 LoadCode(int[] code)
{
memory = new int[code.Length];
code.CopyTo(memory, 0);
_instructionPointer = 0;
return this;
}
}
}

View File

@@ -0,0 +1 @@
3,225,1,225,6,6,1100,1,238,225,104,0,1102,40,93,224,1001,224,-3720,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,1101,56,23,225,1102,64,78,225,1102,14,11,225,1101,84,27,225,1101,7,82,224,1001,224,-89,224,4,224,1002,223,8,223,1001,224,1,224,1,224,223,223,1,35,47,224,1001,224,-140,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1101,75,90,225,101,9,122,224,101,-72,224,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1102,36,63,225,1002,192,29,224,1001,224,-1218,224,4,224,1002,223,8,223,1001,224,7,224,1,223,224,223,102,31,218,224,101,-2046,224,224,4,224,102,8,223,223,101,4,224,224,1,224,223,223,1001,43,38,224,101,-52,224,224,4,224,1002,223,8,223,101,5,224,224,1,223,224,223,1102,33,42,225,2,95,40,224,101,-5850,224,224,4,224,1002,223,8,223,1001,224,7,224,1,224,223,223,1102,37,66,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1007,226,677,224,1002,223,2,223,1005,224,329,1001,223,1,223,1007,226,226,224,1002,223,2,223,1006,224,344,101,1,223,223,1107,677,226,224,102,2,223,223,1006,224,359,1001,223,1,223,108,677,677,224,1002,223,2,223,1006,224,374,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,389,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,404,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,419,101,1,223,223,1008,677,677,224,1002,223,2,223,1005,224,434,101,1,223,223,1008,226,226,224,1002,223,2,223,1005,224,449,101,1,223,223,7,677,226,224,1002,223,2,223,1006,224,464,1001,223,1,223,7,226,226,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,677,677,224,102,2,223,223,1005,224,494,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,509,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,524,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,539,1001,223,1,223,1008,226,677,224,1002,223,2,223,1006,224,554,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,569,1001,223,1,223,1108,677,677,224,102,2,223,223,1005,224,584,101,1,223,223,7,226,677,224,102,2,223,223,1006,224,599,1001,223,1,223,1108,226,677,224,102,2,223,223,1006,224,614,101,1,223,223,107,226,677,224,1002,223,2,223,1005,224,629,101,1,223,223,108,226,677,224,1002,223,2,223,1005,224,644,101,1,223,223,8,226,677,224,1002,223,2,223,1005,224,659,1001,223,1,223,107,226,226,224,1002,223,2,223,1006,224,674,101,1,223,223,4,223,99,226
1 3 225 1 225 6 6 1100 1 238 225 104 0 1102 40 93 224 1001 224 -3720 224 4 224 102 8 223 223 101 3 224 224 1 224 223 223 1101 56 23 225 1102 64 78 225 1102 14 11 225 1101 84 27 225 1101 7 82 224 1001 224 -89 224 4 224 1002 223 8 223 1001 224 1 224 1 224 223 223 1 35 47 224 1001 224 -140 224 4 224 1002 223 8 223 101 5 224 224 1 224 223 223 1101 75 90 225 101 9 122 224 101 -72 224 224 4 224 1002 223 8 223 101 6 224 224 1 224 223 223 1102 36 63 225 1002 192 29 224 1001 224 -1218 224 4 224 1002 223 8 223 1001 224 7 224 1 223 224 223 102 31 218 224 101 -2046 224 224 4 224 102 8 223 223 101 4 224 224 1 224 223 223 1001 43 38 224 101 -52 224 224 4 224 1002 223 8 223 101 5 224 224 1 223 224 223 1102 33 42 225 2 95 40 224 101 -5850 224 224 4 224 1002 223 8 223 1001 224 7 224 1 224 223 223 1102 37 66 225 4 223 99 0 0 0 677 0 0 0 0 0 0 0 0 0 0 0 1105 0 99999 1105 227 247 1105 1 99999 1005 227 99999 1005 0 256 1105 1 99999 1106 227 99999 1106 0 265 1105 1 99999 1006 0 99999 1006 227 274 1105 1 99999 1105 1 280 1105 1 99999 1 225 225 225 1101 294 0 0 105 1 0 1105 1 99999 1106 0 300 1105 1 99999 1 225 225 225 1101 314 0 0 106 0 0 1105 1 99999 1007 226 677 224 1002 223 2 223 1005 224 329 1001 223 1 223 1007 226 226 224 1002 223 2 223 1006 224 344 101 1 223 223 1107 677 226 224 102 2 223 223 1006 224 359 1001 223 1 223 108 677 677 224 1002 223 2 223 1006 224 374 1001 223 1 223 107 677 677 224 1002 223 2 223 1005 224 389 101 1 223 223 8 677 677 224 1002 223 2 223 1005 224 404 1001 223 1 223 108 226 226 224 1002 223 2 223 1005 224 419 101 1 223 223 1008 677 677 224 1002 223 2 223 1005 224 434 101 1 223 223 1008 226 226 224 1002 223 2 223 1005 224 449 101 1 223 223 7 677 226 224 1002 223 2 223 1006 224 464 1001 223 1 223 7 226 226 224 1002 223 2 223 1005 224 479 1001 223 1 223 1007 677 677 224 102 2 223 223 1005 224 494 101 1 223 223 1108 677 226 224 102 2 223 223 1006 224 509 1001 223 1 223 8 677 226 224 102 2 223 223 1005 224 524 1001 223 1 223 1107 226 226 224 102 2 223 223 1006 224 539 1001 223 1 223 1008 226 677 224 1002 223 2 223 1006 224 554 1001 223 1 223 1107 226 677 224 1002 223 2 223 1006 224 569 1001 223 1 223 1108 677 677 224 102 2 223 223 1005 224 584 101 1 223 223 7 226 677 224 102 2 223 223 1006 224 599 1001 223 1 223 1108 226 677 224 102 2 223 223 1006 224 614 101 1 223 223 107 226 677 224 1002 223 2 223 1005 224 629 101 1 223 223 108 226 677 224 1002 223 2 223 1005 224 644 101 1 223 223 8 226 677 224 1002 223 2 223 1005 224 659 1001 223 1 223 107 226 226 224 1002 223 2 223 1006 224 674 101 1 223 223 4 223 99 226

View File

@@ -0,0 +1,119 @@
namespace AdventOfCode.Problems.AOC2019.Day6
{
public class OrbitMap
{
public CelestialObject root;
public Dictionary<string, CelestialObject> objectMap;
public OrbitMap(string[] orbits)
{
objectMap = new Dictionary<string, CelestialObject>();
GenerateOrbits(orbits);
}
public void GenerateOrbits(string[] orbits)
{
for (int i = 0; i < orbits.Length; i++)
{
var bodies = orbits[i].Split(')');
if (bodies[0] == "COM")
root = CreateObject("COM");
var parent = GetOrCreateObject(bodies[0]);
var child = GetOrCreateObject(bodies[1]);
parent.AddChild(child);
}
}
public CelestialObject GetOrCreateObject(string name)
{
if (objectMap.ContainsKey(name))
return objectMap[name];
else
return CreateObject(name);
}
public CelestialObject CreateObject(string name)
{
var o = new CelestialObject(name);
objectMap.Add(name, o);
return o;
}
public int CalculateOrbits()
{
return root.GetOrbitCount();
}
public List<CelestialObject> FindPathTo(string name)
{
var path = new List<CelestialObject>();
root.FindPathTo(name, path);
return path;
}
public int GetDepthOf(string name) => root.GetDepth(name);
public class CelestialObject
{
public string Name { get; set; }
public int ChildCount => children.Count;
public List<CelestialObject> children;
public CelestialObject(string name)
{
children = new List<CelestialObject>();
Name = name;
}
public void AddChild(CelestialObject child)
{
children.Add(child);
}
public int GetOrbitCount(int depth = 0)
{
var count = 0;
for (int i = 0; i < children.Count; i++)
{
count += children[i].GetOrbitCount(depth + 1);
}
return depth + count;
}
public bool FindPathTo(string name, List<CelestialObject> path)
{
if (name == Name)
return true;
for (int i = 0; i < ChildCount; i++)
{
if (children[i].FindPathTo(name, path))
{
path.Add(children[i]);
return true;
}
}
return false;
}
public int GetDepth(string name, int depth = 0)
{
if (name == Name)
return depth;
var d = 0;
for (int i = 0; i < ChildCount; i++)
{
d += children[i].GetDepth(name, depth + 1);
}
return d;
}
public override string ToString()
{
return Name;
}
}
}
}

View File

@@ -0,0 +1,60 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2019.Day6;
[ProblemInfo(2019, 6, "Universal Orbit Map")]
internal class UniversalOrbits : Problem<int, int>
{
private OrbitMap? _map;
public override void CalculatePart1()
{
if(_map == null)
return;
Part1 = _map.CalculateOrbits();
}
public override void CalculatePart2()
{
if (_map == null)
return;
var pathToYOU = _map.FindPathTo("YOU");
var pathToSAN = _map.FindPathTo("SAN");
string pivot = "";
int dist = 0;
HashSet<string> pathYOU = new(pathToYOU.Select(o => o.Name));
for (int i = 0; i < pathToSAN.Count; i++)
{
if (pathYOU.Contains(pathToSAN[i].Name))
{
pivot = pathToSAN[i].Name;
dist = i;
break;
}
}
for (int i = 0; i < pathToYOU.Count; i++)
{
if (pathToYOU[i].Name == pivot)
{
dist += i;
break;
}
}
Part2 = dist - 2;
}
public override void LoadInput()
{
_map = new OrbitMap(ReadInputLines());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
COM)B
B)C
C)D
D)E
E)F
B)G
G)H
D)I
E)J
J)K
K)L
K)YOU
I)SAN

View File

@@ -0,0 +1,161 @@
using AdventOfCode.Day_5;
using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2019.Day7
{
[ProblemInfo(2019, 7, "Amplification Circuit")]
public class AmplificationCircuit : Problem<int, int>
{
private int[] _code = Array.Empty<int>();
public static int RunPhase(IntCodeV2 cpu, int[] code, int[] phaseSettings)
{
if (HasDuplicateValues(phaseSettings))
return int.MinValue;
int[] outputBuffer = { 0 };
int[] inputBuffer;
//Amp A
inputBuffer = new int[] { phaseSettings[0], outputBuffer[0] };
cpu.ExecuteCode(code, inputBuffer, outputBuffer);
//Amp B
inputBuffer = new int[] { phaseSettings[1], outputBuffer[0] };
cpu.ExecuteCode(code, inputBuffer, outputBuffer);
//Amp C
inputBuffer = new int[] { phaseSettings[2], outputBuffer[0] };
cpu.ExecuteCode(code, inputBuffer, outputBuffer);
//Amp D
inputBuffer = new int[] { phaseSettings[3], outputBuffer[0] };
cpu.ExecuteCode(code, inputBuffer, outputBuffer);
//Amp E
inputBuffer = new int[] { phaseSettings[4], outputBuffer[0] };
cpu.ExecuteCode(code, inputBuffer, outputBuffer);
return outputBuffer[0];
}
public static int RunFeedback(int[] code, int[] phaseSettings)
{
if (HasDuplicateValues(phaseSettings))
return int.MinValue;
var ampA = new IntCodeV2(true, true).LoadCode(code);
var ampB = new IntCodeV2(true, true).LoadCode(code);
var ampC = new IntCodeV2(true, true).LoadCode(code);
var ampD = new IntCodeV2(true, true).LoadCode(code);
var ampE = new IntCodeV2(true, true).LoadCode(code);
var outputA = new int[] { 273 };
var outputB = new int[] { 0 };
var outputC = new int[] { 0 };
var outputD = new int[] { 0 };
var outputE = new int[] { 0 };
var inputA = new int[] { phaseSettings[0], outputE[0] };
var inputB = new int[] { phaseSettings[1], outputA[0] };
var inputC = new int[] { phaseSettings[2], outputB[0] };
var inputD = new int[] { phaseSettings[3], outputC[0] };
var inputE = new int[] { phaseSettings[4], outputD[0] };
ampA.SetIO(inputA, outputA);
ampB.SetIO(inputB, outputB);
ampC.SetIO(inputC, outputC);
ampD.SetIO(inputD, outputD);
ampE.SetIO(inputE, outputE);
int iter = 0;
while (!ampE.IsHalted)
{
//Console.WriteLine($"Iteration {iter}");
inputA[1] = outputE[0];
ampA.Run();
inputB[1] = outputA[0];
ampB.Run();
inputC[1] = outputB[0];
ampC.Run();
inputD[1] = outputC[0];
ampD.Run();
inputE[1] = outputD[0];
ampE.Run();
//Console.WriteLine($"Output {outputE[0]}");
iter++;
}
return outputE[0];
}
public static bool HasDuplicateValues(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
for (int j = 0; j < arr.Length; j++)
{
if (i == j)
continue;
if (arr[i] == arr[j])
return true;
}
}
return false;
}
public override void LoadInput()
{
_code = InputParsing.ParseIntCsv(GetInputFile("input.csv"));
}
public override void CalculatePart1()
{
int output = int.MinValue;
int min = 0;
int max = 5;
var cpu = new IntCodeV2();
for (int i = min; i < max; i++)
{
for (int j = min; j < max; j++)
{
for (int k = min; k < max; k++)
{
for (int l = min; l < max; l++)
{
for (int m = min; m < max; m++)
{
var result = RunPhase(cpu, _code, new int[] { i, j, k, l, m });
if (output < result)
{
output = result;
}
}
}
}
}
}
Part1 = output;
}
public override void CalculatePart2()
{
int output = int.MinValue;
int min = 5;
int max = 10;
for (int i = min; i < max; i++)
{
for (int j = min; j < max; j++)
{
for (int k = min; k < max; k++)
{
for (int l = min; l < max; l++)
{
for (int m = min; m < max; m++)
{
var result = RunFeedback(_code, new int[] { i, j, k, l, m });
if (output < result)
{
output = result;
}
}
}
}
}
}
Part2 = output;
}
}
}

View File

@@ -0,0 +1 @@
3,8,1001,8,10,8,105,1,0,0,21,34,59,68,85,102,183,264,345,426,99999,3,9,101,3,9,9,102,3,9,9,4,9,99,3,9,1002,9,4,9,1001,9,2,9,1002,9,2,9,101,5,9,9,102,5,9,9,4,9,99,3,9,1001,9,4,9,4,9,99,3,9,101,3,9,9,1002,9,2,9,1001,9,5,9,4,9,99,3,9,1002,9,3,9,1001,9,5,9,102,3,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,99
1 3 8 1001 8 10 8 105 1 0 0 21 34 59 68 85 102 183 264 345 426 99999 3 9 101 3 9 9 102 3 9 9 4 9 99 3 9 1002 9 4 9 1001 9 2 9 1002 9 2 9 101 5 9 9 102 5 9 9 4 9 99 3 9 1001 9 4 9 4 9 99 3 9 101 3 9 9 1002 9 2 9 1001 9 5 9 4 9 99 3 9 1002 9 3 9 1001 9 5 9 102 3 9 9 4 9 99 3 9 1001 9 1 9 4 9 3 9 1001 9 2 9 4 9 3 9 1002 9 2 9 4 9 3 9 102 2 9 9 4 9 3 9 1001 9 2 9 4 9 3 9 101 2 9 9 4 9 3 9 102 2 9 9 4 9 3 9 102 2 9 9 4 9 3 9 101 1 9 9 4 9 3 9 101 1 9 9 4 9 99 3 9 1002 9 2 9 4 9 3 9 1002 9 2 9 4 9 3 9 1002 9 2 9 4 9 3 9 1001 9 2 9 4 9 3 9 101 1 9 9 4 9 3 9 1001 9 1 9 4 9 3 9 1002 9 2 9 4 9 3 9 101 2 9 9 4 9 3 9 101 1 9 9 4 9 3 9 101 2 9 9 4 9 99 3 9 1001 9 1 9 4 9 3 9 101 1 9 9 4 9 3 9 102 2 9 9 4 9 3 9 1002 9 2 9 4 9 3 9 1002 9 2 9 4 9 3 9 101 2 9 9 4 9 3 9 1001 9 1 9 4 9 3 9 1001 9 1 9 4 9 3 9 102 2 9 9 4 9 3 9 1001 9 1 9 4 9 99 3 9 1002 9 2 9 4 9 3 9 101 1 9 9 4 9 3 9 1001 9 2 9 4 9 3 9 102 2 9 9 4 9 3 9 1002 9 2 9 4 9 3 9 102 2 9 9 4 9 3 9 1001 9 1 9 4 9 3 9 1002 9 2 9 4 9 3 9 1001 9 2 9 4 9 3 9 101 2 9 9 4 9 99 3 9 1001 9 1 9 4 9 3 9 1002 9 2 9 4 9 3 9 101 2 9 9 4 9 3 9 101 1 9 9 4 9 3 9 1002 9 2 9 4 9 3 9 101 1 9 9 4 9 3 9 102 2 9 9 4 9 3 9 101 1 9 9 4 9 3 9 102 2 9 9 4 9 3 9 101 2 9 9 4 9 99

View File

@@ -0,0 +1,91 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AdventOfCode.Problems.AOC2019.Day8
{
[ProblemInfo(2019, 8, "Space Image Format")]
public class SpaceImageFormat : Problem<int, string>
{
private int[] _imageData = Array.Empty<int>();
public static void Execute()
{
var imageData = File.ReadAllText("Day8/input.txt").Replace("\n", "").Select(c => int.Parse(c.ToString())).ToArray();
Console.WriteLine(Checksum(imageData, 25, 6));
}
public static void RenderImage(int[] data, int h, int w)
{
var imgSize = h * w;
var layerCount = data.Length / imgSize;
for (int l = 0; l < layerCount; l++)
{
}
}
public static int Checksum(int[] data, int h, int w)
{
var imgSize = h * w;
var layerCount = data.Length / imgSize;
int[] zeroCount = new int[layerCount];
int[] oneCount = new int[layerCount];
int[] twoCount = new int[layerCount];
int smallestLayer = -1;
int smallestLayerCount = int.MaxValue;
for (int l = 0; l < layerCount; l++)
{
for (int i = imgSize * l; i < imgSize * (l + 1); i++)
{
switch (data[i])
{
case 0:
zeroCount[l]++;
break;
case 1:
oneCount[l]++;
break;
case 2:
twoCount[l]++;
break;
}
}
if (zeroCount[l] <= smallestLayerCount)
{
smallestLayer = l;
smallestLayerCount = zeroCount[l];
}
}
return oneCount[smallestLayer] * twoCount[smallestLayer];
}
public override void LoadInput()
{
_imageData = ReadInputText().Replace("\n", "").Select(c => int.Parse(c.ToString())).ToArray();
}
public override void CalculatePart1()
{
Part1 = Checksum(_imageData, 25, 6);
}
public override void CalculatePart2()
{
Part2 = null;
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace AdventOfCode
{
public static class InputParsing
{
public static int[] ParseIntArray(string file)
{
return File.ReadAllLines(file).Select(s => int.Parse(s)).ToArray();
}
public static int[] ParseIntCsv(string file)
{
return File.ReadAllText(file).Split(',').Select(s => int.Parse(s)).ToArray();
}
public static int ToInt(this int[] intArr)
{
int value = 0;
for (int i = 0; i < intArr.Length; i++)
{
value += (int)Math.Pow(10, intArr.Length - i - 1) * intArr[i];
}
return value;
}
public static int[] ToIntArray(this int number)
{
int[] intArr = number.ToString().Select(d => int.Parse(d.ToString())).ToArray();
return intArr;
}
}
}

View File

@@ -0,0 +1,200 @@
using AdventOfCode.Runner.Attributes;
using System.Collections;
using System.Numerics;
using System.Text;
namespace AdventOfCode.Problems.AOC2021.Day11;
[ProblemInfo(2021, 11, "Dumbo Octopus")]
public class DumboOctopus : Problem<int, int>, IEnumerable<byte>
{
public byte[] dataPart1 = Array.Empty<byte>();
public byte[] dataPart2 = Array.Empty<byte>();
public override void LoadInput()
{
var data = ReadInputLines();
dataPart1 = new byte[10 * 10];
if (data.Length != 10)
throw new ArgumentException("Data must contain 10 elements", nameof(data));
for (int y = 0; y < data.Length; y++)
{
var line = data[y];
if (line.Length != 10)
throw new ArgumentException($"Lines must contain 10 elements. Line: {y + 1}", nameof(data));
for (int x = 0; x < line.Length; x++)
{
dataPart1[x + y * 10] = byte.Parse(line.Substring(x, 1));
}
}
dataPart2 = new byte[10 * 10];
Array.Copy(dataPart1, dataPart2, dataPart1.Length);
}
public override void CalculatePart1()
{
Part1 = Run(ref dataPart1, 100, out _);
}
public override void CalculatePart2()
{
Run(ref dataPart2, 210, out var fullFlash);
Part2 = fullFlash;
}
public IEnumerator<byte> GetEnumerator()
{
return ((IEnumerable<byte>)dataPart1).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return dataPart1.GetEnumerator();
}
public int Run(ref byte[] data, int count, out int fullFlash)
{
var flashes = 0;
fullFlash = 0;
for (int i = 0; i < count; i++)
{
var start = flashes;
Run(ref data, ref flashes);
if (flashes - start == 100)
{
fullFlash = i + 1;
break;
}
}
return flashes;
}
public void Run(ref byte[] data, ref int flashes)
{
Increment(ref data);
Flash(ref data, ref flashes);
}
private static void Increment(ref byte[] data)
{
for (int i = 0; i < data.Length; i++)
data[i]++;
}
private void Flash(ref byte[] data, ref int flashes)
{
int diff;
do
{
var startFlash = flashes;
for (int i = 0; i < data.Length; i++)
{
if (data[i] > 9)
PerformFlash(ref data, i, ref flashes);
}
diff = flashes - startFlash;
} while (diff != 0);
}
private void PerformFlash(ref byte[] data, int index, ref int flashes)
{
flashes++;
var y = index / 10;
var x = index % 10;
data[index] = 0;
if (x > 0)
{
//Left
index = x - 1 + y * 10;
if (index >= 0 && data[index] != 0)
data[index]++;
}
if (x < 9)
{
//Right
index = x + 1 + y * 10;
if (index < data.Length && data[index] != 0)
data[index]++;
}
if (y > 0)
{
//Up
index = x + 0 + (y - 1) * 10;
if (index >= 0 && data[index] != 0)
data[index]++;
if (x > 0)
{
//Up Left
index = x - 1 + (y - 1) * 10;
if (index >= 0 && data[index] != 0)
data[index]++;
}
if (x < 9)
{
//Up Right
index = x + 1 + (y - 1) * 10;
if (index < data.Length && data[index] != 0)
data[index]++;
}
}
if (y < 9)
{
//Bottom
index = x + 0 + (y + 1) * 10;
if (index < data.Length && data[index] != 0)
data[index]++;
if (x > 0)
{
//Bottom Left
index = x - 1 + (y + 1) * 10;
if (index < data.Length && data[index] != 0)
data[index]++;
}
if (x < 9)
{
//Bottom Right
index = x + 1 + (y + 1) * 10;
if (index < data.Length && data[index] != 0)
data[index]++;
}
}
}
//public override string ToString()
//{
// var output = new StringBuilder();
// for (int y = 0; y < 10; y++)
// {
// for (int x = 0; x < 10; x++)
// {
// output.Append(DataPart1[x + y * 10]);
// }
// output.AppendLine();
// }
// return output.ToString();
//}
//public void Render()
//{
// for (int y = 0; y < 10; y++)
// {
// for (int x = 0; x < 10; x++)
// {
// var index = x + y * 10;
// if (DataPart1[index] == 0)
// Console.ForegroundColor = ConsoleColor.Magenta;
// else
// Console.ForegroundColor = ConsoleColor.White;
// Console.Write(DataPart1[index]);
// }
// Console.WriteLine();
// }
//}
}

View File

@@ -0,0 +1,10 @@
6318185732
1122687135
5173237676
8754362612
5718474666
8443654137
1247634346
1446514585
6717288267
1727871228

View File

@@ -0,0 +1,10 @@
1111111111
1111111111
1111111111
1111111111
1111111111
1111111119
1111111111
1111111111
1111111111
1111111119

View File

@@ -0,0 +1,78 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2021.Day3;
[ProblemInfo(2021, 3, "Binary Diagnostic")]
public class BinaryDiagnostic : Problem<int, int>
{
public int[][] Data { get; set; } = Array.Empty<int[]>();
private static int ToDecimal(int[] value)
{
return (int)value.Select((b, idx) => b * Math.Pow(2, value.Length - idx - 1)).Sum();
}
public override void LoadInput()
{
var data = ReadInputLines();
Data = data.Select(line => line.Select(b => int.Parse(b.ToString())).ToArray()).ToArray();
}
public override void CalculatePart1()
{
var width = Data[0].Length;
var transposed = Enumerable.Range(0, width).Select(idx => Data.Select(row => row[idx]));
var transposed2 = new int[width][];
for (int i = 0; i < width; i++)
{
transposed2[i] = Data.Select(row => row[i]).ToArray();
}
var mid = Data.Length / 2;
var gamma = transposed.Select(col => col.Count(c => c == 1) > mid ? 1 : 0).ToArray();
var epsilon = gamma.Select(b => b == 0 ? 1 : 0).ToArray();
var gammaDec = ToDecimal(gamma);
var epsilongDec = ToDecimal(epsilon);
Part1 = gammaDec * epsilongDec;
}
public override void CalculatePart2()
{
var oxygen = Data;
var index = 0;
while (oxygen.Length > 1)
{
var t = oxygen.Select(row => row[index]);
var m = oxygen.Length / 2f;
var g = t.Count(c => c == 1) >= m ? 1 : 0;
oxygen = oxygen.Where(row => row[index] == g).ToArray();
index++;
}
var carbon = Data;
index = 0;
while (carbon.Length > 1)
{
var t = carbon.Select(row => row[index]);
var m = carbon.Length / 2f;
var e = t.Count(c => c == 1) < m ? 1 : 0;
carbon = carbon.Where(row => row[index] == e).ToArray();
index++;
}
var oxygenLevel = ToDecimal(oxygen.First());
var carbonLevel = ToDecimal(carbon.First());
Part2 = oxygenLevel * carbonLevel;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

View File

@@ -0,0 +1,60 @@
using AdventOfCode.Runner.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2021.Day6;
[ProblemInfo(2021, 6, "Lanternfish")]
internal class LanternFish : Problem<long, long>
{
public int[] Data { get; private set; } = Array.Empty<int>();
public override void LoadInput()
{
var input = ReadInputLines();
Data = input.First().Split(",").Select(v => int.Parse(v)).ToArray();
}
public override void CalculatePart1()
{
var lifetimes = PrepareLifetimes();
Part1 = Simulate(lifetimes, 80);
}
public override void CalculatePart2()
{
var lifetimes = PrepareLifetimes();
Part2 = Simulate(lifetimes, 256);
}
private long[] PrepareLifetimes()
{
var lifetimes = new long[9];
foreach (var life in Data)
lifetimes[life] += 1;
return lifetimes;
}
private static long Simulate(long[] lifetimes, int days)
{
for (int i = 0; i < days; i++)
{
var day0Count = lifetimes[0];
for (int j = 1; j < lifetimes.Length; j++)
lifetimes[j - 1] = lifetimes[j];
lifetimes[6] += day0Count;
lifetimes[^1] = day0Count;
}
return lifetimes.Sum();
}
}

View File

@@ -0,0 +1 @@
1,3,4,1,1,1,1,1,1,1,1,2,2,1,4,2,4,1,1,1,1,1,5,4,1,1,2,1,1,1,1,4,1,1,1,4,4,1,1,1,1,1,1,1,2,4,1,3,1,1,2,1,2,1,1,4,1,1,1,4,3,1,3,1,5,1,1,3,4,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,5,2,5,5,3,2,1,5,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,5,1,1,1,1,5,1,1,1,1,1,4,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,3,1,2,4,1,5,5,1,1,5,3,4,4,4,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,5,3,1,4,1,1,2,2,1,2,2,5,1,1,1,2,1,1,1,1,3,4,5,1,2,1,1,1,1,1,5,2,1,1,1,1,1,1,5,1,1,1,1,1,1,1,5,1,4,1,5,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,5,4,5,1,1,1,1,1,1,1,5,1,1,3,1,1,1,3,1,4,2,1,5,1,3,5,5,2,1,3,1,1,1,1,1,3,1,3,1,1,2,4,3,1,4,2,2,1,1,1,1,1,1,1,5,2,1,1,1,2

View File

@@ -0,0 +1 @@
3,4,3,1,2

View File

@@ -2,7 +2,7 @@
using AdventOfCode.Runner.Attributes; using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2022.Day0; namespace AdventOfCode.Problems.AOC2022.Day0;
[ProblemInfo("2022", 0, "Fancy Test")] [ProblemInfo(2022, 0, "Fancy Test")]
public class TestProblem : Problem public class TestProblem : Problem
{ {
public override void LoadInput() public override void LoadInput()

View File

@@ -8,7 +8,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2022.Day1; namespace AdventOfCode.Problems.AOC2022.Day1;
[ProblemInfo("2022", 1, "Calorie Counting")] [ProblemInfo(2022, 1, "Calorie Counting")]
internal class CalorieCounting : Problem internal class CalorieCounting : Problem
{ {
public List<List<int>> FlaresFood { get; set; } public List<List<int>> FlaresFood { get; set; }

View File

@@ -3,7 +3,7 @@ using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2022.Day2; namespace AdventOfCode.Problems.AOC2022.Day2;
[ProblemInfo("2022", 2, "Rock Paper Scissors")] [ProblemInfo(2022, 2, "Rock Paper Scissors")]
internal class RockPaperScissors : Problem internal class RockPaperScissors : Problem
{ {
private string[] _lines; private string[] _lines;

View File

@@ -8,7 +8,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AdventOfCode.Problems.AOC2022.Day3; namespace AdventOfCode.Problems.AOC2022.Day3;
[ProblemInfo("2022", 3, "Rucksack Reorganization")] [ProblemInfo(2022, 3, "Rucksack Reorganization")]
internal class RucksackReorganization : Problem internal class RucksackReorganization : Problem
{ {
private string[] _sacks; private string[] _sacks;

View File

@@ -2,7 +2,7 @@
using AdventOfCode.Runner.Attributes; using AdventOfCode.Runner.Attributes;
namespace AdventOfCode.Problems.AOC2023.Day0; namespace AdventOfCode.Problems.AOC2023.Day0;
[ProblemInfo("2023", 0, "Test")] [ProblemInfo(2023, 0, "Test")]
public class TestProblem : Problem public class TestProblem : Problem
{ {
public override void LoadInput() public override void LoadInput()

View File

@@ -1,4 +1,5 @@
using AdventOfCode.Runner; 
global using AdventOfCode.Runner;
namespace AdventOfCode; namespace AdventOfCode;

View File

@@ -8,12 +8,13 @@ namespace AdventOfCode.Runner;
public class AOCRunner public class AOCRunner
{ {
private Dictionary<string, List<(ProblemInfoAttribute info, Type type)>> _loadedProblems; private Dictionary<int, List<(ProblemInfoAttribute info, Type type)>> _loadedProblems;
private List<string> _years; private List<int> _years;
private string _selectedYear; private int _selectedYear;
private int _selectedDay; private int _selectedDay;
private int _scollOffset = 0; private int _scollOffset = 0;
private int _maxProblemCount; private int _maxProblemCount;
private bool _isQuiting;
private bool _isProblemMode = false; private bool _isProblemMode = false;
@@ -21,8 +22,8 @@ public class AOCRunner
{ {
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
_loadedProblems = new(); _loadedProblems = new();
_years = new List<string>(); _years = new List<int>();
_selectedYear = DateTime.Now.Year.ToString(); _selectedYear = DateTime.Now.Year;
FindProblemClasses(); FindProblemClasses();
InitSizing(); InitSizing();
@@ -50,7 +51,7 @@ public class AOCRunner
private void FindProblemClasses() private void FindProblemClasses()
{ {
var types = Assembly.GetExecutingAssembly().DefinedTypes.Where(t => t.IsAssignableTo(typeof(Problem)) && !t.IsInterface); var types = Assembly.GetExecutingAssembly().DefinedTypes.Where(t => !t.IsAbstract);
if (types == null) if (types == null)
return; return;
foreach (var type in types) foreach (var type in types)
@@ -68,7 +69,7 @@ public class AOCRunner
_years = _loadedProblems.Keys.OrderDescending().ToList(); _years = _loadedProblems.Keys.OrderDescending().ToList();
} }
private void RunDay(string year, int dayIndex) private void RunDay(int year, int dayIndex)
{ {
var yearList = _loadedProblems[year]; var yearList = _loadedProblems[year];
if (yearList.Count <= dayIndex || dayIndex < 0) if (yearList.Count <= dayIndex || dayIndex < 0)
@@ -84,7 +85,7 @@ public class AOCRunner
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
if (Activator.CreateInstance(problemType) is not Problem problem) if (Activator.CreateInstance(problemType) is not IProblem problem)
{ {
Console.WriteLine("Failed to create problem isntance"); Console.WriteLine("Failed to create problem isntance");
return; return;
@@ -122,6 +123,11 @@ public class AOCRunner
Console.ForegroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine($"{sw.ElapsedMilliseconds}ms"); Console.WriteLine($"{sw.ElapsedMilliseconds}ms");
} }
catch (NotImplementedException)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Not Implemented");
}
catch (Exception e) catch (Exception e)
{ {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
@@ -141,7 +147,7 @@ public class AOCRunner
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
Console.CursorVisible = false; Console.CursorVisible = false;
Console.Clear(); Console.Clear();
while (true) while (!_isQuiting)
{ {
InitSizing(); InitSizing();
RenderTopBar(); RenderTopBar();
@@ -205,6 +211,9 @@ public class AOCRunner
case ConsoleKey.Enter: case ConsoleKey.Enter:
_isProblemMode = true; _isProblemMode = true;
break; break;
case ConsoleKey.Escape:
_isQuiting = true;
break;
} }
ConstrainListScroll(); ConstrainListScroll();
} }
@@ -232,9 +241,9 @@ public class AOCRunner
if (end >= tabMaxPos) if (end >= tabMaxPos)
break; break;
if(year == _selectedYear) if(year == _selectedYear)
DrawSelectedButton(year, 2, col, buttonWidth, 1, ConsoleColor.Red, ConsoleColor.Blue); DrawSelectedButton(year.ToString(), 2, col, buttonWidth, 1, ConsoleColor.Red, ConsoleColor.Blue);
else else
DrawButton(year, 2, col, buttonWidth, 1, ConsoleColor.Gray, Console.BackgroundColor); DrawButton(year.ToString(), 2, col, buttonWidth, 1, ConsoleColor.Gray, Console.BackgroundColor);
} }
@@ -290,7 +299,6 @@ public class AOCRunner
private void DrawSelectedButton(string text, int row, int col, int width, int height, ConsoleColor color = ConsoleColor.Gray, ConsoleColor background = ConsoleColor.Black, bool centered = true, int padding = 0) private void DrawSelectedButton(string text, int row, int col, int width, int height, ConsoleColor color = ConsoleColor.Gray, ConsoleColor background = ConsoleColor.Black, bool centered = true, int padding = 0)
{ {
//text = $"\ue0c7{text}\ue0c6"; //text = $"\ue0c7{text}\ue0c6";
Console.SetCursorPosition(row, col);
var origBg = Console.BackgroundColor; var origBg = Console.BackgroundColor;
Console.BackgroundColor = background; Console.BackgroundColor = background;
for (int y = row; y < row + height; y++) for (int y = row; y < row + height; y++)
@@ -318,7 +326,6 @@ public class AOCRunner
private void DrawButton(string text, int row, int col, int width, int height, ConsoleColor color = ConsoleColor.Gray, ConsoleColor background = ConsoleColor.Black, bool centered = true, int padding = 0) private void DrawButton(string text, int row, int col, int width, int height, ConsoleColor color = ConsoleColor.Gray, ConsoleColor background = ConsoleColor.Black, bool centered = true, int padding = 0)
{ {
Console.SetCursorPosition(row, col);
var origBg = Console.BackgroundColor; var origBg = Console.BackgroundColor;
Console.BackgroundColor = background; Console.BackgroundColor = background;
for (int y = row; y < row + height; y++) for (int y = row; y < row + height; y++)

View File

@@ -2,9 +2,9 @@
public class ProblemInfoAttribute : Attribute public class ProblemInfoAttribute : Attribute
{ {
public int Day { get; init; } public int Day { get; init; }
public string Year { get; init; } public int Year { get; init; }
public string Name { get; init; } public string Name { get; init; }
public ProblemInfoAttribute(string year, int day, string name) public ProblemInfoAttribute(int year, int day, string name)
{ {
Year = year; Year = year;
Day = day; Day = day;

View File

@@ -4,16 +4,34 @@ using System.Reflection;
namespace AdventOfCode.Runner; namespace AdventOfCode.Runner;
public abstract class Problem public interface IProblem
{ {
protected string? Part1 { get; set; } void LoadInput();
protected string? Part2 { get; set; }
void CalculatePart1();
void PrintPart1();
void CalculatePart2();
void PrintPart2();
}
public abstract class Problem : Problem<string, string>
{
}
public abstract class Problem<TPart1, TPart2> : IProblem
{
protected TPart1? Part1 { get; set; }
protected TPart2? Part2 { get; set; }
public abstract void LoadInput(); public abstract void LoadInput();
public abstract void CalculatePart1(); public abstract void CalculatePart1();
public virtual void PrintPart1() { public virtual void PrintPart1()
{
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
if (Part1 == null) if (Part1 == null)
{ {