Challenges up to 2024.05
This commit is contained in:
parent
229f9326d1
commit
326bef2755
16 changed files with 709 additions and 2 deletions
52
.vscode/launch.json
vendored
Normal file
52
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "aoc-2024-01 Debug",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "dotnet: build aoc-2024-01",
|
||||
"program": "${workspaceFolder}/artifacts/bin/aoc-2024-01/debug/aoc-2024-01.dll",
|
||||
"args": ["part-one", "data/2024/01/input.txt"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "aoc-2024-02 Debug",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "dotnet: build aoc-2024-02",
|
||||
"program": "${workspaceFolder}/artifacts/bin/aoc-2024-02/debug/aoc-2024-02.dll",
|
||||
"args": ["part-two", "data/2024/02/dev.txt"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "aoc-2024-03 Debug",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "dotnet: build aoc-2024-03",
|
||||
"program": "${workspaceFolder}/artifacts/bin/aoc-2024-03/debug/aoc-2024-03.dll",
|
||||
"args": ["part-two", "data/2024/03/dev2.txt"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "aoc-2024-04 Debug",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "dotnet: build aoc-2024-04",
|
||||
"program": "${workspaceFolder}/artifacts/bin/aoc-2024-04/debug/aoc-2024-04.dll",
|
||||
"args": ["part-one", "data/2024/04/dev.txt"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"stopAtEntry": false,
|
||||
"console": "internalConsole"
|
||||
}
|
||||
]
|
||||
}
|
||||
39
.vscode/tasks.json
vendored
Normal file
39
.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "dotnet",
|
||||
"task": "build aoc-2024-01.csproj",
|
||||
"file": "src/2024/01/aoc-2024-01.csproj",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "dotnet: build aoc-2024-01"
|
||||
},
|
||||
{
|
||||
"type": "dotnet",
|
||||
"task": "build aoc-2024-02.csproj",
|
||||
"file": "src/2024/02/aoc-2024-02.csproj",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "dotnet: build aoc-2024-02"
|
||||
},
|
||||
{
|
||||
"type": "dotnet",
|
||||
"task": "build aoc-2024-03.csproj",
|
||||
"file": "src/2024/03/aoc-2024-03.csproj",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "dotnet: build aoc-2024-03"
|
||||
},
|
||||
{
|
||||
"type": "dotnet",
|
||||
"task": "build aoc-2024-04.csproj",
|
||||
"file": "src/2024/04/aoc-2024-04.csproj",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "dotnet: build aoc-2024-04"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,7 +1,55 @@
|
|||
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2024", "2024", "{37CA8017-085A-4F6A-BADB-535F929C10B9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aoc-2024-01", "src\2024\01\aoc-2024-01.csproj", "{FAF70800-E2C3-4AD7-B433-86C1F20380F7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aoc-2024-02", "src\2024\02\aoc-2024-02.csproj", "{8B563C17-E24D-46F0-A98D-1533DC183C6B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aoc-2024-03", "src\2024\03\aoc-2024-03.csproj", "{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aoc-2024-04", "src\2024\04\aoc-2024-04.csproj", "{49021FCE-1CA9-430F-99B2-8E5C14A48394}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aoc-2024-05", "src\2024\05\aoc-2024-05.csproj", "{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FAF70800-E2C3-4AD7-B433-86C1F20380F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FAF70800-E2C3-4AD7-B433-86C1F20380F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FAF70800-E2C3-4AD7-B433-86C1F20380F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FAF70800-E2C3-4AD7-B433-86C1F20380F7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8B563C17-E24D-46F0-A98D-1533DC183C6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8B563C17-E24D-46F0-A98D-1533DC183C6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8B563C17-E24D-46F0-A98D-1533DC183C6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8B563C17-E24D-46F0-A98D-1533DC183C6B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{49021FCE-1CA9-430F-99B2-8E5C14A48394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{49021FCE-1CA9-430F-99B2-8E5C14A48394}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{49021FCE-1CA9-430F-99B2-8E5C14A48394}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{49021FCE-1CA9-430F-99B2-8E5C14A48394}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{FAF70800-E2C3-4AD7-B433-86C1F20380F7} = {37CA8017-085A-4F6A-BADB-535F929C10B9}
|
||||
{8B563C17-E24D-46F0-A98D-1533DC183C6B} = {37CA8017-085A-4F6A-BADB-535F929C10B9}
|
||||
{D6DAA79C-6B82-46E7-90CD-73D0A3196B8A} = {37CA8017-085A-4F6A-BADB-535F929C10B9}
|
||||
{49021FCE-1CA9-430F-99B2-8E5C14A48394} = {37CA8017-085A-4F6A-BADB-535F929C10B9}
|
||||
{D108A6AB-B974-4BD9-B97A-CB1D1A2F3920} = {37CA8017-085A-4F6A-BADB-535F929C10B9}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
|
||||
<UseArtifactsOutput>true</UseArtifactsOutput>
|
||||
<ArtifactsPath>$(MSBuildThisFileDirectory)artifacts</ArtifactsPath>
|
||||
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -7,6 +7,10 @@
|
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageVersion>
|
||||
<PackageVersion Include="Polyfill" Version="7.8.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageVersion>
|
||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
76
src/2024/01/Program.cs
Normal file
76
src/2024/01/Program.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using ConsoleAppFramework;
|
||||
|
||||
var builder = ConsoleApp.Create();
|
||||
builder.Add("part-one", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
List<int> left = [];
|
||||
List<int> right = [];
|
||||
|
||||
int entries = ReadFile(file, (l, r) =>
|
||||
{
|
||||
left.Add(l);
|
||||
right.Add(r);
|
||||
});
|
||||
|
||||
left.Sort();
|
||||
right.Sort();
|
||||
int rolling = 0;
|
||||
for (int i = 0; i < entries; i++)
|
||||
{
|
||||
rolling += Math.Abs(left[i] - right[i]);
|
||||
}
|
||||
|
||||
Console.WriteLine($"Total distance: {rolling}");
|
||||
});
|
||||
builder.Add("part-two", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
List<int> left = [];
|
||||
Dictionary<int, int> right = [];
|
||||
|
||||
int entries = ReadFile(file, (l, r) =>
|
||||
{
|
||||
left.Add(l);
|
||||
CollectionsMarshal.GetValueRefOrAddDefault(right, r, out _)++;
|
||||
});
|
||||
|
||||
int similarity = 0;
|
||||
for (int i = 0; i < entries; i++)
|
||||
{
|
||||
if (right.TryGetValue(left[i], out var count))
|
||||
{
|
||||
similarity += left[i] * count;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Similarity: {similarity}");
|
||||
});
|
||||
builder.Run(args);
|
||||
|
||||
static int ReadFile(string file, Action<int, int> handler)
|
||||
{
|
||||
int entries = 0;
|
||||
using var fileReader = new StreamReader(file);
|
||||
Span<Range> parse = stackalloc Range[3];
|
||||
while (fileReader.ReadLine() is { } line)
|
||||
{
|
||||
if (line.AsSpan().Split(parse, ' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) != 2)
|
||||
{
|
||||
Console.WriteLine($"Skipping Line {line}");
|
||||
continue;
|
||||
}
|
||||
|
||||
entries += 1;
|
||||
handler(
|
||||
int.Parse(line.AsSpan(parse[0])),
|
||||
int.Parse(line.AsSpan(parse[1])));
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
class FileExistsAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object? value) => value is string path && File.Exists(path);
|
||||
}
|
||||
11
src/2024/01/aoc-2024-01.csproj
Normal file
11
src/2024/01/aoc-2024-01.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>aoc_2024_01</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
94
src/2024/02/Program.cs
Normal file
94
src/2024/02/Program.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
using System.Buffers;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
using ConsoleAppFramework;
|
||||
|
||||
var builder = ConsoleApp.Create();
|
||||
builder.Add("part-one", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Safe Routes: {ReadFile(file, false)}");
|
||||
});
|
||||
builder.Add("part-two", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Safe Routes: {ReadFile(file, true)}");
|
||||
});
|
||||
builder.Run(args);
|
||||
|
||||
static int ReadFile(string file, bool dampening)
|
||||
{
|
||||
int result = 0;
|
||||
using var fileReader = new StreamReader(file);
|
||||
ArrayBufferWriter<int> distances = new(8);
|
||||
while (fileReader.ReadLine() is { } line)
|
||||
{
|
||||
distances.ResetWrittenCount();
|
||||
int? previous = null;
|
||||
foreach (var valueRange in line.AsSpan().Split(' '))
|
||||
{
|
||||
var sep = line.AsSpan(valueRange);
|
||||
if (sep.IsWhiteSpace())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tmp = previous;
|
||||
previous = int.Parse(sep);
|
||||
if (tmp is not null)
|
||||
{
|
||||
distances.GetSpan(1)[0] = previous.Value - tmp.Value;
|
||||
distances.Advance(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Check(distances.WrittenSpan))
|
||||
{
|
||||
result++;
|
||||
}
|
||||
else if (dampening)
|
||||
{
|
||||
// This is ugly.
|
||||
// Should've used Vertex/Edge-data structure.
|
||||
if (Check(distances.WrittenSpan[1..]) || Check(distances.WrittenSpan[..^1]))
|
||||
{
|
||||
Console.WriteLine($"Dropped one front/end for {line}");
|
||||
result++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < distances.WrittenCount - 1; i++)
|
||||
{
|
||||
Span<int> merge = [.. distances.WrittenSpan[(i + 1)..]];
|
||||
merge[0] += distances.WrittenSpan[i];
|
||||
int[] check = [.. distances.WrittenSpan[..i], .. merge];
|
||||
if (Check(check))
|
||||
{
|
||||
result++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
static bool Check(in ReadOnlySpan<int> distances)
|
||||
{
|
||||
int sign = 0;
|
||||
foreach (ref readonly var distance in distances)
|
||||
{
|
||||
if (Math.Abs(distance) is < 1 or > 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sign += Math.Sign(distance);
|
||||
}
|
||||
|
||||
return Math.Abs(sign) == distances.Length;
|
||||
}
|
||||
}
|
||||
|
||||
class FileExistsAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object? value) => value is string path && File.Exists(path);
|
||||
}
|
||||
11
src/2024/02/aoc-2024-02.csproj
Normal file
11
src/2024/02/aoc-2024-02.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>aoc_2024_02</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
61
src/2024/03/Program.cs
Normal file
61
src/2024/03/Program.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ConsoleAppFramework;
|
||||
|
||||
partial class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var builder = ConsoleApp.Create();
|
||||
builder.Add("part-one", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, true)}");
|
||||
});
|
||||
builder.Add("part-two", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, false)}");
|
||||
});
|
||||
builder.Run(args);
|
||||
}
|
||||
|
||||
static int ReadFile(string file, bool forceEnable)
|
||||
{
|
||||
var pattern = MulPattern();
|
||||
int result = 0;
|
||||
|
||||
using (var fileReader = new StreamReader(file))
|
||||
{
|
||||
bool state = true;
|
||||
while (fileReader.ReadLine() is { } line)
|
||||
{
|
||||
foreach (var matchRange in pattern.EnumerateMatches(line))
|
||||
{
|
||||
var match = line.AsSpan(matchRange.Index, matchRange.Length);
|
||||
Console.Out.WriteLine(match);
|
||||
if (match.StartsWith("do"))
|
||||
{
|
||||
state = matchRange.Length == 4;
|
||||
}
|
||||
else if (forceEnable || state) /* Definitely mul */
|
||||
{
|
||||
var r = pattern.Match(line, matchRange.Index, matchRange.Length);
|
||||
result += int.Parse(r.Groups[1].ValueSpan, NumberStyles.None) * int.Parse(r.Groups[2].ValueSpan, NumberStyles.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"do(?:n't)?\(\)|mul\((?<left>\d+),(?<right>\d+)\)")]
|
||||
private static partial Regex MulPattern();
|
||||
}
|
||||
|
||||
|
||||
class FileExistsAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object? value) => value is string path && File.Exists(path);
|
||||
}
|
||||
11
src/2024/03/aoc-2024-03.csproj
Normal file
11
src/2024/03/aoc-2024-03.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>aoc_2024_03</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
177
src/2024/04/Program.cs
Normal file
177
src/2024/04/Program.cs
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using ConsoleAppFramework;
|
||||
|
||||
partial class Program
|
||||
{
|
||||
delegate int Handler(in FileGrid grid, Vector2I index);
|
||||
|
||||
static IndexBuffer s_directions = new()
|
||||
{
|
||||
[0] = new(1, 0),
|
||||
[1] = new(0, 1),
|
||||
[2] = new(0, -1),
|
||||
[3] = new(-1, 0),
|
||||
[4] = new(1, 1),
|
||||
[5] = new(1, -1),
|
||||
[6] = new(-1, 1),
|
||||
[7] = new(-1, -1),
|
||||
};
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var builder = ConsoleApp.Create();
|
||||
builder.Add("part-one", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, 'X', new(InnerHandler))}");
|
||||
|
||||
static int InnerHandler(in FileGrid grid, Vector2I index)
|
||||
{
|
||||
int result = 0;
|
||||
foreach (ref readonly Vector2I direction in s_directions)
|
||||
{
|
||||
if (!grid.IsValid(direction * 3 + index))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("MAS".AsSpan().SequenceEqual([
|
||||
grid[direction + index]!.Value,
|
||||
grid[direction * 2 + index]!.Value,
|
||||
grid[direction * 3 + index]!.Value]))
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
builder.Add("part-two", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, 'A', new(InnerHandler))}");
|
||||
|
||||
static int InnerHandler(in FileGrid grid, Vector2I index)
|
||||
{
|
||||
return (grid[index + s_directions[7]], grid[index + s_directions[4]]) is ('M', 'S') or ('S', 'M') &&
|
||||
(grid[index + s_directions[6]], grid[index + s_directions[5]]) is ('M', 'S') or ('S', 'M')
|
||||
? 1
|
||||
: 0;
|
||||
}
|
||||
});
|
||||
builder.Run(args);
|
||||
}
|
||||
|
||||
static int ReadFile(string file, char activator, Handler handler)
|
||||
{
|
||||
int result = 0;
|
||||
using (var fileView = MemoryMappedFile.CreateFromFile(file, FileMode.Open))
|
||||
using (var accessor = fileView.CreateViewAccessor())
|
||||
{
|
||||
FileGrid grid = new(accessor);
|
||||
var length = grid.Width * grid.Height;
|
||||
for (var ci = 0; ci < length; ci++)
|
||||
{
|
||||
Vector2I index = new(ci / grid.Width, ci % grid.Width);
|
||||
if (grid[index] != activator)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result += handler(grid, index);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
readonly record struct Vector2I(int X, int Y) : IAdditionOperators<Vector2I, Vector2I, Vector2I>, IMultiplyOperators<Vector2I, int, Vector2I>
|
||||
{
|
||||
public Vector2I((int x, int y) index) : this(index.x, index.y)
|
||||
{
|
||||
}
|
||||
|
||||
public static Vector2I operator +(Vector2I left, Vector2I right)
|
||||
{
|
||||
return new(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
public static Vector2I operator *(Vector2I left, int right)
|
||||
{
|
||||
return new(left.X * right, left.Y * right);
|
||||
}
|
||||
}
|
||||
|
||||
[InlineArray(8)]
|
||||
struct IndexBuffer
|
||||
{
|
||||
private Vector2I _element0;
|
||||
|
||||
[UnscopedRef]
|
||||
public ref Vector2I this[int i] => ref this[i];
|
||||
}
|
||||
|
||||
record struct FileGrid
|
||||
{
|
||||
private readonly MemoryMappedViewAccessor _accessor;
|
||||
private readonly int _stride;
|
||||
|
||||
public int Width { get; }
|
||||
|
||||
public int Height { get; }
|
||||
|
||||
public readonly char? this[Vector2I index] => this[index.X, index.Y];
|
||||
|
||||
public readonly char? this[int x, int y]
|
||||
{
|
||||
get
|
||||
{
|
||||
return IsValid(x, y) ? (char)_accessor.ReadByte(y * _stride + x) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public FileGrid(MemoryMappedViewAccessor accessor)
|
||||
{
|
||||
_accessor = accessor;
|
||||
bool hasNewLine = false;
|
||||
for (int i = 0; i < accessor.Capacity; i++)
|
||||
{
|
||||
if ((char)accessor.ReadByte(i) is '\r' or '\n')
|
||||
{
|
||||
if (!hasNewLine)
|
||||
{
|
||||
Width = i;
|
||||
}
|
||||
|
||||
hasNewLine = true;
|
||||
}
|
||||
else if (hasNewLine)
|
||||
{
|
||||
_stride = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Height = (int)((accessor.Capacity + Width) / _stride);
|
||||
}
|
||||
|
||||
public readonly bool IsValid(int x, int y)
|
||||
{
|
||||
return !(x < 0 || x >= Width || y < 0 || y >= Height);
|
||||
}
|
||||
|
||||
public readonly bool IsValid(Vector2I index)
|
||||
{
|
||||
return IsValid(index.X, index.Y);
|
||||
}
|
||||
}
|
||||
|
||||
class FileExistsAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object? value) => value is string path && File.Exists(path);
|
||||
}
|
||||
11
src/2024/04/aoc-2024-04.csproj
Normal file
11
src/2024/04/aoc-2024-04.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>aoc_2024_04</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
83
src/2024/05/Program.cs
Normal file
83
src/2024/05/Program.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
using ConsoleAppFramework;
|
||||
|
||||
var builder = ConsoleApp.Create();
|
||||
builder.Add("part-one", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, false)}");
|
||||
});
|
||||
builder.Add("part-two", static ([Argument, FileExists] string file) =>
|
||||
{
|
||||
Console.WriteLine($"Result: {ReadFile(file, true)}");
|
||||
});
|
||||
builder.Run(args);
|
||||
|
||||
static int ReadFile(string file, bool sort)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
using (var fileReader = new StreamReader(file))
|
||||
{
|
||||
HashSet<OrderingRule> orderingRules = [];
|
||||
while (fileReader.ReadLine() is { } line && !string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
var sep = line.IndexOf('|');
|
||||
var left = short.Parse(line.AsSpan(0, sep));
|
||||
var right = short.Parse(line.AsSpan(sep + 1));
|
||||
orderingRules.Add(new(left, right));
|
||||
}
|
||||
|
||||
var ruleComparer = Comparer<int>.Create((x, y) =>
|
||||
{
|
||||
return orderingRules.Contains(new(x, y)) ? -1
|
||||
: orderingRules.Contains(new(y, x)) ? 1
|
||||
: 0;
|
||||
});
|
||||
|
||||
List<int> pages = [];
|
||||
while (fileReader.ReadLine() is { } line)
|
||||
{
|
||||
pages.Clear();
|
||||
foreach (var element in line.AsSpan().Split(','))
|
||||
{
|
||||
pages.Add(int.Parse(line.AsSpan(element)));
|
||||
}
|
||||
|
||||
bool valid = true;
|
||||
for (int i = 0; valid && i < pages.Count; i++)
|
||||
{
|
||||
for (int j = 0; valid && j < i; j++)
|
||||
{
|
||||
var left = pages[j];
|
||||
var right = pages[i];
|
||||
if (orderingRules.Contains(new(right, left)))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((valid && sort) || !(valid || sort))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sort)
|
||||
{
|
||||
pages.Sort(ruleComparer);
|
||||
}
|
||||
Console.WriteLine(string.Join(',', pages));
|
||||
result += pages[pages.Count / 2];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
readonly record struct OrderingRule(int Left, int Right);
|
||||
|
||||
class FileExistsAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object? value) => value is string path && File.Exists(path);
|
||||
}
|
||||
11
src/2024/05/aoc-2024-05.csproj
Normal file
11
src/2024/05/aoc-2024-05.csproj
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RootNamespace>aoc_2024_05</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
18
src/2024/Directory.Build.props
Normal file
18
src/2024/Directory.Build.props
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<Project>
|
||||
<Import
|
||||
Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"
|
||||
Condition="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../')) != ''" />
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="ConsoleAppFramework">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Polyfill">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue