Completed Day 1
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace AdventOfCode2024.Input;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a text parser that outputs a specific type
|
||||
/// given a text stream
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type that will be parsed</typeparam>
|
||||
public interface IParser<T> where T : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses the stream and returns an object
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns>The object</returns>
|
||||
public Task<T> ParseAsync(Stream input);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace AdventOfCode2024.Input.Parsers;
|
||||
|
||||
public abstract class TextLineParser<U> : IParser<IList<U>> where U : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses a line to the given Entity type
|
||||
/// </summary>
|
||||
/// <param name="line">Line in the form of a string</param>
|
||||
/// <returns>The parsed entity</returns>
|
||||
protected abstract U ParseLine(string line);
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IList<U>> ParseAsync(Stream input)
|
||||
{
|
||||
using StreamReader reader = new StreamReader(input);
|
||||
List<U> entities = [];
|
||||
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
string? line = await reader.ReadLineAsync();
|
||||
if (line != null)
|
||||
{
|
||||
entities.Add(ParseLine(line));
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Day1", "Day1\Day1.csproj", "{B3CC14A1-DFE9-4D6B-832E-849968515E74}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdventOfCode2024.Input", "AdventOfCode2024.Input\AdventOfCode2024.Input.csproj", "{25106B70-A5DC-466A-9A1B-4CA33E2D7FC9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B3CC14A1-DFE9-4D6B-832E-849968515E74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B3CC14A1-DFE9-4D6B-832E-849968515E74}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B3CC14A1-DFE9-4D6B-832E-849968515E74}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B3CC14A1-DFE9-4D6B-832E-849968515E74}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{25106B70-A5DC-466A-9A1B-4CA33E2D7FC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{25106B70-A5DC-466A-9A1B-4CA33E2D7FC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{25106B70-A5DC-466A-9A1B-4CA33E2D7FC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{25106B70-A5DC-466A-9A1B-4CA33E2D7FC9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,28 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AdventOfCode2024.Input\AdventOfCode2024.Input.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\..\input\day1.txt">
|
||||
<Link>input\day1.txt</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\input\day1sample.txt">
|
||||
<Link>input\day1sample.txt</Link>
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="..\..\input\_placeholder">
|
||||
<Link>input\_placeholder</Link>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,70 @@
|
||||
namespace Day1;
|
||||
|
||||
// Advent of Code 2024
|
||||
// Day 1
|
||||
// James Plante (jwplante)
|
||||
|
||||
class DayOne
|
||||
{
|
||||
private static async Task PartOne()
|
||||
{
|
||||
await using FileStream inputStream = File.OpenRead("input/day1.txt");
|
||||
PairParser parser = new();
|
||||
|
||||
IList<(int, int)> entries = await parser.ParseAsync(inputStream);
|
||||
|
||||
// Given the parsed entries, add them to two new lists and sort them
|
||||
List<int> leftList = [];
|
||||
List<int> rightList = [];
|
||||
foreach ((int left, int right) in entries)
|
||||
{
|
||||
leftList.Add(left);
|
||||
rightList.Add(right);
|
||||
}
|
||||
leftList.Sort();
|
||||
rightList.Sort();
|
||||
|
||||
// Convert back into pairs of (smallest, smallest), (secondSmallest, ...
|
||||
List<(int, int)> sortedPairs = leftList
|
||||
.Zip(rightList, (left, right) => (left, right))
|
||||
.ToList();
|
||||
|
||||
long totalDistance = 0;
|
||||
foreach ((int left, int right) in sortedPairs)
|
||||
{
|
||||
var lineDistance = Math.Abs(left - right);
|
||||
totalDistance += lineDistance;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Part 1: The total distance of the lines is {totalDistance}.");
|
||||
}
|
||||
|
||||
private static async Task PartTwo()
|
||||
{
|
||||
await using FileStream inputStream = File.OpenRead("input/day1.txt");
|
||||
PairParser parser = new();
|
||||
|
||||
IList<(int, int)> entries = await parser.ParseAsync(inputStream);
|
||||
|
||||
// Get the frequencies for the right list
|
||||
Dictionary<int, int> frequencies = [];
|
||||
foreach ((_, int right) in entries)
|
||||
{
|
||||
frequencies[right] = frequencies.GetValueOrDefault(right) + 1;
|
||||
}
|
||||
|
||||
long similarityScore = 0;
|
||||
foreach ((int left, _) in entries)
|
||||
{
|
||||
var intermediateScore = left * frequencies.GetValueOrDefault(left);
|
||||
similarityScore += intermediateScore;
|
||||
}
|
||||
Console.WriteLine($"Part 2: The total similarity score is {similarityScore}.");
|
||||
}
|
||||
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
await PartOne();
|
||||
await PartTwo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using AdventOfCode2024.Input.Parsers;
|
||||
|
||||
namespace Day1;
|
||||
|
||||
/// <summary>
|
||||
/// Parses a Stream line by line for pairs of integers
|
||||
/// </summary>
|
||||
public class PairParser : TextLineParser<(int, int)>
|
||||
{
|
||||
protected override (int, int) ParseLine(string line)
|
||||
{
|
||||
var pair = line.Split(" ", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (pair.Length < 2)
|
||||
{
|
||||
throw new ArgumentException("Invalid line");
|
||||
}
|
||||
|
||||
var entryOneParsed = int.TryParse(pair[0], out var entryOne);
|
||||
var entryTwoParsed = int.TryParse(pair[1], out var entryTwo);
|
||||
if (!entryOneParsed || !entryTwoParsed)
|
||||
{
|
||||
throw new ArgumentException("Invalid line");
|
||||
}
|
||||
|
||||
return (entryOne, entryTwo);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user