Compare commits
No commits in common. "70a86f783a2014d81bf3d3c1f45290482f97398f" and "6f4c1c0685147d2f1b6fd6afa7d4a590f331a7bb" have entirely different histories.
70a86f783a
...
6f4c1c0685
|
@ -4,8 +4,8 @@
|
||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
# AdventOfCode input files
|
# Rider configuration directory
|
||||||
inputs/
|
.idea/
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.rsuser
|
*.rsuser
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -1,6 +0,0 @@
|
||||||
.PHONY: build
|
|
||||||
|
|
||||||
build:
|
|
||||||
@dotnet build
|
|
||||||
@echo -e "\033c\nAdvent of Code\n\nBy: @TiagoRG\nGitHub: https://github.com/TiagoRG\n\n============================================================="
|
|
||||||
@dotnet run
|
|
|
@ -1,9 +1,9 @@
|
||||||
using AdventOfCode.Year2023;
|
using AdventOfCode.Year2022;
|
||||||
|
|
||||||
namespace AdventOfCode;
|
namespace AdventOfCode;
|
||||||
|
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
=> Loader2023.Load();
|
=> Loader2022.Load();
|
||||||
}
|
}
|
26
README.md
26
README.md
|
@ -1,25 +1,15 @@
|
||||||
# Advent of Code
|
# Advent of Code
|
||||||
|
|
||||||
## Solutions for the AoC Challenges, all in C#
|
## Solutions for the AoC Challenges, all in C#
|
||||||
|
|
||||||
### They might not be the best solutions but they work and that's the important part of a coders job :xdd:
|
### They might not be the best solutions but they work and that's the important part of a coders job :xdd:
|
||||||
|
|
||||||
## Solutions organized by year, 1 file per day.
|
## Solutions organized by year, 1 file per day.
|
||||||
|
|
||||||
### [2022](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022)
|
### [2022](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022)
|
||||||
|
* [Day 1](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day1.cs)
|
||||||
* [Day 1](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day1.cs)
|
* [Day 2](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day2.cs)
|
||||||
* [Day 2](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day2.cs)
|
* [Day 3](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day3.cs)
|
||||||
* [Day 3](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day3.cs)
|
* [Day 4](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day4.cs)
|
||||||
* [Day 4](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day4.cs)
|
* [Day 6](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day6.cs)
|
||||||
* [Day 6](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day6.cs)
|
* [Day 7](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day7.cs)
|
||||||
* [Day 7](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day7.cs)
|
* [Day 8](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day8.cs)
|
||||||
* [Day 8](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day8.cs)
|
* [Day 9](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day9.cs)
|
||||||
* [Day 9](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day9.cs)
|
|
||||||
* [Day 10](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day10.cs)
|
|
||||||
* [Day 11](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day11.cs)
|
|
||||||
* [Day 12](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day12.cs)
|
|
||||||
|
|
||||||
### [2023](https://github.com/TiagoRG/AdventOfCode/tree/main/Year2023)
|
|
||||||
|
|
||||||
* [Day 1](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2023/Day1.cs)
|
|
|
@ -3,7 +3,7 @@ namespace AdventOfCode.Utils.Extensions;
|
||||||
public static class LinqExtensions
|
public static class LinqExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a slice of the given list
|
/// Returns a slice of the given list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="list">The list you pretend to slice</param>
|
/// <param name="list">The list you pretend to slice</param>
|
||||||
/// <param name="startIndex">The first index of the slice</param>
|
/// <param name="startIndex">The first index of the slice</param>
|
||||||
|
@ -11,49 +11,49 @@ public static class LinqExtensions
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static List<T> Sublist<T>(this List<T> list, int startIndex, int endIndex = default)
|
public static List<T> Sublist<T>(this List<T> list, int startIndex, int endIndex = default)
|
||||||
{
|
{
|
||||||
var result = new List<T>();
|
List<T> result = new List<T>();
|
||||||
if (endIndex == default)
|
if (endIndex == default)
|
||||||
endIndex = list.Count;
|
endIndex = list.Count;
|
||||||
for (var i = startIndex; i < endIndex; i++)
|
for (int i = startIndex; i < endIndex; i++)
|
||||||
result.Add(list[i]);
|
result.Add(list[i]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a column of a give matrix list
|
/// Returns a column of a give matrix list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="list">2 dimensions list</param>
|
/// <param name="list">2 dimensions list</param>
|
||||||
/// <param name="column">Column index</param>
|
/// <param name="column">Column index</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static List<T> GetColumn<T>(this List<List<T>> list, int column)
|
public static List<T> GetColumn<T>(this List<List<T>> list, int column)
|
||||||
{
|
{
|
||||||
var result = new List<T>();
|
List<T> result = new List<T>();
|
||||||
foreach (var row in list) result.AddRange(row.Where((t, i) => i == column));
|
foreach (List<T> row in list) result.AddRange(row.Where((t, i) => i == column));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reverses a given list
|
/// Reverses a given list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="list">The list to reverse</param>
|
/// <param name="list">The list to reverse</param>
|
||||||
/// <returns>The reversed list</returns>
|
/// <returns>The reversed list</returns>
|
||||||
public static List<T> Reversed<T>(this List<T> list)
|
public static List<T> Reversed<T>(this List<T> list)
|
||||||
{
|
{
|
||||||
var reversed = new List<T>();
|
List<T> reversed = new List<T>();
|
||||||
for (var i = 0; i < list.Count; i++)
|
for (int i = 0; i < list.Count; i++)
|
||||||
reversed.Add(list[list.Count - 1 - i]);
|
reversed.Add(list[list.Count-1-i]);
|
||||||
return reversed;
|
return reversed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clones a list of elements
|
/// Clones a list of elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="original">The original list</param>
|
/// <param name="original">The original list</param>
|
||||||
/// <returns>A copy of the original list</returns>
|
/// <returns>A copy of the original list</returns>
|
||||||
public static List<T> Clone<T>(this List<T> original)
|
public static List<T> Clone<T>(this List<T> original)
|
||||||
{
|
{
|
||||||
var ret = new List<T>(original.Count);
|
List<T> ret = new List<T>(original.Count);
|
||||||
foreach (var element in original)
|
foreach (T element in original)
|
||||||
ret.Add(element);
|
ret.Add(element);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,9 @@ public static class LinqExtensions
|
||||||
where TValue : ICloneable
|
where TValue : ICloneable
|
||||||
where TKey : notnull
|
where TKey : notnull
|
||||||
{
|
{
|
||||||
var ret = new Dictionary<TKey, TValue>(original.Count, original.Comparer);
|
Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>(original.Count, original.Comparer);
|
||||||
foreach (var entry in original)
|
foreach (KeyValuePair<TKey, TValue> entry in original)
|
||||||
ret.Add(entry.Key, (TValue)entry.Value.Clone());
|
ret.Add(entry.Key, (TValue) entry.Value.Clone());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ public static class LinqExtensions
|
||||||
(this Dictionary<TKey, List<TValue>> original)
|
(this Dictionary<TKey, List<TValue>> original)
|
||||||
where TKey : notnull
|
where TKey : notnull
|
||||||
{
|
{
|
||||||
var ret = new Dictionary<TKey, List<TValue>>(original.Count, original.Comparer);
|
Dictionary<TKey, List<TValue>> ret = new Dictionary<TKey, List<TValue>>(original.Count, original.Comparer);
|
||||||
foreach (var entry in original)
|
foreach (KeyValuePair<TKey, List<TValue>> entry in original)
|
||||||
ret.Add(entry.Key, entry.Value.Clone());
|
ret.Add(entry.Key, entry.Value.Clone());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -82,20 +82,20 @@ public static class LinqExtensions
|
||||||
public static void Fill<T>(this List<T> list, int count, T element)
|
public static void Fill<T>(this List<T> list, int count, T element)
|
||||||
where T : ICloneable
|
where T : ICloneable
|
||||||
{
|
{
|
||||||
for (var i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
list.Add(element);
|
list.Add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fill<T>(this List<List<T>> list, int count, List<T> element)
|
public static void Fill<T>(this List<List<T>> list, int count, List<T> element)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
list.Add(element.Clone());
|
list.Add(element.Clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Set<T>(this List<T> list, int index, T element)
|
public static void Set<T>(this List<T> list, int index, T element)
|
||||||
{
|
{
|
||||||
var backup = list.Clone();
|
List<T> backup = list.Clone();
|
||||||
list.Clear();
|
list.Clear();
|
||||||
for (var i = 0; i < list.Count; i++) list.Add(i == index ? element : list[i]);
|
for (int i = 0; i < list.Count; i++) list.Add(i == index ? element : list[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@ public static class MathExtensions
|
||||||
{
|
{
|
||||||
Convert.ToInt32(s);
|
Convert.ToInt32(s);
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
catch (FormatException ignored)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -28,32 +28,30 @@ public static class MathExtensions
|
||||||
|
|
||||||
public static ulong ProductOfMax(this List<ulong> list, int maxCount)
|
public static ulong ProductOfMax(this List<ulong> list, int maxCount)
|
||||||
{
|
{
|
||||||
var maxList = new List<ulong>(maxCount);
|
List<ulong> maxList = new List<ulong>(maxCount);
|
||||||
|
|
||||||
foreach (var number in list)
|
foreach (ulong number in list)
|
||||||
{
|
{
|
||||||
if (maxList.Count < maxList.Capacity)
|
if (maxList.Count < maxList.Capacity)
|
||||||
{
|
|
||||||
maxList.Add(number);
|
maxList.Add(number);
|
||||||
}
|
else
|
||||||
else if (number > maxList.Min())
|
if (number > maxList.Min())
|
||||||
{
|
{
|
||||||
maxList.RemoveAt(0);
|
maxList.RemoveAt(0);
|
||||||
maxList.Add(number);
|
maxList.Add(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxList.Sort();
|
maxList.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong product = 1;
|
ulong product = 1;
|
||||||
maxList.ForEach(n => product *= n);
|
maxList.ForEach(n => product*=n);
|
||||||
return product;
|
return product;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int LeastCommonMultiplier(this List<int> list)
|
public static int LeastCommonMultiplier(this List<int> list)
|
||||||
{
|
{
|
||||||
var lcm = 1;
|
int lcm = 1;
|
||||||
foreach (var i in list)
|
foreach (int i in list)
|
||||||
lcm *= i / MathTools.GreatCommonDivider(lcm, i);
|
lcm *= i / MathTools.GreatCommonDivider(lcm, i);
|
||||||
return lcm;
|
return lcm;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,10 @@ public class Day1
|
||||||
|
|
||||||
public Day1()
|
public Day1()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("\nDay1 Solution");
|
||||||
Day1 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
|
@ -21,21 +19,30 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static int Part2()
|
private static int Part2()
|
||||||
{
|
{
|
||||||
return CaloriesPerElf.Order().Reverse().ToArray()[..3].Sum();
|
List<int> top3 = new List<int>();
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
top3.Add(CaloriesPerElf.Max());
|
||||||
|
CaloriesPerElf.Remove(CaloriesPerElf.Max());
|
||||||
|
}
|
||||||
|
|
||||||
|
return top3.Sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<int> GetCaloriesPerElf()
|
private static List<int> GetCaloriesPerElf()
|
||||||
{
|
{
|
||||||
var calories = File.ReadAllLines("inputs/day1.txt");
|
string[] calories = File.ReadAllLines("inputs/day1.txt");
|
||||||
var caloriesPerDay = new int[calories.Length];
|
int[] caloriesPerDay = new int[calories.Length];
|
||||||
var index = 0;
|
var index = 0;
|
||||||
foreach (var calorie in calories)
|
foreach (string calorie in calories)
|
||||||
|
{
|
||||||
if (calorie == "")
|
if (calorie == "")
|
||||||
index++;
|
index++;
|
||||||
else
|
else
|
||||||
caloriesPerDay[index] += Convert.ToInt32(calorie);
|
caloriesPerDay[index] += Convert.ToInt32(calorie);
|
||||||
|
}
|
||||||
|
|
||||||
var elfCount = caloriesPerDay.ToList().IndexOf(0);
|
int elfCount = caloriesPerDay.ToList().IndexOf(0);
|
||||||
return caloriesPerDay.ToList().GetRange(0, elfCount);
|
return caloriesPerDay.ToList().GetRange(0, elfCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,43 +1,42 @@
|
||||||
|
using AdventOfCode.Utils;
|
||||||
|
|
||||||
namespace AdventOfCode.Year2022;
|
namespace AdventOfCode.Year2022;
|
||||||
|
|
||||||
public class Day10
|
public class Day10
|
||||||
{
|
{
|
||||||
private static readonly List<string> CommandsList = new();
|
private static readonly List<string> CommandsList = new();
|
||||||
|
|
||||||
public Day10()
|
public Day10()
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("Day10 Solution");
|
||||||
File.ReadAllLines("inputs/day10.txt").ToList().ForEach(line => CommandsList.Add(line));
|
File.ReadAllLines("inputs/day10.txt").ToList().ForEach(line => CommandsList.Add(line));
|
||||||
Console.WriteLine($@"
|
|
||||||
Day10 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
{
|
{
|
||||||
var sum = 0;
|
int sum = 0;
|
||||||
var currentPower = 1;
|
int currentPower = 1;
|
||||||
|
|
||||||
var listIndex = 0;
|
int listIndex = 0;
|
||||||
var addPower = 0;
|
int addPower = 0;
|
||||||
var skipCycles = 0;
|
int skipCycles = 0;
|
||||||
|
|
||||||
for (var cycle = 1; cycle <= 220; cycle++)
|
for (int cycle = 1; cycle <= 220; cycle++)
|
||||||
{
|
{
|
||||||
if (skipCycles == 0)
|
if (skipCycles == 0)
|
||||||
{
|
{
|
||||||
currentPower += addPower;
|
currentPower += addPower;
|
||||||
var line = CommandsList[listIndex];
|
string line = CommandsList[listIndex];
|
||||||
var cmd = line.Substring(0, 4);
|
string cmd = line.Substring(0, 4);
|
||||||
skipCycles = cmd == "noop" ? 0 : 1;
|
skipCycles = cmd == "noop" ? 0 : 1;
|
||||||
addPower = cmd == "noop" ? 0 : Convert.ToInt32(line.Split(" ")[1]);
|
addPower = cmd == "noop" ? 0 : Convert.ToInt32(line.Split(" ")[1]);
|
||||||
listIndex++;
|
listIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
skipCycles--;
|
skipCycles--;
|
||||||
}
|
|
||||||
|
|
||||||
if ((cycle - 20) % 40 == 0)
|
if ((cycle - 20) % 40 == 0)
|
||||||
sum += currentPower * cycle;
|
sum += currentPower * cycle;
|
||||||
|
@ -48,39 +47,37 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static string Part2()
|
private static string Part2()
|
||||||
{
|
{
|
||||||
var crt = new char[40 * 6];
|
char[] crt = new char[40*6];
|
||||||
var registerPos = 0;
|
int registerPos = 0;
|
||||||
|
|
||||||
var listIndex = 0;
|
int listIndex = 0;
|
||||||
var movePos = 0;
|
int movePos = 0;
|
||||||
var skipCycles = 0;
|
int skipCycles = 0;
|
||||||
|
|
||||||
for (var cycle = 0; cycle < 240; cycle++)
|
for (int cycle = 0; cycle < 240; cycle++)
|
||||||
{
|
{
|
||||||
if (skipCycles == 0)
|
if (skipCycles == 0)
|
||||||
{
|
{
|
||||||
registerPos += movePos;
|
registerPos += movePos;
|
||||||
var line = CommandsList[listIndex];
|
string line = CommandsList[listIndex];
|
||||||
var cmd = line[..4];
|
string cmd = line[..4];
|
||||||
skipCycles = cmd == "noop" ? 0 : 1;
|
skipCycles = cmd == "noop" ? 0 : 1;
|
||||||
movePos = cmd == "noop" ? 0 : Convert.ToInt32(line.Split(" ")[1]);
|
movePos = cmd == "noop" ? 0 : Convert.ToInt32(line.Split(" ")[1]);
|
||||||
listIndex++;
|
listIndex++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
skipCycles--;
|
skipCycles--;
|
||||||
}
|
|
||||||
|
|
||||||
var sprite = CreateSprite(registerPos);
|
char[] sprite = CreateSprite(registerPos);
|
||||||
crt[cycle] = sprite[cycle % 40];
|
crt[cycle] = sprite[cycle%40];
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = "\n";
|
string result = "\n";
|
||||||
var charI = 0;
|
int charI = 0;
|
||||||
crt.ToList().ForEach(c =>
|
crt.ToList().ForEach(c =>
|
||||||
{
|
{
|
||||||
result += c.ToString();
|
result += c.ToString();
|
||||||
if ((charI + 1) % 40 == 0)
|
if ((charI+1)%40==0)
|
||||||
result += "\n";
|
result += "\n";
|
||||||
charI++;
|
charI++;
|
||||||
});
|
});
|
||||||
|
@ -89,9 +86,9 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static char[] CreateSprite(int registerPos)
|
private static char[] CreateSprite(int registerPos)
|
||||||
{
|
{
|
||||||
var result = new char[40];
|
char[] result = new char[40];
|
||||||
for (var i = 0; i < 40; i++)
|
for (int i = 0; i < 40; i++)
|
||||||
result[i] = i > registerPos - 1 && i < registerPos + 3 ? '#' : ' ';
|
result[i] = i > registerPos-1 && i < registerPos+3 ? '#' : '.';
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,175 +0,0 @@
|
||||||
using AdventOfCode.Utils.Extensions;
|
|
||||||
|
|
||||||
namespace AdventOfCode.Year2022;
|
|
||||||
|
|
||||||
public class Day11
|
|
||||||
{
|
|
||||||
private static readonly List<Monkey> Part1Monkeys = new();
|
|
||||||
private static readonly List<Monkey> Part2Monkeys = new();
|
|
||||||
|
|
||||||
public Day11()
|
|
||||||
{
|
|
||||||
File.ReadAllText("inputs/day11.txt").Split("\n\n").ToList().ForEach(monkey =>
|
|
||||||
{
|
|
||||||
var lines = monkey.Split("\n");
|
|
||||||
|
|
||||||
// Getting starting items
|
|
||||||
var items1 = new List<Item>();
|
|
||||||
var items2 = new List<Item>();
|
|
||||||
lines[1][(lines[1].IndexOf(':') + 2)..].Split(", ").ToList().ForEach(item =>
|
|
||||||
{
|
|
||||||
items1.Add(new Item(Convert.ToInt32(item)));
|
|
||||||
items2.Add(new Item(Convert.ToInt32(item)));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Getting operation
|
|
||||||
var op = lines[2][19..];
|
|
||||||
|
|
||||||
// Getting test info
|
|
||||||
var test = Convert.ToInt32(lines[3][21..]);
|
|
||||||
var testMonkeys = (Convert.ToInt32(lines[4][29..]), Convert.ToInt32(lines[5][30..]));
|
|
||||||
|
|
||||||
Part1Monkeys.Add(new Monkey(items1, op, test, testMonkeys));
|
|
||||||
Part2Monkeys.Add(new Monkey(items2, op, test, testMonkeys));
|
|
||||||
});
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day11 Solution
|
|
||||||
Part1 Result: {Part1()}
|
|
||||||
Part2 Result: {Part2()}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ulong Part1()
|
|
||||||
{
|
|
||||||
var inspections = new ulong[Part1Monkeys.Count];
|
|
||||||
|
|
||||||
for (var round = 0; round < 20; round++)
|
|
||||||
foreach (var monkey in Part1Monkeys)
|
|
||||||
{
|
|
||||||
foreach (var item in monkey.Items)
|
|
||||||
{
|
|
||||||
if (monkey.Operation.Contains('+'))
|
|
||||||
item.Value += Convert.ToInt32(monkey.Operation.Split(" ").Last());
|
|
||||||
else if (monkey.Operation == "old * old")
|
|
||||||
item.Value *= item.Value;
|
|
||||||
else
|
|
||||||
item.Value *= Convert.ToInt32(monkey.Operation.Split(" ").Last());
|
|
||||||
item.Value /= 3;
|
|
||||||
Part1Monkeys[
|
|
||||||
item.Value % monkey.DivisionTest == 0
|
|
||||||
? monkey.TestMonkeys.Item1
|
|
||||||
: monkey.TestMonkeys.Item2
|
|
||||||
].Items.Add(item);
|
|
||||||
inspections[Part1Monkeys.IndexOf(monkey)]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
monkey.Items.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<ulong>(inspections).ProductOfMax(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ulong Part2()
|
|
||||||
{
|
|
||||||
for (double round = 0; round < 10000; round++)
|
|
||||||
foreach (var monkey in Part2Monkeys)
|
|
||||||
{
|
|
||||||
monkey.UpdateItems();
|
|
||||||
var receiversAndItems = monkey.GetReceiversAndItems();
|
|
||||||
foreach (var key in receiversAndItems.Keys)
|
|
||||||
Part2Monkeys[key].ReceiveItems(receiversAndItems[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
var topMonkeys = new List<ulong>();
|
|
||||||
Part2Monkeys.ForEach(monkey => topMonkeys.Add((ulong)monkey.TotalItemsChecked));
|
|
||||||
return topMonkeys.ProductOfMax(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Monkey
|
|
||||||
{
|
|
||||||
public Monkey(List<Item> items, string operation, int divisionTest, (int, int) testMonkeys)
|
|
||||||
{
|
|
||||||
Items = items;
|
|
||||||
Operation = operation;
|
|
||||||
DivisionTest = divisionTest;
|
|
||||||
TestMonkeys = testMonkeys;
|
|
||||||
TotalItemsChecked = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Item> Items { get; private set; }
|
|
||||||
public string Operation { get; }
|
|
||||||
public int DivisionTest { get; }
|
|
||||||
public (int, int) TestMonkeys { get; }
|
|
||||||
public int TotalItemsChecked { get; private set; }
|
|
||||||
|
|
||||||
public void UpdateItems()
|
|
||||||
{
|
|
||||||
if (Operation.Contains('+'))
|
|
||||||
foreach (var item in Items)
|
|
||||||
item.UpdateDivisibleBy(Operator.Add, Convert.ToInt32(Operation.Split(" ").Last()));
|
|
||||||
else if (Operation == "old * old")
|
|
||||||
foreach (var item in Items)
|
|
||||||
item.UpdateDivisibleBy(Operator.Square);
|
|
||||||
else
|
|
||||||
foreach (var item in Items)
|
|
||||||
item.UpdateDivisibleBy(Operator.Multiply, Convert.ToInt32(Operation.Split(" ").Last()));
|
|
||||||
TotalItemsChecked += Items.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<int, List<Item>> GetReceiversAndItems()
|
|
||||||
{
|
|
||||||
var result = new Dictionary<int, List<Item>>
|
|
||||||
{
|
|
||||||
[TestMonkeys.Item1] = new(),
|
|
||||||
[TestMonkeys.Item2] = new()
|
|
||||||
};
|
|
||||||
Items.ForEach(item =>
|
|
||||||
{
|
|
||||||
if (item.DivisibleBy[DivisionTest] == 0)
|
|
||||||
result[TestMonkeys.Item1].Add(item);
|
|
||||||
else
|
|
||||||
result[TestMonkeys.Item2].Add(item);
|
|
||||||
});
|
|
||||||
Items = new List<Item>();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ReceiveItems(List<Item> items)
|
|
||||||
{
|
|
||||||
Items.AddRange(items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Item
|
|
||||||
{
|
|
||||||
public Item(int value)
|
|
||||||
{
|
|
||||||
Value = value;
|
|
||||||
foreach (var i in new[] { 2, 3, 5, 7, 11, 13, 17, 19, 23 })
|
|
||||||
DivisibleBy.Add(i, value % i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Value { get; set; }
|
|
||||||
public Dictionary<int, int> DivisibleBy { get; } = new();
|
|
||||||
|
|
||||||
public void UpdateDivisibleBy(Operator op, int value = default)
|
|
||||||
{
|
|
||||||
foreach (var key in DivisibleBy.Keys)
|
|
||||||
DivisibleBy[key] = op switch
|
|
||||||
{
|
|
||||||
Operator.Add => (DivisibleBy[key] + value) % key,
|
|
||||||
Operator.Multiply => DivisibleBy[key] * value % key,
|
|
||||||
Operator.Square => DivisibleBy[key] * DivisibleBy[key] % key,
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(op), op, null)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Operator
|
|
||||||
{
|
|
||||||
Add,
|
|
||||||
Multiply,
|
|
||||||
Square
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
namespace AdventOfCode.Year2022;
|
|
||||||
|
|
||||||
public class Day12
|
|
||||||
{
|
|
||||||
private const int SOrd = -14;
|
|
||||||
private const int EOrd = -28;
|
|
||||||
private static short[,]? _map;
|
|
||||||
private static (int, int) _sCoords;
|
|
||||||
private static (int, int) _eCoords;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Slowest solution so far.
|
|
||||||
/// Could most certainly use some improvements :skull:
|
|
||||||
/// </summary>
|
|
||||||
public Day12()
|
|
||||||
{
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day12 Solution
|
|
||||||
Part1 Result: {Part1()}
|
|
||||||
Part2 Result: {Part2()}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void PartInit()
|
|
||||||
{
|
|
||||||
var lines = File.ReadAllLines("inputs/day12.txt");
|
|
||||||
var map = new short[lines.Length, lines[0].Length];
|
|
||||||
|
|
||||||
for (var i = 0; i < lines.Length; i++)
|
|
||||||
for (var j = 0; j < lines[i].Length; j++)
|
|
||||||
map[i, j] = (short)(Convert.ToInt16(lines[i][j]) - 97);
|
|
||||||
|
|
||||||
_map = map;
|
|
||||||
_sCoords = FindCoords(map, SOrd);
|
|
||||||
_eCoords = FindCoords(map, EOrd);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Part1()
|
|
||||||
{
|
|
||||||
PartInit();
|
|
||||||
var distances = GetIndexes(_map!).Where(item => item != _sCoords)
|
|
||||||
.ToDictionary(index => (index.Item1, index.Item2), _ => short.MaxValue);
|
|
||||||
distances[(_sCoords.Item1, _sCoords.Item2)] = 0;
|
|
||||||
|
|
||||||
_map![_sCoords.Item1, _sCoords.Item2] = 0;
|
|
||||||
_map[_eCoords.Item1, _eCoords.Item2] = (short)(Convert.ToInt16('z') - 97);
|
|
||||||
|
|
||||||
var visited = new List<(int, int)>();
|
|
||||||
var current = _sCoords;
|
|
||||||
var unvisited = GetIndexes(_map).ToList();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dijkstra(current, distances, visited, Part.Part1);
|
|
||||||
unvisited.Remove(current);
|
|
||||||
current = distances.Where(pair => unvisited.Contains(pair.Key)).MinBy(pair => pair.Value).Key;
|
|
||||||
}
|
|
||||||
catch (InvalidOperationException)
|
|
||||||
{
|
|
||||||
return distances[_eCoords];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Part2()
|
|
||||||
{
|
|
||||||
PartInit();
|
|
||||||
var distances = GetIndexes(_map!).ToDictionary(index => (index.Item1, index.Item2), _ => short.MaxValue);
|
|
||||||
distances[(_eCoords.Item1, _eCoords.Item2)] = 0;
|
|
||||||
|
|
||||||
_map![_sCoords.Item1, _sCoords.Item2] = 0;
|
|
||||||
_map[_eCoords.Item1, _eCoords.Item2] = (short)(Convert.ToInt16('z') - 97);
|
|
||||||
|
|
||||||
var visited = new List<(int, int)>();
|
|
||||||
var current = _eCoords;
|
|
||||||
var unvisited = GetIndexes(_map).ToList();
|
|
||||||
var aIndexes = FindAllCoords(_map, 0).ToList();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (aIndexes.Contains(Dijkstra(current, distances, visited, Part.Part2)))
|
|
||||||
return distances.Where(pair => aIndexes.Contains(pair.Key)).Min(pair => pair.Value);
|
|
||||||
unvisited.Remove(current);
|
|
||||||
current = distances.Where(pair => unvisited.Contains(pair.Key)).MinBy(pair => pair.Value).Key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static (int, int) Dijkstra((int, int) current, IDictionary<(int, int), short> distances,
|
|
||||||
ICollection<(int, int)> visited, Part part)
|
|
||||||
{
|
|
||||||
var nextCoords = new Dictionary<char, (int, int)>
|
|
||||||
{
|
|
||||||
['D'] = (current.Item1 + 1, current.Item2),
|
|
||||||
['U'] = (current.Item1 - 1, current.Item2),
|
|
||||||
['R'] = (current.Item1, current.Item2 + 1),
|
|
||||||
['L'] = (current.Item1, current.Item2 - 1)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (current.Item1 < _map!.GetLength(0) - 1
|
|
||||||
&& IsStepPossible(current, nextCoords['D'], part)
|
|
||||||
&& !visited.Contains(nextCoords['D']))
|
|
||||||
UpdateDistances(distances, current, nextCoords['D']);
|
|
||||||
|
|
||||||
if (current.Item1 > 0
|
|
||||||
&& IsStepPossible(current, nextCoords['U'], part)
|
|
||||||
&& !visited.Contains(nextCoords['U']))
|
|
||||||
UpdateDistances(distances, current, nextCoords['U']);
|
|
||||||
|
|
||||||
if (current.Item2 < _map.GetLength(1) - 1
|
|
||||||
&& IsStepPossible(current, nextCoords['R'], part)
|
|
||||||
&& !visited.Contains(nextCoords['R']))
|
|
||||||
UpdateDistances(distances, current, nextCoords['R']);
|
|
||||||
|
|
||||||
if (current.Item2 > 0
|
|
||||||
&& IsStepPossible(current, nextCoords['L'], part)
|
|
||||||
&& !visited.Contains(nextCoords['L']))
|
|
||||||
UpdateDistances(distances, current, nextCoords['L']);
|
|
||||||
|
|
||||||
visited.Add(current);
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsStepPossible((int, int) currentCoords, (int, int) nextCoord, Part part)
|
|
||||||
{
|
|
||||||
return part switch
|
|
||||||
{
|
|
||||||
Part.Part1 => _map![nextCoord.Item1, nextCoord.Item2] - 1 <= _map[currentCoords.Item1, currentCoords.Item2],
|
|
||||||
Part.Part2 => _map![nextCoord.Item1, nextCoord.Item2] + 1 >= _map[currentCoords.Item1, currentCoords.Item2],
|
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(part), part, null)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateDistances(IDictionary<(int, int), short> distances, (int, int) currentCoords,
|
|
||||||
(int, int) nextCoords)
|
|
||||||
{
|
|
||||||
if (distances[(nextCoords.Item1, nextCoords.Item2)] == short.MaxValue ||
|
|
||||||
distances[(nextCoords.Item1, nextCoords.Item2)] > distances[(currentCoords.Item1, currentCoords.Item2)])
|
|
||||||
distances[(nextCoords.Item1, nextCoords.Item2)] =
|
|
||||||
(short)(distances[(currentCoords.Item1, currentCoords.Item2)] + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds the first occurrence of a value in a 2D array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">The 2D array</param>
|
|
||||||
/// <param name="value">The value to be found</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="ArgumentNullException">Array can't be null</exception>
|
|
||||||
private static (int, int) FindCoords(short[,] array, int value)
|
|
||||||
{
|
|
||||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
|
||||||
foreach (var index in GetIndexes(array))
|
|
||||||
if (array[index.Item1, index.Item2] == value)
|
|
||||||
return (index.Item1, index.Item2);
|
|
||||||
return (-1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds all coordinates of a value in a 2D array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">The 2D array</param>
|
|
||||||
/// <param name="value">The value to be found</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="ArgumentNullException">Array can't be null</exception>
|
|
||||||
private static IEnumerable<(int, int)> FindAllCoords(short[,] array, int value)
|
|
||||||
{
|
|
||||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
|
||||||
return from index in GetIndexes(array)
|
|
||||||
where array[index.Item1, index.Item2] == value
|
|
||||||
select (index.Item1, index.Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns an enumerable of all indexes of a 2D array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="array">The 2D array</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="ArgumentNullException">Array can't be null</exception>
|
|
||||||
private static IEnumerable<(int, int)> GetIndexes(short[,] array)
|
|
||||||
{
|
|
||||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
|
||||||
for (var i = 0; i < array.GetLength(0); i++)
|
|
||||||
for (var j = 0; j < array.GetLength(1); j++)
|
|
||||||
yield return (i, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum Part
|
|
||||||
{
|
|
||||||
Part1,
|
|
||||||
Part2
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,18 +6,16 @@ public class Day2
|
||||||
|
|
||||||
public Day2()
|
public Day2()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("Day2 Solution");
|
||||||
Day2 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
{
|
{
|
||||||
var score = 0;
|
int score = 0;
|
||||||
foreach (var match in Matches)
|
foreach (string[] match in Matches)
|
||||||
{
|
{
|
||||||
if (match[0] == "A")
|
if (match[0] == "A")
|
||||||
{
|
{
|
||||||
|
@ -28,7 +26,6 @@ Part2 Result: {Part2()}
|
||||||
if (match[1] == "Z")
|
if (match[1] == "Z")
|
||||||
score += 3;
|
score += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match[0] == "B")
|
if (match[0] == "B")
|
||||||
{
|
{
|
||||||
if (match[1] == "X")
|
if (match[1] == "X")
|
||||||
|
@ -38,7 +35,6 @@ Part2 Result: {Part2()}
|
||||||
if (match[1] == "Z")
|
if (match[1] == "Z")
|
||||||
score += 3 + 6;
|
score += 3 + 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match[0] == "C")
|
if (match[0] == "C")
|
||||||
{
|
{
|
||||||
if (match[1] == "X")
|
if (match[1] == "X")
|
||||||
|
@ -55,8 +51,8 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static int Part2()
|
private static int Part2()
|
||||||
{
|
{
|
||||||
var score = 0;
|
int score = 0;
|
||||||
foreach (var match in Matches)
|
foreach (string[] match in Matches)
|
||||||
{
|
{
|
||||||
if (match[0] == "A")
|
if (match[0] == "A")
|
||||||
{
|
{
|
||||||
|
@ -67,7 +63,6 @@ Part2 Result: {Part2()}
|
||||||
if (match[1] == "Z")
|
if (match[1] == "Z")
|
||||||
score += 2 + 6;
|
score += 2 + 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match[0] == "B")
|
if (match[0] == "B")
|
||||||
{
|
{
|
||||||
if (match[1] == "X")
|
if (match[1] == "X")
|
||||||
|
@ -77,7 +72,6 @@ Part2 Result: {Part2()}
|
||||||
if (match[1] == "Z")
|
if (match[1] == "Z")
|
||||||
score += 3 + 6;
|
score += 3 + 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match[0] == "C")
|
if (match[0] == "C")
|
||||||
{
|
{
|
||||||
if (match[1] == "X")
|
if (match[1] == "X")
|
||||||
|
@ -94,8 +88,8 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static List<string[]> LoadMatches()
|
private static List<string[]> LoadMatches()
|
||||||
{
|
{
|
||||||
var matches = new List<string[]>();
|
List<string[]> matches = new List<string[]>();
|
||||||
foreach (var line in File.ReadAllLines("inputs/day2.txt"))
|
foreach (string line in File.ReadAllLines("inputs/day2.txt"))
|
||||||
matches.Add(line.Split(" "));
|
matches.Add(line.Split(" "));
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,54 +6,55 @@ public class Day3
|
||||||
|
|
||||||
public Day3()
|
public Day3()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("Day3 Solution");
|
||||||
Day3 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
{
|
{
|
||||||
var sum = 0;
|
int sum = 0;
|
||||||
|
|
||||||
var duplicates = new List<char>();
|
List<char> duplicates = new List<char>();
|
||||||
|
|
||||||
foreach (var backpack in Backpacks)
|
foreach (string backpack in Backpacks)
|
||||||
{
|
{
|
||||||
var compartmentSize = backpack.Length / 2;
|
int compartmentSize = backpack.Length / 2;
|
||||||
var itemsInCompartment1 = new List<char>();
|
List<char> itemsInCompartment1 = new List<char>();
|
||||||
var itemsInCompartment2 = new List<char>();
|
List<char> itemsInCompartment2 = new List<char>();
|
||||||
|
|
||||||
for (var i = 0; i < compartmentSize; i++)
|
for (int i = 0; i < compartmentSize; i++)
|
||||||
itemsInCompartment1.Add(backpack[i]);
|
itemsInCompartment1.Add(backpack[i]);
|
||||||
for (var i = compartmentSize; i < compartmentSize * 2; i++)
|
for (int i = compartmentSize; i < compartmentSize * 2; i++)
|
||||||
itemsInCompartment2.Add(backpack[i]);
|
itemsInCompartment2.Add(backpack[i]);
|
||||||
|
|
||||||
var duplicatedItem = itemsInCompartment1.Intersect(itemsInCompartment2).FirstOrDefault();
|
char duplicatedItem = itemsInCompartment1.Intersect(itemsInCompartment2).FirstOrDefault();
|
||||||
duplicates.Add(duplicatedItem);
|
duplicates.Add(duplicatedItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var duplicate in duplicates)
|
foreach (char duplicate in duplicates)
|
||||||
if (char.IsUpper(duplicate))
|
{
|
||||||
|
if (Char.IsUpper(duplicate))
|
||||||
sum += Convert.ToInt16(duplicate) - 38;
|
sum += Convert.ToInt16(duplicate) - 38;
|
||||||
else
|
else
|
||||||
sum += Convert.ToInt16(duplicate) - 96;
|
sum += Convert.ToInt16(duplicate) - 96;
|
||||||
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part2()
|
private static int Part2()
|
||||||
{
|
{
|
||||||
var sum = 0;
|
int sum = 0;
|
||||||
var groups = new List<List<string>>();
|
List<List<string>> groups = new List<List<string>>();
|
||||||
|
|
||||||
for (var i = 0; i < Backpacks.Length; i += 3)
|
for (int i = 0; i < Backpacks.Length; i+=3)
|
||||||
{
|
{
|
||||||
var group = new List<string>();
|
List<string> group = new List<string>();
|
||||||
|
|
||||||
for (var x = 0; x < 3; x++)
|
for (int x = 0; x < 3; x++)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
group.Add(Backpacks[i + x]);
|
group.Add(Backpacks[i + x]);
|
||||||
|
@ -62,23 +63,26 @@ Part2 Result: {Part2()}
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (group.All(x => x != ""))
|
if (group.All(x => x != ""))
|
||||||
groups.Add(group);
|
groups.Add(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
var duplicates = new List<char>();
|
List<char> duplicates = new List<char>();
|
||||||
foreach (var group in groups)
|
foreach (List<string> group in groups)
|
||||||
{
|
{
|
||||||
var groupArray = group.ToArray();
|
string[] groupArray = group.ToArray();
|
||||||
duplicates.Add(groupArray[0].Intersect(groupArray[1].Intersect(groupArray[2])).FirstOrDefault());
|
duplicates.Add(groupArray[0].Intersect(groupArray[1].Intersect(groupArray[2])).FirstOrDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var duplicate in duplicates)
|
foreach (char duplicate in duplicates)
|
||||||
if (char.IsUpper(duplicate))
|
{
|
||||||
|
if (Char.IsUpper(duplicate))
|
||||||
sum += Convert.ToInt16(duplicate) - 38;
|
sum += Convert.ToInt16(duplicate) - 38;
|
||||||
else
|
else
|
||||||
sum += Convert.ToInt16(duplicate) - 96;
|
sum += Convert.ToInt16(duplicate) - 96;
|
||||||
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,12 @@ public class Day4
|
||||||
{
|
{
|
||||||
public Day4()
|
public Day4()
|
||||||
{
|
{
|
||||||
var lines = File.ReadAllLines("inputs/day4.txt");
|
Console.WriteLine("Day4 Solution");
|
||||||
var containedCount = 0;
|
|
||||||
var intersectedCount = 0;
|
string[] lines = File.ReadAllLines("inputs/day4.txt");
|
||||||
foreach (var line in lines)
|
int containedCount = 0;
|
||||||
|
int intersectedCount = 0;
|
||||||
|
foreach (string line in lines)
|
||||||
{
|
{
|
||||||
if (IsContained(line))
|
if (IsContained(line))
|
||||||
containedCount++;
|
containedCount++;
|
||||||
|
@ -15,37 +17,34 @@ public class Day4
|
||||||
intersectedCount++;
|
intersectedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine($@"
|
Console.WriteLine($"Part1 Result: {containedCount}");
|
||||||
Day4 Solution
|
Console.WriteLine($"Part2 Result: {intersectedCount}");
|
||||||
Part1 Result: {containedCount}
|
Console.WriteLine("\n=============================\n");
|
||||||
Part2 Result: {intersectedCount}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsContained(string line)
|
private static bool IsContained(string line)
|
||||||
{
|
{
|
||||||
var limits = GetLimits(line);
|
int[][] limits = GetLimits(line);
|
||||||
return (limits[0][0] >= limits[1][0] && limits[0][1] <= limits[1][1])
|
return (limits[0][0] >= limits[1][0] && limits[0][1] <= limits[1][1])
|
||||||
|| (limits[1][0] >= limits[0][0] && limits[1][1] <= limits[0][1]);
|
|| (limits[1][0] >= limits[0][0] && limits[1][1] <= limits[0][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsIntersected(string line)
|
private static bool IsIntersected(string line)
|
||||||
{
|
{
|
||||||
var limits = GetLimits(line);
|
int[][] limits = GetLimits(line);
|
||||||
return (limits[0][1] >= limits[1][0] && limits[0][0] <= limits[1][1])
|
return (limits[0][1] >= limits[1][0] && limits[0][0] <= limits[1][1])
|
||||||
|| (limits[1][1] >= limits[0][0] && limits[1][0] <= limits[0][1]);
|
|| (limits[1][1] >= limits[0][0] && limits[1][0] <= limits[0][1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int[][] GetLimits(string line)
|
private static int[][] GetLimits(string line)
|
||||||
{
|
{
|
||||||
var pair = line.Split(",");
|
string[] pair = line.Split(",");
|
||||||
var pair1 = pair[0].Split("-");
|
string[] pair1 = pair[0].Split("-");
|
||||||
var pair2 = pair[1].Split("-");
|
string[] pair2 = pair[1].Split("-");
|
||||||
return new[]
|
return new []
|
||||||
{
|
{
|
||||||
new[] { Convert.ToInt32(pair1[0]), Convert.ToInt32(pair1[1]) },
|
new [] {Convert.ToInt32(pair1[0]), Convert.ToInt32(pair1[1])},
|
||||||
new[] { Convert.ToInt32(pair2[0]), Convert.ToInt32(pair2[1]) }
|
new [] {Convert.ToInt32(pair2[0]), Convert.ToInt32(pair2[1])}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,59 +6,59 @@ public class Day5
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<int, List<char>> Crates = new()
|
private static readonly Dictionary<int, List<char>> Crates = new()
|
||||||
{
|
{
|
||||||
[1] = new List<char>(),
|
[1] = new(),
|
||||||
[2] = new List<char>(),
|
[2] = new(),
|
||||||
[3] = new List<char>(),
|
[3] = new(),
|
||||||
[4] = new List<char>(),
|
[4] = new(),
|
||||||
[5] = new List<char>(),
|
[5] = new(),
|
||||||
[6] = new List<char>(),
|
[6] = new(),
|
||||||
[7] = new List<char>(),
|
[7] = new(),
|
||||||
[8] = new List<char>(),
|
[8] = new(),
|
||||||
[9] = new List<char>()
|
[9] = new()
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly List<(int, int, int)> Moves = new();
|
private static readonly List<(int, int, int)> Moves = new();
|
||||||
|
|
||||||
public Day5()
|
public Day5()
|
||||||
{
|
{
|
||||||
var input = File.ReadAllText("inputs/day5.txt").Split("\n\n");
|
Console.WriteLine("Day5 Solution");
|
||||||
|
|
||||||
|
string[] input = File.ReadAllText("inputs/day5.txt").Split("\n\n");
|
||||||
LoadCrates(input[0]);
|
LoadCrates(input[0]);
|
||||||
LoadMoves(input[1]);
|
LoadMoves(input[1]);
|
||||||
Console.WriteLine($@"
|
|
||||||
Day5 Solution
|
|
||||||
Part1 Result: {Parts(Part.Part1)}
|
|
||||||
Part2 Result: {Parts(Part.Part2)}
|
|
||||||
|
|
||||||
=============================");
|
Console.WriteLine($"Part1 Result: {Parts(Part.Part1)}");
|
||||||
|
Console.WriteLine($"Part2 Result: {Parts(Part.Part2)}");
|
||||||
|
Console.WriteLine("\n=============================\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string Parts(Part part)
|
private static string Parts(Part part)
|
||||||
{
|
{
|
||||||
var crates = Crates.Clone();
|
Dictionary<int, List<char>> crates = Crates.Clone();
|
||||||
foreach (var move in Moves)
|
foreach ((int, int, int) move in Moves)
|
||||||
{
|
{
|
||||||
var cratesMoved = crates[move.Item2].Sublist(0, move.Item1);
|
List<char> cratesMoved = crates[move.Item2].Sublist(0, move.Item1);
|
||||||
for (var i = 0; i < move.Item1; i++)
|
for (int i = 0; i < move.Item1; i++)
|
||||||
crates[move.Item2].Remove(crates[move.Item2][0]);
|
crates[move.Item2].Remove(crates[move.Item2][0]);
|
||||||
foreach (var crate in part == Part.Part1 ? cratesMoved : cratesMoved.Reversed())
|
foreach (char crate in part == Part.Part1 ? cratesMoved : cratesMoved.Reversed())
|
||||||
crates[move.Item3].Insert(0, crate);
|
crates[move.Item3].Insert(0, crate);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = "";
|
string result = "";
|
||||||
foreach (var crateList in crates.Values)
|
foreach (List<char> crateList in crates.Values)
|
||||||
result += crateList[0];
|
result += crateList[0];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LoadCrates(string crates)
|
private static void LoadCrates(string crates)
|
||||||
{
|
{
|
||||||
var crate_lines = crates.Split("\n");
|
string[] crate_lines = crates.Split("\n");
|
||||||
foreach (var line in crate_lines)
|
foreach (string line in crate_lines)
|
||||||
{
|
{
|
||||||
var firstCrate = 0;
|
int firstCrate = 0;
|
||||||
if (line[firstCrate] == '[')
|
if (line[firstCrate] == '[')
|
||||||
Crates[1].Add(line[1]);
|
Crates[1].Add(line[1]);
|
||||||
while (line.Substring(firstCrate + 1).Contains('['))
|
while (line.Substring(firstCrate+1).Contains('['))
|
||||||
{
|
{
|
||||||
firstCrate = line.IndexOf('[', firstCrate + 1);
|
firstCrate = line.IndexOf('[', firstCrate + 1);
|
||||||
Crates[firstCrate / 4 + 1].Add(line[firstCrate + 1]);
|
Crates[firstCrate / 4 + 1].Add(line[firstCrate + 1]);
|
||||||
|
@ -68,19 +68,18 @@ Part2 Result: {Parts(Part.Part2)}
|
||||||
|
|
||||||
private static void LoadMoves(string moves)
|
private static void LoadMoves(string moves)
|
||||||
{
|
{
|
||||||
var move_lines = moves.Split("\n");
|
string[] move_lines = moves.Split("\n");
|
||||||
foreach (var line in move_lines)
|
foreach (string line in move_lines)
|
||||||
{
|
{
|
||||||
var move = line.Substring(5);
|
string move = line.Substring(5);
|
||||||
var moved = move.Split(" from ");
|
string[] moved = move.Split(" from ");
|
||||||
var crates = moved[1].Split(" to ");
|
string[] crates = moved[1].Split(" to ");
|
||||||
Moves.Add((Convert.ToInt32(moved[0]), Convert.ToInt32(crates[0]), Convert.ToInt32(crates[1])));
|
Moves.Add((Convert.ToInt32(moved[0]), Convert.ToInt32(crates[0]), Convert.ToInt32(crates[1])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Part
|
private enum Part
|
||||||
{
|
{
|
||||||
Part1,
|
Part1, Part2
|
||||||
Part2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,17 +6,15 @@ public class Day6
|
||||||
|
|
||||||
public Day6()
|
public Day6()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("Day6 Solution");
|
||||||
Day6 Solution
|
Console.WriteLine($"Part1 Result: {GetValidMarkerIndex(4)}");
|
||||||
Part1 Result: {GetValidMarkerIndex(4)}
|
Console.WriteLine($"Part2 Result: {GetValidMarkerIndex(14)}");
|
||||||
Part2 Result: {GetValidMarkerIndex(14)}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int? GetValidMarkerIndex(int size)
|
private static int? GetValidMarkerIndex(int size)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < Input.Length - size; i++)
|
for (int i = 0; i < Input.Length-size; i++)
|
||||||
if (ValidateMarker(Input.Substring(i, size)))
|
if (ValidateMarker(Input.Substring(i, size)))
|
||||||
return i + size;
|
return i + size;
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -6,20 +6,18 @@ public class Day7
|
||||||
|
|
||||||
public Day7()
|
public Day7()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("Day7 Solution");
|
||||||
Day7 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
{
|
{
|
||||||
var sum = 0;
|
int sum = 0;
|
||||||
foreach (var path in Tree.Keys)
|
foreach (string path in Tree.Keys)
|
||||||
{
|
{
|
||||||
var size = CalculateDirSize(path);
|
int size = CalculateDirSize(path);
|
||||||
if (size <= 100000)
|
if (size <= 100000)
|
||||||
sum += size;
|
sum += size;
|
||||||
}
|
}
|
||||||
|
@ -29,13 +27,16 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static int Part2()
|
private static int Part2()
|
||||||
{
|
{
|
||||||
var neededSpace = CalculateDirSize("/") - 40000000;
|
int neededSpace = CalculateDirSize("/") - 40000000;
|
||||||
if (neededSpace <= 0) return 0;
|
if (neededSpace <= 0)
|
||||||
|
|
||||||
var bigEnoughDir = new List<int>();
|
|
||||||
foreach (var path in Tree.Keys)
|
|
||||||
{
|
{
|
||||||
var size = CalculateDirSize(path);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> bigEnoughDir = new List<int>();
|
||||||
|
foreach (string path in Tree.Keys)
|
||||||
|
{
|
||||||
|
int size = CalculateDirSize(path);
|
||||||
if (size > neededSpace)
|
if (size > neededSpace)
|
||||||
bigEnoughDir.Add(size);
|
bigEnoughDir.Add(size);
|
||||||
}
|
}
|
||||||
|
@ -46,11 +47,11 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static int CalculateDirSize(string path)
|
private static int CalculateDirSize(string path)
|
||||||
{
|
{
|
||||||
var size = 0;
|
int size = 0;
|
||||||
var dirContent = Tree[path];
|
List<string> dirContent = Tree[path];
|
||||||
foreach (var content in dirContent)
|
foreach (string content in dirContent)
|
||||||
{
|
{
|
||||||
var properties = content.Split(" ");
|
string[] properties = content.Split(" ");
|
||||||
if (properties[0] == "dir")
|
if (properties[0] == "dir")
|
||||||
size += CalculateDirSize(path + properties[1] + "/");
|
size += CalculateDirSize(path + properties[1] + "/");
|
||||||
else
|
else
|
||||||
|
@ -62,33 +63,30 @@ Part2 Result: {Part2()}
|
||||||
|
|
||||||
private static Dictionary<string, List<string>> GetTree()
|
private static Dictionary<string, List<string>> GetTree()
|
||||||
{
|
{
|
||||||
var tree = new Dictionary<string, List<string>>();
|
Dictionary<string, List<string>> tree = new Dictionary<string, List<string>>();
|
||||||
var currentPath = "";
|
string currentPath = "";
|
||||||
|
|
||||||
var input = File.ReadLines("inputs/day7.txt");
|
IEnumerable<string> input = File.ReadLines("inputs/day7.txt");
|
||||||
foreach (var line in input)
|
foreach (string line in input)
|
||||||
|
{
|
||||||
if (line.StartsWith("$"))
|
if (line.StartsWith("$"))
|
||||||
{
|
{
|
||||||
var cmdLine = line.Substring(2).Split(" ");
|
string[] cmdLine = line.Substring(2).Split(" ");
|
||||||
if (cmdLine[0] == "cd")
|
if (cmdLine[0] == "cd")
|
||||||
{
|
{
|
||||||
var dir = cmdLine[1];
|
string dir = cmdLine[1];
|
||||||
if (dir == "/")
|
if (dir == "/")
|
||||||
{
|
|
||||||
currentPath = "/";
|
currentPath = "/";
|
||||||
}
|
|
||||||
else if (dir == "..")
|
else if (dir == "..")
|
||||||
{
|
{
|
||||||
if (currentPath == "/") continue;
|
if (currentPath == "/") continue;
|
||||||
var slashIndex = currentPath
|
int slashIndex = currentPath
|
||||||
.Substring(0, currentPath.Length - 1)
|
.Substring(0, currentPath.Length - 1)
|
||||||
.LastIndexOf('/');
|
.LastIndexOf('/');
|
||||||
currentPath = currentPath.Substring(0, slashIndex + 1);
|
currentPath = currentPath.Substring(0, slashIndex + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
currentPath += dir + "/";
|
currentPath += dir + "/";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -97,6 +95,7 @@ Part2 Result: {Part2()}
|
||||||
tree.Add(currentPath, new List<string>());
|
tree.Add(currentPath, new List<string>());
|
||||||
tree[currentPath].Add(line);
|
tree[currentPath].Add(line);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
125
Year2022/Day8.cs
125
Year2022/Day8.cs
|
@ -8,92 +8,89 @@ public class Day8
|
||||||
|
|
||||||
public Day8()
|
public Day8()
|
||||||
{
|
{
|
||||||
Console.WriteLine($@"
|
Console.WriteLine("Day8 Solution");
|
||||||
Day8 Solution
|
Console.WriteLine($"Part1 Result: {Part1()}");
|
||||||
Part1 Result: {Part1()}
|
Console.WriteLine($"Part2 Result: {Part2()}");
|
||||||
Part2 Result: {Part2()}
|
Console.WriteLine("\n=============================\n");
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part1()
|
private static int Part1()
|
||||||
{
|
{
|
||||||
var count = 0;
|
int count = 0;
|
||||||
for (var i = 0; i < TreeMap.Count; i++)
|
for (int i = 0; i < TreeMap.Count; i++)
|
||||||
for (var j = 0; j < TreeMap[i].Count; j++)
|
for (int j = 0; j < TreeMap[i].Count; j++)
|
||||||
if (i == 0 || i == TreeMap.Count - 1 || j == 0 || j == TreeMap.Count - 1
|
if (i == 0 || i == TreeMap.Count-1 || j == 0 || j == TreeMap.Count-1
|
||||||
|| TreeMap[i].Sublist(0, j).Max() < TreeMap[i][j]
|
|| TreeMap[i].Sublist(0, j).Max() < TreeMap[i][j]
|
||||||
|| TreeMap[i].Sublist(j + 1, TreeMap[i].Count).DefaultIfEmpty().Max() < TreeMap[i][j]
|
|| TreeMap[i].Sublist(j + 1, TreeMap[i].Count).DefaultIfEmpty().Max() < TreeMap[i][j]
|
||||||
|| TreeMap.GetColumn(j).Sublist(0, i).Max() < TreeMap[i][j]
|
|| TreeMap.GetColumn(j).Sublist(0, i).Max() < TreeMap[i][j]
|
||||||
|| TreeMap.GetColumn(j).Sublist(i + 1, TreeMap[i].Count).DefaultIfEmpty().Max() < TreeMap[i][j])
|
|| TreeMap.GetColumn(j).Sublist(i + 1, TreeMap[i].Count).DefaultIfEmpty().Max() < TreeMap[i][j])
|
||||||
count++;
|
count++;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Part2()
|
private static int Part2()
|
||||||
{
|
{
|
||||||
var highestScore = 0;
|
int highestScore = 0;
|
||||||
|
|
||||||
for (var i = 0; i < TreeMap.Count; i++)
|
for (int i = 0; i < TreeMap.Count; i++)
|
||||||
for (var j = 0; j < TreeMap[i].Count; j++)
|
for (int j = 0; j < TreeMap[i].Count; j++)
|
||||||
{
|
|
||||||
if (i == 0 || j == 0) continue;
|
|
||||||
|
|
||||||
var currentTree = TreeMap[i][j];
|
|
||||||
var currentTreeScore = 1;
|
|
||||||
var directionCount = 0;
|
|
||||||
|
|
||||||
for (var k = i - 1; k >= 0; k--)
|
|
||||||
{
|
{
|
||||||
directionCount++;
|
if (i == 0 || j == 0) continue;
|
||||||
if (TreeMap[k][j] >= currentTree) break;
|
|
||||||
|
int currentTree = TreeMap[i][j];
|
||||||
|
int currentTreeScore = 1;
|
||||||
|
int directionCount = 0;
|
||||||
|
|
||||||
|
for (int k = i - 1; k >= 0; k--)
|
||||||
|
{
|
||||||
|
directionCount++;
|
||||||
|
if (TreeMap[k][j] >= currentTree) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTreeScore *= directionCount;
|
||||||
|
directionCount = 0;
|
||||||
|
|
||||||
|
for (int k = j - 1; k >= 0; k--)
|
||||||
|
{
|
||||||
|
directionCount++;
|
||||||
|
if (TreeMap[i][k] >= currentTree) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTreeScore *= directionCount;
|
||||||
|
directionCount = 0;
|
||||||
|
|
||||||
|
for (int k = i + 1; k < TreeMap.Count; k++)
|
||||||
|
{
|
||||||
|
directionCount++;
|
||||||
|
if (TreeMap[k][j] >= currentTree) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTreeScore *= directionCount;
|
||||||
|
directionCount = 0;
|
||||||
|
|
||||||
|
for (int k = j + 1; k < TreeMap[i].Count; k++)
|
||||||
|
{
|
||||||
|
directionCount++;
|
||||||
|
if (TreeMap[i][k] >= currentTree) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTreeScore *= directionCount;
|
||||||
|
highestScore = Math.Max(highestScore, currentTreeScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTreeScore *= directionCount;
|
|
||||||
directionCount = 0;
|
|
||||||
|
|
||||||
for (var k = j - 1; k >= 0; k--)
|
|
||||||
{
|
|
||||||
directionCount++;
|
|
||||||
if (TreeMap[i][k] >= currentTree) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTreeScore *= directionCount;
|
|
||||||
directionCount = 0;
|
|
||||||
|
|
||||||
for (var k = i + 1; k < TreeMap.Count; k++)
|
|
||||||
{
|
|
||||||
directionCount++;
|
|
||||||
if (TreeMap[k][j] >= currentTree) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTreeScore *= directionCount;
|
|
||||||
directionCount = 0;
|
|
||||||
|
|
||||||
for (var k = j + 1; k < TreeMap[i].Count; k++)
|
|
||||||
{
|
|
||||||
directionCount++;
|
|
||||||
if (TreeMap[i][k] >= currentTree) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTreeScore *= directionCount;
|
|
||||||
highestScore = Math.Max(highestScore, currentTreeScore);
|
|
||||||
}
|
|
||||||
|
|
||||||
return highestScore;
|
return highestScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<List<int>> LoadMap()
|
private static List<List<int>> LoadMap()
|
||||||
{
|
{
|
||||||
var map = new List<List<int>>();
|
List<List<int>> map = new List<List<int>>();
|
||||||
var lines = File.ReadAllLines("inputs/day8.txt");
|
string[] lines = File.ReadAllLines("inputs/day8.txt");
|
||||||
for (var i = 0; i < lines.Length; i++)
|
for (int i = 0; i < lines.Length; i++)
|
||||||
{
|
{
|
||||||
map.Add(new List<int>());
|
map.Add(new List<int>());
|
||||||
for (var j = 0; j < lines[i].Length; j++)
|
for (int j = 0; j < lines[i].Length; j++)
|
||||||
map[i].Add(Convert.ToInt32(lines[i][j].ToString()));
|
map[i].Add(Convert.ToInt32(lines[i][j].ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,37 +6,34 @@ public class Day9
|
||||||
{
|
{
|
||||||
public Day9()
|
public Day9()
|
||||||
{
|
{
|
||||||
var moves = new List<(char, int)>();
|
Console.WriteLine("Day9 Solution");
|
||||||
|
List<(char, int)> moves = new List<(char, int)>();
|
||||||
File.ReadAllLines("inputs/day9.txt").ToList().ForEach(line =>
|
File.ReadAllLines("inputs/day9.txt").ToList().ForEach(line =>
|
||||||
{
|
{
|
||||||
var split = line.Split(" ");
|
string[] split = line.Split(" ");
|
||||||
moves.Add((Convert.ToChar(split[0]), Convert.ToInt32(split[1])));
|
moves.Add((Convert.ToChar(split[0]), Convert.ToInt32(split[1])));
|
||||||
});
|
});
|
||||||
Console.WriteLine($@"
|
Console.WriteLine($"Part1 Result: {GetPositionCount(moves, 2)}");
|
||||||
Day9 Solution
|
Console.WriteLine($"Part2 Result: {GetPositionCount(moves, 10)}");
|
||||||
Part1 Result: {GetPositionCount(moves, 2)}
|
Console.WriteLine("\n=============================\n");
|
||||||
Part2 Result: {GetPositionCount(moves, 10)}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GetPositionCount(List<(char, int)> moves, int knots)
|
private static int GetPositionCount(List<(char, int)> moves, int knots)
|
||||||
{
|
{
|
||||||
var currentPositions = new List<List<int>>();
|
List<List<int>> currentPositions = new List<List<int>>();
|
||||||
currentPositions.Fill(knots, new List<int>(new[] { 0, 0 }));
|
currentPositions.Fill(knots, new List<int>(new[]{0,0}));
|
||||||
var tailHistory = new HashSet<(int, int)>();
|
HashSet<(int, int)> tailHistory = new HashSet<(int, int)>();
|
||||||
|
|
||||||
foreach (var move in moves)
|
foreach ((char, int) move in moves)
|
||||||
for (var moveN = 0; moveN < move.Item2; moveN++)
|
for (int moveN = 0; moveN < move.Item2; moveN++)
|
||||||
{
|
{
|
||||||
var vector = GetVector(move.Item1);
|
int[] vector = GetVector(move.Item1);
|
||||||
var previousTailPosition = currentPositions[0].ToArray();
|
int[] previousTailPosition = currentPositions[0].ToArray();
|
||||||
currentPositions[0] = UpdateHead(vector, currentPositions[0]);
|
currentPositions[0] = UpdateHead(vector, currentPositions[0]);
|
||||||
for (var tailN = 0; tailN < knots - 1; tailN++)
|
for (int tailN = 0; tailN < knots-1; tailN++)
|
||||||
{
|
{
|
||||||
var nextPreviousTailPosition = currentPositions[tailN + 1].ToArray();
|
int[] nextPreviousTailPosition = currentPositions[tailN + 1].ToArray();
|
||||||
currentPositions[tailN + 1] = UpdateTail(currentPositions[tailN], currentPositions[tailN + 1],
|
currentPositions[tailN + 1] = UpdateTail(currentPositions[tailN], currentPositions[tailN + 1], previousTailPosition);
|
||||||
previousTailPosition);
|
|
||||||
previousTailPosition = nextPreviousTailPosition;
|
previousTailPosition = nextPreviousTailPosition;
|
||||||
if (tailN == knots - 2)
|
if (tailN == knots - 2)
|
||||||
tailHistory.Add((currentPositions[knots - 1][0], currentPositions[knots - 1][1]));
|
tailHistory.Add((currentPositions[knots - 1][0], currentPositions[knots - 1][1]));
|
||||||
|
@ -53,10 +50,9 @@ Part2 Result: {GetPositionCount(moves, 10)}
|
||||||
return new List<int> { currentPosition[0], currentPosition[1] };
|
return new List<int> { currentPosition[0], currentPosition[1] };
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<int> UpdateTail(List<int> currentHeadPosition, List<int> currentTailPosition,
|
private static List<int> UpdateTail(List<int> currentHeadPosition, List<int> currentTailPosition, int[] previousTailPosition)
|
||||||
int[] previousTailPosition)
|
|
||||||
{
|
{
|
||||||
var head = new List<int>
|
List<int> head = new List<int>
|
||||||
{
|
{
|
||||||
currentHeadPosition[0] - previousTailPosition[0],
|
currentHeadPosition[0] - previousTailPosition[0],
|
||||||
currentHeadPosition[1] - previousTailPosition[1]
|
currentHeadPosition[1] - previousTailPosition[1]
|
||||||
|
@ -73,7 +69,7 @@ Part2 Result: {GetPositionCount(moves, 10)}
|
||||||
currentTailPosition[1] + head[1]
|
currentTailPosition[1] + head[1]
|
||||||
};
|
};
|
||||||
|
|
||||||
var difference = new List<int>
|
List<int> difference = new List<int>
|
||||||
{
|
{
|
||||||
currentHeadPosition[0] - currentTailPosition[0],
|
currentHeadPosition[0] - currentTailPosition[0],
|
||||||
currentHeadPosition[1] - currentTailPosition[1]
|
currentHeadPosition[1] - currentTailPosition[1]
|
||||||
|
|
|
@ -4,12 +4,6 @@ public static class Loader2022
|
||||||
{
|
{
|
||||||
public static void Load()
|
public static void Load()
|
||||||
{
|
{
|
||||||
/* Year 2022
|
|
||||||
*
|
|
||||||
* Solutions in C# for the 2022 Advent of Code
|
|
||||||
* Slower solutions are commented
|
|
||||||
*/
|
|
||||||
|
|
||||||
new Day1();
|
new Day1();
|
||||||
new Day2();
|
new Day2();
|
||||||
new Day3();
|
new Day3();
|
||||||
|
@ -17,10 +11,8 @@ public static class Loader2022
|
||||||
new Day5();
|
new Day5();
|
||||||
new Day6();
|
new Day6();
|
||||||
new Day7();
|
new Day7();
|
||||||
// new Day8();
|
// new Day8(); -- Commented because it's a slow solution
|
||||||
new Day9();
|
new Day9();
|
||||||
new Day10();
|
new Day10();
|
||||||
// new Day11();
|
|
||||||
// new Day12();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,56 +0,0 @@
|
||||||
namespace AdventOfCode.Year2023;
|
|
||||||
|
|
||||||
public class Day1
|
|
||||||
{
|
|
||||||
private static string[] Input = File.ReadAllLines("inputs/Year2023/day1.txt");
|
|
||||||
|
|
||||||
private static Dictionary<string, int> Part1Numbers = new Dictionary<string, int>() {
|
|
||||||
{"1", 1},
|
|
||||||
{"2", 2},
|
|
||||||
{"3", 3},
|
|
||||||
{"4", 4},
|
|
||||||
{"5", 5},
|
|
||||||
{"6", 6},
|
|
||||||
{"7", 7},
|
|
||||||
{"8", 8},
|
|
||||||
{"9", 9},
|
|
||||||
};
|
|
||||||
|
|
||||||
private static Dictionary<string, int> Part2Numbers = new Dictionary<string, int>(Part1Numbers) {
|
|
||||||
{"one", 1},
|
|
||||||
{"two", 2},
|
|
||||||
{"three", 3},
|
|
||||||
{"four", 4},
|
|
||||||
{"five", 5},
|
|
||||||
{"six", 6},
|
|
||||||
{"seven", 7},
|
|
||||||
{"eight", 8},
|
|
||||||
{"nine", 9},
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void Run()
|
|
||||||
{
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day1 Solution
|
|
||||||
Part1 Result: {Solve(Part1Numbers)}
|
|
||||||
Part2 Result: {Solve(Part2Numbers)}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Solve(Dictionary<string, int> numbers)
|
|
||||||
=> Input.Select(line =>
|
|
||||||
{
|
|
||||||
int first = numbers.Select(num => (index: line.IndexOf(num.Key), val: num.Value))
|
|
||||||
.Where(num => num.index >= 0)
|
|
||||||
.MinBy(num => num.index)
|
|
||||||
.val;
|
|
||||||
|
|
||||||
int last = numbers.Select(num => (index: line.LastIndexOf(num.Key), val: num.Value))
|
|
||||||
.Where(num => num.index >= 0)
|
|
||||||
.MaxBy(num => num.index)
|
|
||||||
.val;
|
|
||||||
|
|
||||||
return first * 10 + last;
|
|
||||||
}).Sum();
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
namespace AdventOfCode.Year2023;
|
|
||||||
|
|
||||||
public static class Day2
|
|
||||||
{
|
|
||||||
private static List<string> Input = File.ReadAllLines("inputs/Year2023/day2.txt").ToList();
|
|
||||||
|
|
||||||
private class Game
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
public List<Dictionary<string, int>> Sets { get; set; } = new List<Dictionary<string, int>>();
|
|
||||||
}
|
|
||||||
private static List<Game> Games = new List<Game>();
|
|
||||||
|
|
||||||
public static void Run()
|
|
||||||
{
|
|
||||||
ParseGames();
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day2 Solution
|
|
||||||
Part1 Result: {Part1()}
|
|
||||||
Part2 Result: {Part2()}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Part1()
|
|
||||||
{
|
|
||||||
int sum = 0;
|
|
||||||
|
|
||||||
foreach (var game in Games)
|
|
||||||
{
|
|
||||||
foreach (var set in game.Sets)
|
|
||||||
if (set["red"] > 12 || set["green"] > 13 || set["blue"] > 14) goto cont;
|
|
||||||
sum += game.Id;
|
|
||||||
cont: continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Part2()
|
|
||||||
{
|
|
||||||
int sum = 0;
|
|
||||||
|
|
||||||
foreach (var game in Games)
|
|
||||||
{
|
|
||||||
Dictionary<string, int> minimum = new Dictionary<string, int> {
|
|
||||||
{"red", 0},
|
|
||||||
{"green", 0},
|
|
||||||
{"blue", 0}
|
|
||||||
};
|
|
||||||
foreach (var set in game.Sets)
|
|
||||||
{
|
|
||||||
foreach (var color in set.Keys)
|
|
||||||
{
|
|
||||||
if (minimum[color] < set[color]) minimum[color] = set[color];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sum += minimum.Values.ToArray().Product();
|
|
||||||
}
|
|
||||||
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ParseGames()
|
|
||||||
{
|
|
||||||
foreach (var line in Input)
|
|
||||||
{
|
|
||||||
Game game = new Game();
|
|
||||||
|
|
||||||
string[] game_sets = line.Split(": ");
|
|
||||||
game.Id = Convert.ToInt32(game_sets[0].Split(" ")[1]);
|
|
||||||
|
|
||||||
string[] sets = game_sets[1].Split("; ");
|
|
||||||
|
|
||||||
foreach (var setStr in sets)
|
|
||||||
{
|
|
||||||
Dictionary<string, int> set = new Dictionary<string, int>();
|
|
||||||
foreach (var color in setStr.Split(", "))
|
|
||||||
{
|
|
||||||
set.Add(color.Split(" ")[1], Convert.ToInt32(color.Split(" ")[0]));
|
|
||||||
}
|
|
||||||
if (!set.ContainsKey("red")) set.Add("red", 0);
|
|
||||||
if (!set.ContainsKey("green")) set.Add("green", 0);
|
|
||||||
if (!set.ContainsKey("blue")) set.Add("blue", 0);
|
|
||||||
game.Sets.Add(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
Games.Add(game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int Product(this int[] array)
|
|
||||||
{
|
|
||||||
int result = 1;
|
|
||||||
foreach (var e in array)
|
|
||||||
result *= e;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace AdventOfCode.Year2023;
|
|
||||||
|
|
||||||
public static class Day4
|
|
||||||
{
|
|
||||||
private class Card
|
|
||||||
{
|
|
||||||
public int CardNumber { get; set; }
|
|
||||||
public int ValidNumbers { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Card> Cards = new();
|
|
||||||
private static double Sum;
|
|
||||||
|
|
||||||
public static void Run()
|
|
||||||
{
|
|
||||||
File.ReadAllLines("inputs/Year2023/day4.txt").ToList().ForEach(line =>
|
|
||||||
{
|
|
||||||
Card card = new Card();
|
|
||||||
card.CardNumber = Convert.ToInt32(Regex.Split(line.Split(": ")[0], @"\s+").Last());
|
|
||||||
string[] cardNumbers = Regex.Split(line.Split(": ")[1], @"\s+\|\s+");
|
|
||||||
int[] winningNumbers = Regex.Split(cardNumbers.First(), @"\W+").Where(x => !string.IsNullOrEmpty(x)).Select(x => Convert.ToInt32(x)).ToArray();
|
|
||||||
int[] numbers = Regex.Split(cardNumbers.Last(), @"\W+").Where(x => !string.IsNullOrEmpty(x)).Select(x => Convert.ToInt32(x)).ToArray();
|
|
||||||
card.ValidNumbers = 0;
|
|
||||||
numbers.ToList().ForEach(number => card.ValidNumbers += winningNumbers.Contains(number) ? 1 : 0);
|
|
||||||
Cards.Add(card);
|
|
||||||
});
|
|
||||||
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day4 Solution
|
|
||||||
Part1 Result: {Part1()}
|
|
||||||
Part2 Result: {Part2()}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double Part1()
|
|
||||||
{
|
|
||||||
Sum = 0;
|
|
||||||
Cards.ForEach(card => Sum += card.ValidNumbers > 0 ? Math.Pow(2, card.ValidNumbers - 1) : 0);
|
|
||||||
return Sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double Part2()
|
|
||||||
{
|
|
||||||
Sum = 0;
|
|
||||||
|
|
||||||
Dictionary<int, int> CardInstances = new();
|
|
||||||
Cards.ForEach(card => CardInstances.Add(card.CardNumber, 1));
|
|
||||||
Cards.ForEach(card =>
|
|
||||||
{
|
|
||||||
for (int i = card.CardNumber + 1; i <= card.CardNumber + card.ValidNumbers; i++)
|
|
||||||
CardInstances[i] += CardInstances[card.CardNumber];
|
|
||||||
|
|
||||||
Sum += CardInstances[card.CardNumber];
|
|
||||||
});
|
|
||||||
|
|
||||||
return Sum;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
namespace AdventOfCode.Year2023;
|
|
||||||
|
|
||||||
public static class Day5
|
|
||||||
{
|
|
||||||
private class Converter
|
|
||||||
{
|
|
||||||
public string? Name { get; set; }
|
|
||||||
public long Start { get; set; }
|
|
||||||
public long End { get; set; }
|
|
||||||
public long Count { get; set; }
|
|
||||||
}
|
|
||||||
private static string[] MapTypes = { "seed-to-soil", "soil-to-fertilizer", "fertilizer-to-water", "water-to-light", "light-to-temperature", "temperature-to-humidity", "humidity-to-location", };
|
|
||||||
private static List<Converter> Converters = new List<Converter>();
|
|
||||||
|
|
||||||
private static string? CurrentMap;
|
|
||||||
|
|
||||||
public static void Run()
|
|
||||||
{
|
|
||||||
string[] input = File.ReadAllLines("inputs/Year2023/day5.txt")[2..].ToArray();
|
|
||||||
|
|
||||||
foreach (var line in input)
|
|
||||||
{
|
|
||||||
if (String.IsNullOrEmpty(line))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Char.IsLetter(line[0]))
|
|
||||||
{
|
|
||||||
CurrentMap = line.Split(" ")[0];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Converters.Add(new Converter
|
|
||||||
{
|
|
||||||
Name = CurrentMap,
|
|
||||||
Start = Convert.ToInt64(line.Split(" ")[1]),
|
|
||||||
End = Convert.ToInt64(line.Split(" ")[0]),
|
|
||||||
Count = Convert.ToInt64(line.Split(" ")[2])
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine($@"
|
|
||||||
Day5 Solution
|
|
||||||
Part1 Result: {Part1()}
|
|
||||||
|
|
||||||
=============================");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long Part1()
|
|
||||||
{
|
|
||||||
List<long> seeds = File.ReadAllLines("inputs/Year2023/day5.txt")[0].Split(": ")[1].Split(" ").Select(long.Parse).ToList();
|
|
||||||
List<long> locations = new List<long>(seeds);
|
|
||||||
|
|
||||||
for (int i = 0; i < seeds.Count(); i++)
|
|
||||||
{
|
|
||||||
locations[i] = seeds[i];
|
|
||||||
foreach (var type in MapTypes)
|
|
||||||
{
|
|
||||||
Converter? conv = Converters.Where(c => c.Name == type).Where(c => (c.Start <= locations[i] && c.Start + c.Count > locations[i])).FirstOrDefault();
|
|
||||||
if (conv == null) continue;
|
|
||||||
locations[i] = conv.End + locations[i] - conv.Start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return locations.Min();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
namespace AdventOfCode.Year2023;
|
|
||||||
|
|
||||||
public static class Loader2023
|
|
||||||
{
|
|
||||||
public static void Load()
|
|
||||||
{
|
|
||||||
/* Year 2023
|
|
||||||
*
|
|
||||||
* Solutions in C# for the 2023 Advent of Code
|
|
||||||
* Slower solutions are commented
|
|
||||||
*/
|
|
||||||
|
|
||||||
Day1.Run();
|
|
||||||
Day2.Run();
|
|
||||||
Day4.Run();
|
|
||||||
Day5.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue