Compare commits

...

10 Commits

Author SHA1 Message Date
Tiago Garcia 70a86f783a
[2023] Add Day5 Part1
Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-09 21:17:03 +00:00
Tiago Garcia 343f1f08ba
[2023] Update Day4
Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-05 17:22:28 +00:00
Tiago Garcia d999774ec1
[2023] Finish Day4
- Yes, did skip day 3 💀

Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-04 17:28:27 +00:00
Tiago Garcia 0ddb0fd959
[2023] Update Day1
Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-03 14:40:40 +00:00
Tiago Garcia 8c20f2ce7e
AoC 2023: Day 2
- Also updated to .NET 8.0

Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-02 16:20:10 +00:00
Tiago Garcia a677039025
Update README.md
Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-02 01:48:40 +00:00
Tiago Garcia 496975da67
Advent of Code 2023 started :D
Signed-off-by: TiagoRG <tiago.rgarcia@ua.pt>
2023-12-02 01:39:47 +00:00
Tiago Garcia 8f4ed4d132
[2022] Day 12 added
--> Solution is slow as hell
--> Could probably use new algorithm
2023-06-24 22:27:02 +01:00
Tiago Garcia 47b55aaaec
Some refactoring 2023-06-24 22:26:39 +01:00
Tiago Garcia bd026a7ff9
[2022] Day11 added 2023-06-11 23:28:47 +01:00
25 changed files with 1021 additions and 316 deletions

4
.gitignore vendored
View File

@ -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
# Rider configuration directory # AdventOfCode input files
.idea/ inputs/
# User-specific files # User-specific files
*.rsuser *.rsuser

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

6
Makefile Normal file
View File

@ -0,0 +1,6 @@
.PHONY: build
build:
@dotnet build
@echo -e "\033c\nAdvent of Code\n\nBy: @TiagoRG\nGitHub: https://github.com/TiagoRG\n\n============================================================="
@dotnet run

View File

@ -1,9 +1,9 @@
using AdventOfCode.Year2022; using AdventOfCode.Year2023;
namespace AdventOfCode; namespace AdventOfCode;
internal static class Program internal static class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
=> Loader2022.Load(); => Loader2023.Load();
} }

View File

@ -1,15 +1,25 @@
# 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 2](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day2.cs) * [Day 1](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day1.cs)
* [Day 3](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day3.cs) * [Day 2](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day2.cs)
* [Day 4](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day4.cs) * [Day 3](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day3.cs)
* [Day 6](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day6.cs) * [Day 4](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day4.cs)
* [Day 7](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day7.cs) * [Day 6](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day6.cs)
* [Day 8](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day8.cs) * [Day 7](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day7.cs)
* [Day 9](https://github.com/TiagoRG/AdventOfCode/tree/main/AdventOfCode/Year2022/Day9.cs) * [Day 8](https://github.com/TiagoRG/AdventOfCode/blob/main/Year2022/Day8.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)

View File

@ -11,10 +11,10 @@ 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)
{ {
List<T> result = new List<T>(); var result = new List<T>();
if (endIndex == default) if (endIndex == default)
endIndex = list.Count; endIndex = list.Count;
for (int i = startIndex; i < endIndex; i++) for (var i = startIndex; i < endIndex; i++)
result.Add(list[i]); result.Add(list[i]);
return result; return result;
} }
@ -27,8 +27,8 @@ public static class LinqExtensions
/// <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)
{ {
List<T> result = new List<T>(); var result = new List<T>();
foreach (List<T> row in list) result.AddRange(row.Where((t, i) => i == column)); foreach (var row in list) result.AddRange(row.Where((t, i) => i == column));
return result; return result;
} }
@ -39,8 +39,8 @@ public static class LinqExtensions
/// <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)
{ {
List<T> reversed = new List<T>(); var reversed = new List<T>();
for (int i = 0; i < list.Count; i++) for (var i = 0; i < list.Count; i++)
reversed.Add(list[list.Count - 1 - i]); reversed.Add(list[list.Count - 1 - i]);
return reversed; return reversed;
} }
@ -52,8 +52,8 @@ public static class LinqExtensions
/// <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)
{ {
List<T> ret = new List<T>(original.Count); var ret = new List<T>(original.Count);
foreach (T element in original) foreach (var element in original)
ret.Add(element); ret.Add(element);
return ret; return ret;
} }
@ -63,8 +63,8 @@ public static class LinqExtensions
where TValue : ICloneable where TValue : ICloneable
where TKey : notnull where TKey : notnull
{ {
Dictionary<TKey, TValue> ret = new Dictionary<TKey, TValue>(original.Count, original.Comparer); var ret = new Dictionary<TKey, TValue>(original.Count, original.Comparer);
foreach (KeyValuePair<TKey, TValue> entry in original) foreach (var 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
{ {
Dictionary<TKey, List<TValue>> ret = new Dictionary<TKey, List<TValue>>(original.Count, original.Comparer); var ret = new Dictionary<TKey, List<TValue>>(original.Count, original.Comparer);
foreach (KeyValuePair<TKey, List<TValue>> entry in original) foreach (var 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 (int i = 0; i < count; i++) for (var 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 (int i = 0; i < count; i++) for (var 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)
{ {
List<T> backup = list.Clone(); var backup = list.Clone();
list.Clear(); list.Clear();
for (int i = 0; i < list.Count; i++) list.Add(i == index ? element : list[i]); for (var i = 0; i < list.Count; i++) list.Add(i == index ? element : list[i]);
} }
} }

View File

@ -18,7 +18,7 @@ public static class MathExtensions
{ {
Convert.ToInt32(s); Convert.ToInt32(s);
} }
catch (FormatException ignored) catch (FormatException)
{ {
return false; return false;
} }
@ -28,18 +28,20 @@ public static class MathExtensions
public static ulong ProductOfMax(this List<ulong> list, int maxCount) public static ulong ProductOfMax(this List<ulong> list, int maxCount)
{ {
List<ulong> maxList = new List<ulong>(maxCount); var maxList = new List<ulong>(maxCount);
foreach (ulong number in list) foreach (var number in list)
{ {
if (maxList.Count < maxList.Capacity) if (maxList.Count < maxList.Capacity)
{
maxList.Add(number); maxList.Add(number);
else }
if (number > maxList.Min()) else if (number > maxList.Min())
{ {
maxList.RemoveAt(0); maxList.RemoveAt(0);
maxList.Add(number); maxList.Add(number);
} }
maxList.Sort(); maxList.Sort();
} }
@ -50,8 +52,8 @@ public static class MathExtensions
public static int LeastCommonMultiplier(this List<int> list) public static int LeastCommonMultiplier(this List<int> list)
{ {
int lcm = 1; var lcm = 1;
foreach (int i in list) foreach (var i in list)
lcm *= i / MathTools.GreatCommonDivider(lcm, i); lcm *= i / MathTools.GreatCommonDivider(lcm, i);
return lcm; return lcm;
} }

View File

@ -6,10 +6,12 @@ public class Day1
public Day1() public Day1()
{ {
Console.WriteLine("\nDay1 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day1 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
@ -19,30 +21,21 @@ public class Day1
private static int Part2() private static int Part2()
{ {
List<int> top3 = new List<int>(); return CaloriesPerElf.Order().Reverse().ToArray()[..3].Sum();
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()
{ {
string[] calories = File.ReadAllLines("inputs/day1.txt"); var calories = File.ReadAllLines("inputs/day1.txt");
int[] caloriesPerDay = new int[calories.Length]; var caloriesPerDay = new int[calories.Length];
var index = 0; var index = 0;
foreach (string calorie in calories) foreach (var calorie in calories)
{
if (calorie == "") if (calorie == "")
index++; index++;
else else
caloriesPerDay[index] += Convert.ToInt32(calorie); caloriesPerDay[index] += Convert.ToInt32(calorie);
}
int elfCount = caloriesPerDay.ToList().IndexOf(0); var elfCount = caloriesPerDay.ToList().IndexOf(0);
return caloriesPerDay.ToList().GetRange(0, elfCount); return caloriesPerDay.ToList().GetRange(0, elfCount);
} }
} }

View File

@ -1,42 +1,43 @@
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($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day10 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
{ {
int sum = 0; var sum = 0;
int currentPower = 1; var currentPower = 1;
int listIndex = 0; var listIndex = 0;
int addPower = 0; var addPower = 0;
int skipCycles = 0; var skipCycles = 0;
for (int cycle = 1; cycle <= 220; cycle++) for (var cycle = 1; cycle <= 220; cycle++)
{ {
if (skipCycles == 0) if (skipCycles == 0)
{ {
currentPower += addPower; currentPower += addPower;
string line = CommandsList[listIndex]; var line = CommandsList[listIndex];
string cmd = line.Substring(0, 4); var 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;
@ -47,33 +48,35 @@ public class Day10
private static string Part2() private static string Part2()
{ {
char[] crt = new char[40*6]; var crt = new char[40 * 6];
int registerPos = 0; var registerPos = 0;
int listIndex = 0; var listIndex = 0;
int movePos = 0; var movePos = 0;
int skipCycles = 0; var skipCycles = 0;
for (int cycle = 0; cycle < 240; cycle++) for (var cycle = 0; cycle < 240; cycle++)
{ {
if (skipCycles == 0) if (skipCycles == 0)
{ {
registerPos += movePos; registerPos += movePos;
string line = CommandsList[listIndex]; var line = CommandsList[listIndex];
string cmd = line[..4]; var 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--;
}
char[] sprite = CreateSprite(registerPos); var sprite = CreateSprite(registerPos);
crt[cycle] = sprite[cycle % 40]; crt[cycle] = sprite[cycle % 40];
} }
string result = "\n"; var result = "\n";
int charI = 0; var charI = 0;
crt.ToList().ForEach(c => crt.ToList().ForEach(c =>
{ {
result += c.ToString(); result += c.ToString();
@ -86,9 +89,9 @@ public class Day10
private static char[] CreateSprite(int registerPos) private static char[] CreateSprite(int registerPos)
{ {
char[] result = new char[40]; var result = new char[40];
for (int i = 0; i < 40; i++) for (var 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;
} }
} }

175
Year2022/Day11.cs Normal file
View File

@ -0,0 +1,175 @@
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
}
}

193
Year2022/Day12.cs Normal file
View File

@ -0,0 +1,193 @@
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
}
}

View File

@ -6,16 +6,18 @@ public class Day2
public Day2() public Day2()
{ {
Console.WriteLine("Day2 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day2 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
{ {
int score = 0; var score = 0;
foreach (string[] match in Matches) foreach (var match in Matches)
{ {
if (match[0] == "A") if (match[0] == "A")
{ {
@ -26,6 +28,7 @@ public class Day2
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")
@ -35,6 +38,7 @@ public class Day2
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")
@ -51,8 +55,8 @@ public class Day2
private static int Part2() private static int Part2()
{ {
int score = 0; var score = 0;
foreach (string[] match in Matches) foreach (var match in Matches)
{ {
if (match[0] == "A") if (match[0] == "A")
{ {
@ -63,6 +67,7 @@ public class Day2
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")
@ -72,6 +77,7 @@ public class Day2
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")
@ -88,8 +94,8 @@ public class Day2
private static List<string[]> LoadMatches() private static List<string[]> LoadMatches()
{ {
List<string[]> matches = new List<string[]>(); var matches = new List<string[]>();
foreach (string line in File.ReadAllLines("inputs/day2.txt")) foreach (var line in File.ReadAllLines("inputs/day2.txt"))
matches.Add(line.Split(" ")); matches.Add(line.Split(" "));
return matches; return matches;
} }

View File

@ -6,55 +6,54 @@ public class Day3
public Day3() public Day3()
{ {
Console.WriteLine("Day3 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day3 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
{ {
int sum = 0; var sum = 0;
List<char> duplicates = new List<char>(); var duplicates = new List<char>();
foreach (string backpack in Backpacks) foreach (var backpack in Backpacks)
{ {
int compartmentSize = backpack.Length / 2; var compartmentSize = backpack.Length / 2;
List<char> itemsInCompartment1 = new List<char>(); var itemsInCompartment1 = new List<char>();
List<char> itemsInCompartment2 = new List<char>(); var itemsInCompartment2 = new List<char>();
for (int i = 0; i < compartmentSize; i++) for (var i = 0; i < compartmentSize; i++)
itemsInCompartment1.Add(backpack[i]); itemsInCompartment1.Add(backpack[i]);
for (int i = compartmentSize; i < compartmentSize * 2; i++) for (var i = compartmentSize; i < compartmentSize * 2; i++)
itemsInCompartment2.Add(backpack[i]); itemsInCompartment2.Add(backpack[i]);
char duplicatedItem = itemsInCompartment1.Intersect(itemsInCompartment2).FirstOrDefault(); var duplicatedItem = itemsInCompartment1.Intersect(itemsInCompartment2).FirstOrDefault();
duplicates.Add(duplicatedItem); duplicates.Add(duplicatedItem);
} }
foreach (char duplicate in duplicates) foreach (var 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()
{ {
int sum = 0; var sum = 0;
List<List<string>> groups = new List<List<string>>(); var groups = new List<List<string>>();
for (int i = 0; i < Backpacks.Length; i+=3) for (var i = 0; i < Backpacks.Length; i += 3)
{ {
List<string> group = new List<string>(); var group = new List<string>();
for (int x = 0; x < 3; x++) for (var x = 0; x < 3; x++)
{
try try
{ {
group.Add(Backpacks[i + x]); group.Add(Backpacks[i + x]);
@ -63,26 +62,23 @@ public class Day3
{ {
break; break;
} }
}
if (group.All(x => x != "")) if (group.All(x => x != ""))
groups.Add(group); groups.Add(group);
} }
List<char> duplicates = new List<char>(); var duplicates = new List<char>();
foreach (List<string> group in groups) foreach (var group in groups)
{ {
string[] groupArray = group.ToArray(); var 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 (char duplicate in duplicates) foreach (var 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;
} }

View File

@ -4,12 +4,10 @@ public class Day4
{ {
public Day4() public Day4()
{ {
Console.WriteLine("Day4 Solution"); var lines = File.ReadAllLines("inputs/day4.txt");
var containedCount = 0;
string[] lines = File.ReadAllLines("inputs/day4.txt"); var intersectedCount = 0;
int containedCount = 0; foreach (var line in lines)
int intersectedCount = 0;
foreach (string line in lines)
{ {
if (IsContained(line)) if (IsContained(line))
containedCount++; containedCount++;
@ -17,30 +15,33 @@ public class Day4
intersectedCount++; intersectedCount++;
} }
Console.WriteLine($"Part1 Result: {containedCount}"); Console.WriteLine($@"
Console.WriteLine($"Part2 Result: {intersectedCount}"); Day4 Solution
Console.WriteLine("\n=============================\n"); Part1 Result: {containedCount}
Part2 Result: {intersectedCount}
=============================");
} }
private static bool IsContained(string line) private static bool IsContained(string line)
{ {
int[][] limits = GetLimits(line); var 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)
{ {
int[][] limits = GetLimits(line); var 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)
{ {
string[] pair = line.Split(","); var pair = line.Split(",");
string[] pair1 = pair[0].Split("-"); var pair1 = pair[0].Split("-");
string[] pair2 = pair[1].Split("-"); var 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]) },

View File

@ -6,56 +6,56 @@ public class Day5
{ {
private static readonly Dictionary<int, List<char>> Crates = new() private static readonly Dictionary<int, List<char>> Crates = new()
{ {
[1] = new(), [1] = new List<char>(),
[2] = new(), [2] = new List<char>(),
[3] = new(), [3] = new List<char>(),
[4] = new(), [4] = new List<char>(),
[5] = new(), [5] = new List<char>(),
[6] = new(), [6] = new List<char>(),
[7] = new(), [7] = new List<char>(),
[8] = new(), [8] = new List<char>(),
[9] = new() [9] = new List<char>()
}; };
private static readonly List<(int, int, int)> Moves = new(); private static readonly List<(int, int, int)> Moves = new();
public Day5() public Day5()
{ {
Console.WriteLine("Day5 Solution"); var input = File.ReadAllText("inputs/day5.txt").Split("\n\n");
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)
{ {
Dictionary<int, List<char>> crates = Crates.Clone(); var crates = Crates.Clone();
foreach ((int, int, int) move in Moves) foreach (var move in Moves)
{ {
List<char> cratesMoved = crates[move.Item2].Sublist(0, move.Item1); var cratesMoved = crates[move.Item2].Sublist(0, move.Item1);
for (int i = 0; i < move.Item1; i++) for (var i = 0; i < move.Item1; i++)
crates[move.Item2].Remove(crates[move.Item2][0]); crates[move.Item2].Remove(crates[move.Item2][0]);
foreach (char crate in part == Part.Part1 ? cratesMoved : cratesMoved.Reversed()) foreach (var crate in part == Part.Part1 ? cratesMoved : cratesMoved.Reversed())
crates[move.Item3].Insert(0, crate); crates[move.Item3].Insert(0, crate);
} }
string result = ""; var result = "";
foreach (List<char> crateList in crates.Values) foreach (var 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)
{ {
string[] crate_lines = crates.Split("\n"); var crate_lines = crates.Split("\n");
foreach (string line in crate_lines) foreach (var line in crate_lines)
{ {
int firstCrate = 0; var 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('['))
@ -68,18 +68,19 @@ public class Day5
private static void LoadMoves(string moves) private static void LoadMoves(string moves)
{ {
string[] move_lines = moves.Split("\n"); var move_lines = moves.Split("\n");
foreach (string line in move_lines) foreach (var line in move_lines)
{ {
string move = line.Substring(5); var move = line.Substring(5);
string[] moved = move.Split(" from "); var moved = move.Split(" from ");
string[] crates = moved[1].Split(" to "); var 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, Part2 Part1,
Part2
} }
} }

View File

@ -6,15 +6,17 @@ public class Day6
public Day6() public Day6()
{ {
Console.WriteLine("Day6 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {GetValidMarkerIndex(4)}"); Day6 Solution
Console.WriteLine($"Part2 Result: {GetValidMarkerIndex(14)}"); Part1 Result: {GetValidMarkerIndex(4)}
Console.WriteLine("\n=============================\n"); Part2 Result: {GetValidMarkerIndex(14)}
=============================");
} }
private static int? GetValidMarkerIndex(int size) private static int? GetValidMarkerIndex(int size)
{ {
for (int i = 0; i < Input.Length-size; i++) for (var 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;

View File

@ -6,18 +6,20 @@ public class Day7
public Day7() public Day7()
{ {
Console.WriteLine("Day7 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day7 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
{ {
int sum = 0; var sum = 0;
foreach (string path in Tree.Keys) foreach (var path in Tree.Keys)
{ {
int size = CalculateDirSize(path); var size = CalculateDirSize(path);
if (size <= 100000) if (size <= 100000)
sum += size; sum += size;
} }
@ -27,16 +29,13 @@ public class Day7
private static int Part2() private static int Part2()
{ {
int neededSpace = CalculateDirSize("/") - 40000000; var neededSpace = CalculateDirSize("/") - 40000000;
if (neededSpace <= 0) if (neededSpace <= 0) return 0;
{
return 0;
}
List<int> bigEnoughDir = new List<int>(); var bigEnoughDir = new List<int>();
foreach (string path in Tree.Keys) foreach (var path in Tree.Keys)
{ {
int size = CalculateDirSize(path); var size = CalculateDirSize(path);
if (size > neededSpace) if (size > neededSpace)
bigEnoughDir.Add(size); bigEnoughDir.Add(size);
} }
@ -47,11 +46,11 @@ public class Day7
private static int CalculateDirSize(string path) private static int CalculateDirSize(string path)
{ {
int size = 0; var size = 0;
List<string> dirContent = Tree[path]; var dirContent = Tree[path];
foreach (string content in dirContent) foreach (var content in dirContent)
{ {
string[] properties = content.Split(" "); var properties = content.Split(" ");
if (properties[0] == "dir") if (properties[0] == "dir")
size += CalculateDirSize(path + properties[1] + "/"); size += CalculateDirSize(path + properties[1] + "/");
else else
@ -63,39 +62,41 @@ public class Day7
private static Dictionary<string, List<string>> GetTree() private static Dictionary<string, List<string>> GetTree()
{ {
Dictionary<string, List<string>> tree = new Dictionary<string, List<string>>(); var tree = new Dictionary<string, List<string>>();
string currentPath = ""; var currentPath = "";
IEnumerable<string> input = File.ReadLines("inputs/day7.txt"); var input = File.ReadLines("inputs/day7.txt");
foreach (string line in input) foreach (var line in input)
{
if (line.StartsWith("$")) if (line.StartsWith("$"))
{ {
string[] cmdLine = line.Substring(2).Split(" "); var cmdLine = line.Substring(2).Split(" ");
if (cmdLine[0] == "cd") if (cmdLine[0] == "cd")
{ {
string dir = cmdLine[1]; var dir = cmdLine[1];
if (dir == "/") if (dir == "/")
{
currentPath = "/"; currentPath = "/";
}
else if (dir == "..") else if (dir == "..")
{ {
if (currentPath == "/") continue; if (currentPath == "/") continue;
int slashIndex = currentPath var 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
{ {
if (!tree.ContainsKey(currentPath)) if (!tree.ContainsKey(currentPath))
tree.Add(currentPath, new List<string>()); tree.Add(currentPath, new List<string>());
tree[currentPath].Add(line); tree[currentPath].Add(line);
} }
}
return tree; return tree;
} }

View File

@ -8,17 +8,19 @@ public class Day8
public Day8() public Day8()
{ {
Console.WriteLine("Day8 Solution"); Console.WriteLine($@"
Console.WriteLine($"Part1 Result: {Part1()}"); Day8 Solution
Console.WriteLine($"Part2 Result: {Part2()}"); Part1 Result: {Part1()}
Console.WriteLine("\n=============================\n"); Part2 Result: {Part2()}
=============================");
} }
private static int Part1() private static int Part1()
{ {
int count = 0; var count = 0;
for (int i = 0; i < TreeMap.Count; i++) for (var i = 0; i < TreeMap.Count; i++)
for (int j = 0; j < TreeMap[i].Count; j++) for (var 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]
@ -30,18 +32,18 @@ public class Day8
private static int Part2() private static int Part2()
{ {
int highestScore = 0; var highestScore = 0;
for (int i = 0; i < TreeMap.Count; i++) for (var i = 0; i < TreeMap.Count; i++)
for (int j = 0; j < TreeMap[i].Count; j++) for (var j = 0; j < TreeMap[i].Count; j++)
{ {
if (i == 0 || j == 0) continue; if (i == 0 || j == 0) continue;
int currentTree = TreeMap[i][j]; var currentTree = TreeMap[i][j];
int currentTreeScore = 1; var currentTreeScore = 1;
int directionCount = 0; var directionCount = 0;
for (int k = i - 1; k >= 0; k--) for (var k = i - 1; k >= 0; k--)
{ {
directionCount++; directionCount++;
if (TreeMap[k][j] >= currentTree) break; if (TreeMap[k][j] >= currentTree) break;
@ -50,7 +52,7 @@ public class Day8
currentTreeScore *= directionCount; currentTreeScore *= directionCount;
directionCount = 0; directionCount = 0;
for (int k = j - 1; k >= 0; k--) for (var k = j - 1; k >= 0; k--)
{ {
directionCount++; directionCount++;
if (TreeMap[i][k] >= currentTree) break; if (TreeMap[i][k] >= currentTree) break;
@ -59,7 +61,7 @@ public class Day8
currentTreeScore *= directionCount; currentTreeScore *= directionCount;
directionCount = 0; directionCount = 0;
for (int k = i + 1; k < TreeMap.Count; k++) for (var k = i + 1; k < TreeMap.Count; k++)
{ {
directionCount++; directionCount++;
if (TreeMap[k][j] >= currentTree) break; if (TreeMap[k][j] >= currentTree) break;
@ -68,7 +70,7 @@ public class Day8
currentTreeScore *= directionCount; currentTreeScore *= directionCount;
directionCount = 0; directionCount = 0;
for (int k = j + 1; k < TreeMap[i].Count; k++) for (var k = j + 1; k < TreeMap[i].Count; k++)
{ {
directionCount++; directionCount++;
if (TreeMap[i][k] >= currentTree) break; if (TreeMap[i][k] >= currentTree) break;
@ -83,14 +85,15 @@ public class Day8
private static List<List<int>> LoadMap() private static List<List<int>> LoadMap()
{ {
List<List<int>> map = new List<List<int>>(); var map = new List<List<int>>();
string[] lines = File.ReadAllLines("inputs/day8.txt"); var lines = File.ReadAllLines("inputs/day8.txt");
for (int i = 0; i < lines.Length; i++) for (var i = 0; i < lines.Length; i++)
{ {
map.Add(new List<int>()); map.Add(new List<int>());
for (int j = 0; j < lines[i].Length; j++) for (var 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;
} }
} }

View File

@ -6,34 +6,37 @@ public class Day9
{ {
public Day9() public Day9()
{ {
Console.WriteLine("Day9 Solution"); var moves = new List<(char, int)>();
List<(char, int)> moves = new List<(char, int)>();
File.ReadAllLines("inputs/day9.txt").ToList().ForEach(line => File.ReadAllLines("inputs/day9.txt").ToList().ForEach(line =>
{ {
string[] split = line.Split(" "); var 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($"Part1 Result: {GetPositionCount(moves, 2)}"); Console.WriteLine($@"
Console.WriteLine($"Part2 Result: {GetPositionCount(moves, 10)}"); Day9 Solution
Console.WriteLine("\n=============================\n"); Part1 Result: {GetPositionCount(moves, 2)}
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)
{ {
List<List<int>> currentPositions = new List<List<int>>(); var currentPositions = new List<List<int>>();
currentPositions.Fill(knots, new List<int>(new[] { 0, 0 })); currentPositions.Fill(knots, new List<int>(new[] { 0, 0 }));
HashSet<(int, int)> tailHistory = new HashSet<(int, int)>(); var tailHistory = new HashSet<(int, int)>();
foreach ((char, int) move in moves) foreach (var move in moves)
for (int moveN = 0; moveN < move.Item2; moveN++) for (var moveN = 0; moveN < move.Item2; moveN++)
{ {
int[] vector = GetVector(move.Item1); var vector = GetVector(move.Item1);
int[] previousTailPosition = currentPositions[0].ToArray(); var previousTailPosition = currentPositions[0].ToArray();
currentPositions[0] = UpdateHead(vector, currentPositions[0]); currentPositions[0] = UpdateHead(vector, currentPositions[0]);
for (int tailN = 0; tailN < knots-1; tailN++) for (var tailN = 0; tailN < knots - 1; tailN++)
{ {
int[] nextPreviousTailPosition = currentPositions[tailN + 1].ToArray(); var nextPreviousTailPosition = currentPositions[tailN + 1].ToArray();
currentPositions[tailN + 1] = UpdateTail(currentPositions[tailN], currentPositions[tailN + 1], previousTailPosition); currentPositions[tailN + 1] = UpdateTail(currentPositions[tailN], currentPositions[tailN + 1],
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]));
@ -50,9 +53,10 @@ public class Day9
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, int[] previousTailPosition) private static List<int> UpdateTail(List<int> currentHeadPosition, List<int> currentTailPosition,
int[] previousTailPosition)
{ {
List<int> head = new List<int> var head = new List<int>
{ {
currentHeadPosition[0] - previousTailPosition[0], currentHeadPosition[0] - previousTailPosition[0],
currentHeadPosition[1] - previousTailPosition[1] currentHeadPosition[1] - previousTailPosition[1]
@ -69,7 +73,7 @@ public class Day9
currentTailPosition[1] + head[1] currentTailPosition[1] + head[1]
}; };
List<int> difference = new List<int> var difference = new List<int>
{ {
currentHeadPosition[0] - currentTailPosition[0], currentHeadPosition[0] - currentTailPosition[0],
currentHeadPosition[1] - currentTailPosition[1] currentHeadPosition[1] - currentTailPosition[1]

View File

@ -4,6 +4,12 @@ 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();
@ -11,8 +17,10 @@ public static class Loader2022
new Day5(); new Day5();
new Day6(); new Day6();
new Day7(); new Day7();
// new Day8(); -- Commented because it's a slow solution // new Day8();
new Day9(); new Day9();
new Day10(); new Day10();
// new Day11();
// new Day12();
} }
} }

56
Year2023/Day1.cs Normal file
View File

@ -0,0 +1,56 @@
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();
}

99
Year2023/Day2.cs Normal file
View File

@ -0,0 +1,99 @@
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;
}
}

61
Year2023/Day4.cs Normal file
View File

@ -0,0 +1,61 @@
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;
}
}

66
Year2023/Day5.cs Normal file
View File

@ -0,0 +1,66 @@
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();
}
}

19
Year2023/Loader2023.cs Normal file
View File

@ -0,0 +1,19 @@
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();
}
}