Updates to Runner
Added Previous years of AOC
This commit is contained in:
@@ -14,10 +14,24 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Problems\*\*\*.csv">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Problems\AOC2022\Day3\input.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>
|
||||
|
||||
</Project>
|
||||
|
||||
62
AdventOfCode/Problems/AOC2015/Day10/LookAndSay.cs
Normal file
62
AdventOfCode/Problems/AOC2015/Day10/LookAndSay.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
109
AdventOfCode/Problems/AOC2015/Day5/NiceList.cs
Normal file
109
AdventOfCode/Problems/AOC2015/Day5/NiceList.cs
Normal 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
|
||||
};
|
||||
}
|
||||
}
|
||||
1000
AdventOfCode/Problems/AOC2015/Day5/input.txt
Normal file
1000
AdventOfCode/Problems/AOC2015/Day5/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
48
AdventOfCode/Problems/AOC2019/Day1/FuelCaluclation.cs
Normal file
48
AdventOfCode/Problems/AOC2019/Day1/FuelCaluclation.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
100
AdventOfCode/Problems/AOC2019/Day1/input.txt
Normal file
100
AdventOfCode/Problems/AOC2019/Day1/input.txt
Normal 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
|
||||
72
AdventOfCode/Problems/AOC2019/Day2/IntCode.cs
Normal file
72
AdventOfCode/Problems/AOC2019/Day2/IntCode.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
AdventOfCode/Problems/AOC2019/Day2/input.csv
Normal file
1
AdventOfCode/Problems/AOC2019/Day2/input.csv
Normal 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
|
||||
|
328
AdventOfCode/Problems/AOC2019/Day3/CrossedWires.cs
Normal file
328
AdventOfCode/Problems/AOC2019/Day3/CrossedWires.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
AdventOfCode/Problems/AOC2019/Day3/input.txt
Normal file
2
AdventOfCode/Problems/AOC2019/Day3/input.txt
Normal 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
|
||||
157
AdventOfCode/Problems/AOC2019/Day4/SecureContainer.cs
Normal file
157
AdventOfCode/Problems/AOC2019/Day4/SecureContainer.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
36
AdventOfCode/Problems/AOC2019/Day5/ChanceOfAsteroids.cs
Normal file
36
AdventOfCode/Problems/AOC2019/Day5/ChanceOfAsteroids.cs
Normal 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"));
|
||||
}
|
||||
}
|
||||
240
AdventOfCode/Problems/AOC2019/Day5/IntCodeV2.cs
Normal file
240
AdventOfCode/Problems/AOC2019/Day5/IntCodeV2.cs
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
1
AdventOfCode/Problems/AOC2019/Day5/input.csv
Normal file
1
AdventOfCode/Problems/AOC2019/Day5/input.csv
Normal 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
|
||||
|
119
AdventOfCode/Problems/AOC2019/Day6/OrbitMap.cs
Normal file
119
AdventOfCode/Problems/AOC2019/Day6/OrbitMap.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
60
AdventOfCode/Problems/AOC2019/Day6/UniversalOrbits.cs
Normal file
60
AdventOfCode/Problems/AOC2019/Day6/UniversalOrbits.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
1799
AdventOfCode/Problems/AOC2019/Day6/input.txt
Normal file
1799
AdventOfCode/Problems/AOC2019/Day6/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
13
AdventOfCode/Problems/AOC2019/Day6/test.txt
Normal file
13
AdventOfCode/Problems/AOC2019/Day6/test.txt
Normal 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
|
||||
161
AdventOfCode/Problems/AOC2019/Day7/AmplificationCircuit.cs
Normal file
161
AdventOfCode/Problems/AOC2019/Day7/AmplificationCircuit.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
AdventOfCode/Problems/AOC2019/Day7/input.csv
Normal file
1
AdventOfCode/Problems/AOC2019/Day7/input.csv
Normal 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
|
||||
|
91
AdventOfCode/Problems/AOC2019/Day8/SpaceImageFormat.cs
Normal file
91
AdventOfCode/Problems/AOC2019/Day8/SpaceImageFormat.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
AdventOfCode/Problems/AOC2019/Day8/input.txt
Normal file
1
AdventOfCode/Problems/AOC2019/Day8/input.txt
Normal file
File diff suppressed because one or more lines are too long
37
AdventOfCode/Problems/AOC2019/InputParsing.cs
Normal file
37
AdventOfCode/Problems/AOC2019/InputParsing.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
200
AdventOfCode/Problems/AOC2021/Day11/DumboOctopus.cs
Normal file
200
AdventOfCode/Problems/AOC2021/Day11/DumboOctopus.cs
Normal 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();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
10
AdventOfCode/Problems/AOC2021/Day11/input.txt
Normal file
10
AdventOfCode/Problems/AOC2021/Day11/input.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
6318185732
|
||||
1122687135
|
||||
5173237676
|
||||
8754362612
|
||||
5718474666
|
||||
8443654137
|
||||
1247634346
|
||||
1446514585
|
||||
6717288267
|
||||
1727871228
|
||||
10
AdventOfCode/Problems/AOC2021/Day11/input2.txt
Normal file
10
AdventOfCode/Problems/AOC2021/Day11/input2.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
1111111111
|
||||
1111111111
|
||||
1111111111
|
||||
1111111111
|
||||
1111111111
|
||||
1111111119
|
||||
1111111111
|
||||
1111111111
|
||||
1111111111
|
||||
1111111119
|
||||
78
AdventOfCode/Problems/AOC2021/Day3/BinaryDiagnostic.cs
Normal file
78
AdventOfCode/Problems/AOC2021/Day3/BinaryDiagnostic.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
1000
AdventOfCode/Problems/AOC2021/Day3/Input.txt
Normal file
1000
AdventOfCode/Problems/AOC2021/Day3/Input.txt
Normal file
File diff suppressed because it is too large
Load Diff
1000
AdventOfCode/Problems/AOC2021/Day3/sara.txt
Normal file
1000
AdventOfCode/Problems/AOC2021/Day3/sara.txt
Normal file
File diff suppressed because it is too large
Load Diff
12
AdventOfCode/Problems/AOC2021/Day3/test.txt
Normal file
12
AdventOfCode/Problems/AOC2021/Day3/test.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
00100
|
||||
11110
|
||||
10110
|
||||
10111
|
||||
10101
|
||||
01111
|
||||
00111
|
||||
11100
|
||||
10000
|
||||
11001
|
||||
00010
|
||||
01010
|
||||
60
AdventOfCode/Problems/AOC2021/Day6/LanternFish.cs
Normal file
60
AdventOfCode/Problems/AOC2021/Day6/LanternFish.cs
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
1
AdventOfCode/Problems/AOC2021/Day6/input.txt
Normal file
1
AdventOfCode/Problems/AOC2021/Day6/input.txt
Normal 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
|
||||
1
AdventOfCode/Problems/AOC2021/Day6/test.txt
Normal file
1
AdventOfCode/Problems/AOC2021/Day6/test.txt
Normal file
@@ -0,0 +1 @@
|
||||
3,4,3,1,2
|
||||
@@ -2,7 +2,7 @@
|
||||
using AdventOfCode.Runner.Attributes;
|
||||
|
||||
namespace AdventOfCode.Problems.AOC2022.Day0;
|
||||
[ProblemInfo("2022", 0, "Fancy Test")]
|
||||
[ProblemInfo(2022, 0, "Fancy Test")]
|
||||
public class TestProblem : Problem
|
||||
{
|
||||
public override void LoadInput()
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AdventOfCode.Problems.AOC2022.Day1;
|
||||
[ProblemInfo("2022", 1, "Calorie Counting")]
|
||||
[ProblemInfo(2022, 1, "Calorie Counting")]
|
||||
internal class CalorieCounting : Problem
|
||||
{
|
||||
public List<List<int>> FlaresFood { get; set; }
|
||||
|
||||
@@ -3,7 +3,7 @@ using AdventOfCode.Runner.Attributes;
|
||||
|
||||
namespace AdventOfCode.Problems.AOC2022.Day2;
|
||||
|
||||
[ProblemInfo("2022", 2, "Rock Paper Scissors")]
|
||||
[ProblemInfo(2022, 2, "Rock Paper Scissors")]
|
||||
internal class RockPaperScissors : Problem
|
||||
{
|
||||
private string[] _lines;
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AdventOfCode.Problems.AOC2022.Day3;
|
||||
[ProblemInfo("2022", 3, "Rucksack Reorganization")]
|
||||
[ProblemInfo(2022, 3, "Rucksack Reorganization")]
|
||||
internal class RucksackReorganization : Problem
|
||||
{
|
||||
private string[] _sacks;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using AdventOfCode.Runner.Attributes;
|
||||
|
||||
namespace AdventOfCode.Problems.AOC2023.Day0;
|
||||
[ProblemInfo("2023", 0, "Test")]
|
||||
[ProblemInfo(2023, 0, "Test")]
|
||||
public class TestProblem : Problem
|
||||
{
|
||||
public override void LoadInput()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AdventOfCode.Runner;
|
||||
|
||||
global using AdventOfCode.Runner;
|
||||
|
||||
namespace AdventOfCode;
|
||||
|
||||
|
||||
@@ -8,12 +8,13 @@ namespace AdventOfCode.Runner;
|
||||
|
||||
public class AOCRunner
|
||||
{
|
||||
private Dictionary<string, List<(ProblemInfoAttribute info, Type type)>> _loadedProblems;
|
||||
private List<string> _years;
|
||||
private string _selectedYear;
|
||||
private Dictionary<int, List<(ProblemInfoAttribute info, Type type)>> _loadedProblems;
|
||||
private List<int> _years;
|
||||
private int _selectedYear;
|
||||
private int _selectedDay;
|
||||
private int _scollOffset = 0;
|
||||
private int _maxProblemCount;
|
||||
private bool _isQuiting;
|
||||
|
||||
private bool _isProblemMode = false;
|
||||
|
||||
@@ -21,8 +22,8 @@ public class AOCRunner
|
||||
{
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
_loadedProblems = new();
|
||||
_years = new List<string>();
|
||||
_selectedYear = DateTime.Now.Year.ToString();
|
||||
_years = new List<int>();
|
||||
_selectedYear = DateTime.Now.Year;
|
||||
FindProblemClasses();
|
||||
|
||||
InitSizing();
|
||||
@@ -50,7 +51,7 @@ public class AOCRunner
|
||||
|
||||
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)
|
||||
return;
|
||||
foreach (var type in types)
|
||||
@@ -68,7 +69,7 @@ public class AOCRunner
|
||||
_years = _loadedProblems.Keys.OrderDescending().ToList();
|
||||
}
|
||||
|
||||
private void RunDay(string year, int dayIndex)
|
||||
private void RunDay(int year, int dayIndex)
|
||||
{
|
||||
var yearList = _loadedProblems[year];
|
||||
if (yearList.Count <= dayIndex || dayIndex < 0)
|
||||
@@ -84,7 +85,7 @@ public class AOCRunner
|
||||
|
||||
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");
|
||||
return;
|
||||
@@ -122,6 +123,11 @@ public class AOCRunner
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine($"{sw.ElapsedMilliseconds}ms");
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Not Implemented");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
@@ -141,7 +147,7 @@ public class AOCRunner
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Console.CursorVisible = false;
|
||||
Console.Clear();
|
||||
while (true)
|
||||
while (!_isQuiting)
|
||||
{
|
||||
InitSizing();
|
||||
RenderTopBar();
|
||||
@@ -205,6 +211,9 @@ public class AOCRunner
|
||||
case ConsoleKey.Enter:
|
||||
_isProblemMode = true;
|
||||
break;
|
||||
case ConsoleKey.Escape:
|
||||
_isQuiting = true;
|
||||
break;
|
||||
}
|
||||
ConstrainListScroll();
|
||||
}
|
||||
@@ -232,9 +241,9 @@ public class AOCRunner
|
||||
if (end >= tabMaxPos)
|
||||
break;
|
||||
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
|
||||
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)
|
||||
{
|
||||
//text = $"\ue0c7{text}\ue0c6";
|
||||
Console.SetCursorPosition(row, col);
|
||||
var origBg = Console.BackgroundColor;
|
||||
Console.BackgroundColor = background;
|
||||
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)
|
||||
{
|
||||
Console.SetCursorPosition(row, col);
|
||||
var origBg = Console.BackgroundColor;
|
||||
Console.BackgroundColor = background;
|
||||
for (int y = row; y < row + height; y++)
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
public class ProblemInfoAttribute : Attribute
|
||||
{
|
||||
public int Day { get; init; }
|
||||
public string Year { get; init; }
|
||||
public int Year { 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;
|
||||
Day = day;
|
||||
|
||||
@@ -4,16 +4,34 @@ using System.Reflection;
|
||||
|
||||
namespace AdventOfCode.Runner;
|
||||
|
||||
public abstract class Problem
|
||||
public interface IProblem
|
||||
{
|
||||
protected string? Part1 { get; set; }
|
||||
protected string? Part2 { get; set; }
|
||||
void LoadInput();
|
||||
|
||||
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 CalculatePart1();
|
||||
|
||||
public virtual void PrintPart1() {
|
||||
public virtual void PrintPart1()
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
if (Part1 == null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user