-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProgram.cs
76 lines (61 loc) · 2.07 KB
/
Program.cs
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
using System.Text.RegularExpressions;
using AdventOfCode.Common;
using Range = AdventOfCode.Common.Range;
var lines = Resources.GetInputFileLines();
var headerPattern = new Regex(@"(?<from>[a-z]+)\-to\-(?<to>[a-z]+) map:");
var seeds = lines.First().ParseLongNumbersOut();
var categories = new Dictionary<string, Category>();
Category category = null!;
foreach (var line in lines.Skip(1))
{
var match = headerPattern.Match(line);
if (match.Success)
{
if (category != null)
{
categories.Add(category.From, category);
}
var to = match.Groups["to"].Value;
category = new Category(
match.Groups["from"].Value,
to == "location" ? null : to,
[]);
continue;
}
if (line.ParseLongNumbersOut() is [long dest, long source, long length])
{
category.Rules.Add(new(dest, source, length));
}
}
categories.Add(category.From, category);
// Quite ashamed of this but it did finish in a couple of minutes
var part2 = seeds
.GroupsOf(2)
.Select(pair => new Range(pair.First(), pair.First() + pair.Last() - 1))
.Select(range => range.Enumerate().AsParallel().Select(i => GetLocation(i)).Min())
.Min();
Console.WriteLine($"Part 1: {seeds.Select(s => GetLocation(s)).Min()}");
Console.WriteLine($"Part 2: {part2}");
long GetLocation(long seed, string categoryName = "seed")
{
var category = categories[categoryName];
var mappedValue = category.Map(seed);
return category.To is null
? mappedValue
: GetLocation(mappedValue, category.To);
}
file record Rule : Range
{
public Rule(long destination, long source, long rangeLength)
: base(source, source + rangeLength - 1)
{
Destination = destination;
}
public long Destination { get; }
public long? Map(long number) => Contains(number) ? number + Destination - Start : null;
}
file record Category(string From, string? To, IList<Rule> Rules)
{
public long Map(long number)
=> Rules.FirstOrDefault(r => r.Map(number) != null)?.Map(number) ?? number;
}