mirror of
https://github.com/parnic/advent-of-code-2024.git
synced 2025-06-16 12:30:13 -05:00
Day 19
Nothing a little caching can't solve!
This commit is contained in:
102
src/19.cs
Normal file
102
src/19.cs
Normal file
@ -0,0 +1,102 @@
|
||||
namespace aoc2024;
|
||||
|
||||
internal class Day19 : Day
|
||||
{
|
||||
private readonly List<string> towels = [];
|
||||
private readonly List<string> desiredPatterns = [];
|
||||
|
||||
internal override void Parse()
|
||||
{
|
||||
var lines = Util.Parsing.ReadAllLines($"{GetDay()}").ToList();
|
||||
towels.AddRange(lines[0].Split(", ", StringSplitOptions.RemoveEmptyEntries));
|
||||
for (int i = 2; i < lines.Count; i++)
|
||||
{
|
||||
desiredPatterns.Add(lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly HashSet<string> knownGood = [];
|
||||
private bool IsPossible(ReadOnlySpan<char> desired)
|
||||
{
|
||||
if (knownGood.Contains(desired.ToString()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var towel in towels)
|
||||
{
|
||||
if (!desired.StartsWith(towel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (desired.Length == towel.Length || IsPossible(desired[towel.Length..]))
|
||||
{
|
||||
knownGood.Add(towel);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, long> knownGoodCount = [];
|
||||
private long NumPossible(ReadOnlySpan<char> desired)
|
||||
{
|
||||
var desiredStr = desired.ToString();
|
||||
if (knownGoodCount.TryGetValue(desiredStr, out var count))
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
foreach (var towel in towels)
|
||||
{
|
||||
if (!desired.StartsWith(towel))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var numPossible = desired.Length != towel.Length ? NumPossible(desired[towel.Length..]) : 1;
|
||||
if (numPossible == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!knownGoodCount.TryAdd(desiredStr, numPossible))
|
||||
{
|
||||
knownGoodCount[desiredStr] += numPossible;
|
||||
}
|
||||
}
|
||||
|
||||
return knownGoodCount.GetValueOrDefault(desiredStr, 0);
|
||||
}
|
||||
|
||||
internal override string Part1()
|
||||
{
|
||||
int numPossible = 0;
|
||||
foreach (var desired in desiredPatterns)
|
||||
{
|
||||
if (IsPossible(desired))
|
||||
{
|
||||
numPossible++;
|
||||
}
|
||||
}
|
||||
|
||||
return $"Possible designs: <+white>{numPossible}";
|
||||
}
|
||||
|
||||
internal override string Part2()
|
||||
{
|
||||
long total = 0;
|
||||
foreach (var desired in desiredPatterns)
|
||||
{
|
||||
var combinations = NumPossible(desired);
|
||||
if (combinations > 0)
|
||||
{
|
||||
total += combinations;
|
||||
}
|
||||
}
|
||||
|
||||
return $"Ways to make each design: <+white>{total}";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user