-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay19.cs
More file actions
88 lines (74 loc) · 2.6 KB
/
Day19.cs
File metadata and controls
88 lines (74 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System.Collections.Immutable;
using System.Runtime.InteropServices.ComTypes;
using _2024.Utils;
namespace _2024._19;
public class Day19 : Base
{
private Dictionary<string, long> Cache { get; } = new();
private List<string> AvailableTowels { get; set; } = [];
private List<string> NeededPatterns { get; set; } = [];
public Day19(bool example) : base(example)
{
Day = "19";
ParseInput();
}
private void ParseInput()
{
string[] input = ReadInput();
foreach ((string line, int idx) in input.Enumerate())
{
switch (idx)
{
case 0:
AvailableTowels = [..line.Split(", ")];
continue;
case 1:
continue;
default:
NeededPatterns.Add(line);
break;
}
}
}
private long IsPatternPossible(string pattern)
{
if (Cache.TryGetValue(pattern, out long possible))
{
return possible;
}
if (pattern.Length == 0)
{
Cache[pattern] = 1;
return 1;
}
Cache[pattern] = 0;
// before I had pattern.StartsWith(availableTowel), this is roughly 2000ms slower than pattern[..availableTowel.Length] == availableTowel
foreach (string availableTowel in AvailableTowels.Where(availableTowel => availableTowel.Length <= pattern.Length && pattern[..availableTowel.Length] == availableTowel))
{
string subPattern = pattern[availableTowel.Length..];
Cache[pattern] += IsPatternPossible(subPattern);
}
// loop above could be replaced with this linq expression:
/*
Cache[pattern] = AvailableTowels
.Where(availableTowel =>
availableTowel.Length <= pattern.Length && pattern[..availableTowel.Length] == availableTowel)
.Select(availableTowel => IsPatternPossible(pattern[availableTowel.Length..])).Sum();
*/
return Cache[pattern];
}
public override object PartOne()
{
return NeededPatterns.Count(neededPattern => IsPatternPossible(neededPattern) > 0);
}
public override object PartTwo()
{
return NeededPatterns.Sum(IsPatternPossible);
}
public override void Reset()
{
// removing this line makes part 2 use the cache build from part 1
// effectively making it run instantly
Cache.Clear();
}
}