Changed challange interface, updated code

This commit is contained in:
Rob 2024-11-30 11:18:43 +01:00
parent 2ade6fdb0f
commit 97d6a79643
24 changed files with 291 additions and 255 deletions

View File

@ -7,9 +7,7 @@ InputReader inputReader = new()
//IsDebug = true
};
//inputReader.SetInputByChallange(12);
IChallange challange = new Day19(inputReader);
IChallange challange = new Day12(inputReader);
Console.WriteLine($"Part 1: {await challange.GetSolutionPart1()}");

View File

@ -13,19 +13,13 @@ namespace AdventOfCode.Core
private int Year { get; set; }
private string InputFilePath => IsDebug ? DebugInputFileTemplate : string.Format(InputFileTemplate, Day, Year);
public InputReader() => SetInputByChallange();
public void SetInputByChallange()
public void SetInput(IChallange challange)
{
SetInputByChallange(DateTime.Now.Day, DateTime.Now.Year);
Day = challange.Day;
Year = challange.Year;
}
public void SetInputByChallange(int day)
{
SetInputByChallange(day, DateTime.Now.Year);
}
public void SetInputByChallange(int day, int year)
public void SetInput(int day, int year)
{
Day = day;
Year = year;

View File

@ -2,6 +2,9 @@
{
public interface IChallange
{
int Year { get; }
int Day { get; }
Task<string> GetSolutionPart1();
Task<string> GetSolutionPart2();

View File

@ -1,9 +1,18 @@
namespace AdventOfCode.Solutions._2023
{
public class Day00(InputReader reader) : IChallange
public class Day00 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 0;
public int Day => 0;
private readonly InputReader _inputReader;
public Day00(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
return string.Empty;

View File

@ -1,13 +1,20 @@
using AdventOfCode.Core;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day01(InputReader reader) : IChallange
public class Day01 : IChallange
{
private readonly List<string> NumberMapping = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
public int Year => 2023;
public int Day => 1;
private InputReader _inputReader = reader;
private readonly List<string> NumberMapping = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
private readonly InputReader _inputReader;
public Day01(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -31,8 +38,6 @@ namespace AdventOfCode.Solutions._2023
int sum = 0;
await foreach (string line in _inputReader.ReadAsStringLine())
{
string regex = @"(\d|one|two|three|four|five|six|seven|eight|nine)";
MatchCollection matchCollection = Regex.Matches(line, @"(\d)");
List<Match> captures = matchCollection.ToList();

View File

@ -1,11 +1,19 @@
using AdventOfCode.Core;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day02(InputReader reader) : IChallange
public class Day02: IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 2;
private readonly InputReader _inputReader;
public Day02(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,12 +1,19 @@
using AdventOfCode.Core;
using AdventOfCode.Core.Shared.Grid;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public partial class Day03(InputReader reader) : IChallange
public partial class Day03 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 3;
private readonly InputReader _inputReader;
public Day03(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
private class PartNumber
{

View File

@ -1,13 +1,19 @@
using AdventOfCode.Core;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day04(InputReader reader) : IChallange
public class Day04 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 4;
private Dictionary<int, int> _cardRuns = new Dictionary<int, int> { { 1, 1 } };
private readonly InputReader _inputReader;
public Day04(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
int total = 0;

View File

@ -1,11 +1,9 @@
using AdventOfCode.Core;
using AdventOfCode.Core.Shared.Grid;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day05(InputReader reader) : IChallange
public class Day05 : IChallange
{
private readonly InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 5;
public const string SeedSoil = "seed-to-soil map:";
public const string SoilFertilizer = "soil-to-fertilizer map:";
@ -15,6 +13,14 @@ namespace AdventOfCode.Solutions._2023
public const string TemperatureHumidity = "temperature-to-humidity map:";
public const string HumidityLocation = "humidity-to-location map:";
private readonly InputReader _inputReader;
public Day05(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
List<string> data = new(await _inputReader.ReadAsArrayString());

View File

@ -1,13 +1,19 @@
using AdventOfCode.Core;
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public partial class Day06(InputReader reader) : IChallange
public partial class Day06 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 6;
private readonly InputReader _inputReader;
public Day06(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,15 +1,22 @@
using AdventOfCode.Core;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day07(InputReader reader) : IChallange
public class Day07 : IChallange
{
private readonly InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 7;
private static readonly List<char> CardValues = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'];
private static readonly List<char> CardValuesJoker = ['J', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'Q', 'K', 'A'];
private enum SetRanks { High, OnePair, TwoPair, ThreeKind, FullHouse, FourKind, FiveKind }
private readonly InputReader _inputReader;
public Day07(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
return (await _inputReader.ReadAsArrayString())

View File

@ -1,12 +1,19 @@
using AdventOfCode.Core;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day08(InputReader reader) : IChallange
public class Day08 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 8;
private readonly InputReader _inputReader;
public Day08(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -16,7 +23,7 @@ namespace AdventOfCode.Solutions._2023
string route = lines.Current;
await lines.MoveNextAsync();
Dictionary<string, LeftRight> routes = new Dictionary<string, LeftRight>();
Dictionary<string, LeftRight> routes = [];
while(await lines.MoveNextAsync())
{
@ -47,7 +54,7 @@ namespace AdventOfCode.Solutions._2023
string route = lines.Current;
await lines.MoveNextAsync();
Dictionary<string, LeftRight> routes = new Dictionary<string, LeftRight>();
Dictionary<string, LeftRight> routes = [];
while (await lines.MoveNextAsync())
{

View File

@ -1,10 +1,17 @@
using AdventOfCode.Core;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day09(InputReader reader) : IChallange
public class Day09 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 9;
private readonly InputReader _inputReader;
public Day09(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,12 +1,17 @@
using AdventOfCode.Core;
using AdventOfCode.Core.Shared.Grid;
using System.Linq.Expressions;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day10(InputReader reader) : IChallange
public class Day10 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 10;
private readonly InputReader _inputReader;
public Day10(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -102,7 +107,7 @@ namespace AdventOfCode.Solutions._2023
public class Pipe : Point
{
public Pipe From { get; set; } = null;
public Pipe? From { get; set; } = null;
public int Steps { get; set; } = -1;

View File

@ -1,11 +1,19 @@
using AdventOfCode.Core;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day11(InputReader reader) : IChallange
public class Day11 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 11;
private readonly InputReader _inputReader;
public Day11(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,12 +1,17 @@
using AdventOfCode.Core;
using System.Linq;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public partial class Day12(InputReader reader) : IChallange
public partial class Day12 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 12;
private readonly InputReader _inputReader;
public Day12(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -16,11 +21,8 @@ namespace AdventOfCode.Solutions._2023
string[] splitted = line.Split(' ');
int[] groups = splitted[1].Split(',').Select(int.Parse).ToArray();
Console.Write(splitted[0]);
long possiblies = Possibilities2(splitted[0], groups, 0, 0);
Console.WriteLine($": {possiblies}");
long possiblies = Possibilities([], splitted[0], groups, 0, 0, 0);
total += possiblies;
//total += Possibilities(splitted[0], groups);
}
return total.ToString();
}
@ -31,132 +33,45 @@ namespace AdventOfCode.Solutions._2023
await foreach (string line in _inputReader.ReadAsStringLine())
{
string[] splitted = line.Split(' ');
var joinedLine = string.Join("?", new[] { splitted[0], splitted[0], splitted[0], splitted[0], splitted[0] });
var joinedLine = string.Join("?", [splitted[0], splitted[0], splitted[0], splitted[0], splitted[0]]);
int[] groups = splitted[1].Split(',').Select(int.Parse).ToArray();
int[] groupsTotal = groups.Concat(groups).Concat(groups).Concat(groups).Concat(groups).ToArray();
//total += Possibilities(splitted[0], groups);
Console.Write(joinedLine + " " + string.Join(",", new[] { splitted[1], splitted[1], splitted[1], splitted[1], splitted[1] }));
long possiblies = Possibilities2(joinedLine, groupsTotal, 0, 0);
Console.WriteLine($": {possiblies}");
long possiblies = Possibilities([], joinedLine, groupsTotal, 0, 0, 0);
total += possiblies;
}
return total.ToString();
}
private long Possibilities(string lineToValidate, int[] groups)
private static long Possibilities(Dictionary<(int, int, int), long> capturedCache, string stringToValidate, int[] captureGroups, int stringIndex, int groupIndex, int currentCaptureLength)
{
long total = 0;
if (lineToValidate.Contains('?'))
{
var regex = new Regex(Regex.Escape("?"));
total += Possibilities(regex.Replace(lineToValidate, ".", 1), groups);
total += Possibilities(regex.Replace(lineToValidate, "#", 1), groups);
if (capturedCache.TryGetValue((stringIndex, groupIndex, currentCaptureLength), out var possibilities))
return possibilities;
return total;
if (stringIndex == stringToValidate.Length) // End of string
return groupIndex == captureGroups.Length || (groupIndex == captureGroups.Length - 1 && captureGroups[groupIndex] == currentCaptureLength) ? 1 : 0;
possibilities = 0L;
if (stringToValidate[stringIndex] is '.' or '?') // Assuming '?' is '.'
{
if (currentCaptureLength == 0) // Start a capture
{
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex, 0); // Not in capture. Skip to next char
}
else if (currentCaptureLength == captureGroups[groupIndex]) // After a capture
{
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex + 1, 0); // Captured group. Go to next group
}
}
MatchCollection matches = GroupMatch().Matches(lineToValidate);
if (matches.Count == groups.Length &&
groups.Where((g, i) => matches[i].Length == g).Count() == groups.Length)
if (stringToValidate[stringIndex] is '#' or '?' && groupIndex < captureGroups.Length && currentCaptureLength < captureGroups[groupIndex]) // Assuming '?' is '#'
{
//Console.WriteLine($"{lineToValidate} is valid");
return 1;
possibilities += Possibilities(capturedCache, stringToValidate, captureGroups, stringIndex + 1, groupIndex, currentCaptureLength + 1); // In capture
}
else
return 0;
// Add the capture to the capture cache
capturedCache[(stringIndex, groupIndex, currentCaptureLength)] = possibilities;
return possibilities;
}
private long Possibilities2(string lineToValidate, int[] groups, int readIndex, int captureSize)
{
// if group index is 0 there are no captures and not captures running
if (readIndex < lineToValidate.Length)
{
int[] splitGroups = lineToValidate[..readIndex].Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray();
if (groups.Length < splitGroups.Length)
{
// we have more groups than expected
return 0;
}
if (lineToValidate.Length - readIndex < groups.Skip(splitGroups.Length).Sum() + groups.Length - splitGroups.Length - 1)
{
// there is not enough space to even fit the groups so reject
return 0;
}
// validate everything, including fixed groups
for (int i = 0; i < splitGroups.Length - 1; i++)
{
// all except the last must match
if (splitGroups[i] != groups[i])
{
return 0; // group lengths do not match, reject
}
}
// the last one is allowed to be smaller than the expected groups size
if (splitGroups.Any() && splitGroups[^1] > groups[splitGroups.Length - 1])
{
// if the last group is larger than allowed the line is invalid
return 0;
}
}
if (!lineToValidate.Contains('?')) // no more variations
{
int[] splitGroups = lineToValidate.Split('.', StringSplitOptions.RemoveEmptyEntries).Select(s => s.Length).ToArray();
if (splitGroups.Length != groups.Length)
{
// group amount does not match
return 0;
}
for (int i = 0; i < groups.Length; i++)
{
if (splitGroups[i] != groups[i])
{
return 0; // group lengths do not match, reject
}
}
// valid combos so valid
return 1;
}
long total = 0;
//go search for # or ?
for (int charIndex = readIndex; charIndex < lineToValidate.Length; charIndex++)
{
if (lineToValidate[charIndex] == '.')
{
captureSize = 0;
readIndex++;
continue;
}
if (lineToValidate[charIndex] == '#')
{
captureSize++;
readIndex++;
continue;
}
if (lineToValidate[charIndex] == '?')
{
var regex = new Regex(Regex.Escape("?"));
total += Possibilities2(regex.Replace(lineToValidate, "#", 1), groups, readIndex + 1, captureSize + 1);
total += Possibilities2(regex.Replace(lineToValidate, ".", 1), groups, readIndex + 1, captureSize);
return total;
}
}
return Possibilities2(lineToValidate, groups, readIndex + 1, captureSize);
}
[GeneratedRegex("#+")]
private static partial Regex GroupMatch();
}
}

View File

@ -1,12 +1,19 @@
using AdventOfCode.Core;
using AdventOfCode.Solutions._2023.Day_13;
using System.Data;
using AdventOfCode.Solutions._2023.Day_13;
namespace AdventOfCode.Solutions._2023
{
public class Day13(InputReader reader) : IChallange
public class Day13 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 13;
private readonly InputReader _inputReader;
public Day13(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,12 +1,19 @@
using AdventOfCode.Core;
using AdventOfCode.Core.Shared.Grid;
using System.Text;
using System.Text;
namespace AdventOfCode.Solutions._2023
{
public class Day14(InputReader reader) : IChallange
public class Day14 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 14;
private readonly InputReader _inputReader;
public Day14(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -67,7 +74,7 @@ namespace AdventOfCode.Solutions._2023
return totalWeight.ToString();
}
private HashSet<Point> MoveUp(HashSet<Point> bolders, HashSet<Point> cubes)
private static HashSet<Point> MoveUp(HashSet<Point> bolders, HashSet<Point> cubes)
{
HashSet<Point> boldersMoved = [];
foreach (Point bolder in bolders.OrderBy(bolder => bolder.Y) )
@ -88,7 +95,7 @@ namespace AdventOfCode.Solutions._2023
return boldersMoved;
}
private HashSet<Point> MoveDown(HashSet<Point> bolders, HashSet<Point> cubes, long ySize)
private static HashSet<Point> MoveDown(HashSet<Point> bolders, HashSet<Point> cubes, long ySize)
{
HashSet<Point> boldersMoved = [];
foreach (Point bolder in bolders.OrderByDescending(bolder => bolder.Y))
@ -107,7 +114,7 @@ namespace AdventOfCode.Solutions._2023
return boldersMoved;
}
private HashSet<Point> MoveLeft(HashSet<Point> bolders, HashSet<Point> cubes)
private static HashSet<Point> MoveLeft(HashSet<Point> bolders, HashSet<Point> cubes)
{
HashSet<Point> boldersMoved = [];
foreach (Point bolder in bolders.OrderBy(bolder => bolder.X))
@ -126,7 +133,7 @@ namespace AdventOfCode.Solutions._2023
return boldersMoved;
}
private HashSet<Point> MoveRight(HashSet<Point> bolders, HashSet<Point> cubes, long xSize)
private static HashSet<Point> MoveRight(HashSet<Point> bolders, HashSet<Point> cubes, long xSize)
{
HashSet<Point> boldersMoved = [];
foreach (Point bolder in bolders.OrderByDescending(bolder => bolder.X))

View File

@ -1,11 +1,19 @@
using AdventOfCode.Core;
using System.Text;
using System.Text;
namespace AdventOfCode.Solutions._2023
{
public class Day15(InputReader reader) : IChallange
public class Day15 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 15;
private readonly InputReader _inputReader;
public Day15(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,14 +1,20 @@
using AdventOfCode.Core.Shared.Grid;
namespace AdventOfCode.Solutions._2023
namespace AdventOfCode.Solutions._2023
{
public class Day16(InputReader reader) : IChallange
public class Day16 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 16;
private readonly InputReader _inputReader;
public Day16(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
Grid<Point> grid = await _inputReader.ReadToGrid<Point>();
Point? point = grid.TryGetNode(0, 0);
ISet<Point> set = Move(grid, new HashSet<Point>(), new HashSet<Point>(), point, Direction.Right);

View File

@ -1,8 +1,17 @@
namespace AdventOfCode.Solutions._2023
{
public class Day17(InputReader reader) : IChallange
public class Day17 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 17;
private readonly InputReader _inputReader;
public Day17(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,8 +1,17 @@
namespace AdventOfCode.Solutions._2023
{
public class Day18(InputReader reader) : IChallange
public class Day18 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 18;
private readonly InputReader _inputReader;
public Day18(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
@ -29,7 +38,6 @@
int total = set.Count;
int movedOver = 0;
char prev = '.';
//Console
for(long row = set.Min(d => d.Y); row <= set.Max(d => d.Y); row++)
{
@ -37,7 +45,6 @@
{
if (!set.Add(new(column, row)))
{
//Console.Write('#');
if (prev != '#')
movedOver++;
@ -45,7 +52,6 @@
continue;
}
//Console.Write('.');
if (movedOver % 2 == 1)
{
@ -53,7 +59,7 @@
total++;
}
}
//Console.WriteLine();
movedOver = 0;
prev = '.';
}
@ -65,7 +71,5 @@
{
return string.Empty;
}
}
}

View File

@ -1,11 +1,19 @@
using System.Reflection.Metadata.Ecma335;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace AdventOfCode.Solutions._2023
{
public class Day19(InputReader reader) : IChallange
public class Day19 : IChallange
{
private InputReader _inputReader = reader;
public int Year => 2023;
public int Day => 19;
private readonly InputReader _inputReader;
public Day19(InputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{

View File

@ -1,17 +1,13 @@
px{a<2006:qkq,m>2090:A,rfg}
pv{a>1716:R,A}
lnx{m>1548:A,A}
rfg{s<537:gd,x>2440:R,A}
qs{s>3448:A,lnx}
qkq{x<1416:A,crn}
crn{x>2662:A,R}
in{s<1351:px,qqz}
qqz{s>2770:qs,m<1801:hdj,R}
gd{a>3333:R,R}
hdj{m>838:A,pv}
{x=787,m=2655,a=1222,s=2876}
{x=1679,m=44,a=2067,s=496}
{x=2036,m=264,a=79,s=2244}
{x=2461,m=1339,a=466,s=291}
{x=2127,m=1623,a=2188,s=1013}
2413432311323
3215453535623
3255245654254
3446585845452
4546657867536
1438598798454
4457876987766
3637877979653
4654967986887
4564679986453
1224686865563
2546548887735
4322674655533