diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2f99098 --- /dev/null +++ b/.vscode/launch.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ff6ee0c --- /dev/null +++ b/.vscode/tasks.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/AdventOfCode.sln b/AdventOfCode.sln index f4f2125..674fbdd 100644 --- a/AdventOfCode.sln +++ b/AdventOfCode.sln @@ -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 diff --git a/Directory.Build.props b/Directory.Build.props index 2047dee..ff785ed 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - true + $(MSBuildThisFileDirectory)artifacts \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index 3e3b132..a81f256 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,6 +7,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + \ No newline at end of file diff --git a/src/2024/01/Program.cs b/src/2024/01/Program.cs new file mode 100644 index 0000000..d9bbb7e --- /dev/null +++ b/src/2024/01/Program.cs @@ -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 left = []; + List 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 left = []; + Dictionary 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 handler) +{ + int entries = 0; + using var fileReader = new StreamReader(file); + Span 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); +} diff --git a/src/2024/01/aoc-2024-01.csproj b/src/2024/01/aoc-2024-01.csproj new file mode 100644 index 0000000..8aeb71a --- /dev/null +++ b/src/2024/01/aoc-2024-01.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + aoc_2024_01 + enable + enable + + + diff --git a/src/2024/02/Program.cs b/src/2024/02/Program.cs new file mode 100644 index 0000000..1f7abf5 --- /dev/null +++ b/src/2024/02/Program.cs @@ -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 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 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 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); +} diff --git a/src/2024/02/aoc-2024-02.csproj b/src/2024/02/aoc-2024-02.csproj new file mode 100644 index 0000000..6d1cba6 --- /dev/null +++ b/src/2024/02/aoc-2024-02.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + aoc_2024_02 + enable + enable + + + \ No newline at end of file diff --git a/src/2024/03/Program.cs b/src/2024/03/Program.cs new file mode 100644 index 0000000..b09b451 --- /dev/null +++ b/src/2024/03/Program.cs @@ -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\((?\d+),(?\d+)\)")] + private static partial Regex MulPattern(); +} + + +class FileExistsAttribute : ValidationAttribute +{ + public override bool IsValid(object? value) => value is string path && File.Exists(path); +} diff --git a/src/2024/03/aoc-2024-03.csproj b/src/2024/03/aoc-2024-03.csproj new file mode 100644 index 0000000..96ca86f --- /dev/null +++ b/src/2024/03/aoc-2024-03.csproj @@ -0,0 +1,11 @@ + + + + Exe + net9.0 + aoc_2024_03 + enable + enable + + + \ No newline at end of file diff --git a/src/2024/04/Program.cs b/src/2024/04/Program.cs new file mode 100644 index 0000000..12d9f79 --- /dev/null +++ b/src/2024/04/Program.cs @@ -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, IMultiplyOperators +{ + 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); +} diff --git a/src/2024/04/aoc-2024-04.csproj b/src/2024/04/aoc-2024-04.csproj new file mode 100644 index 0000000..a47f4d3 --- /dev/null +++ b/src/2024/04/aoc-2024-04.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + aoc_2024_04 + enable + enable + + + diff --git a/src/2024/05/Program.cs b/src/2024/05/Program.cs new file mode 100644 index 0000000..521210f --- /dev/null +++ b/src/2024/05/Program.cs @@ -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 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.Create((x, y) => + { + return orderingRules.Contains(new(x, y)) ? -1 + : orderingRules.Contains(new(y, x)) ? 1 + : 0; + }); + + List 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); +} diff --git a/src/2024/05/aoc-2024-05.csproj b/src/2024/05/aoc-2024-05.csproj new file mode 100644 index 0000000..9202d77 --- /dev/null +++ b/src/2024/05/aoc-2024-05.csproj @@ -0,0 +1,11 @@ + + + + Exe + net8.0 + aoc_2024_05 + enable + enable + + + diff --git a/src/2024/Directory.Build.props b/src/2024/Directory.Build.props new file mode 100644 index 0000000..68d915b --- /dev/null +++ b/src/2024/Directory.Build.props @@ -0,0 +1,18 @@ + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + \ No newline at end of file