-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathProgram.cs
65 lines (51 loc) · 1.87 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
using AdventOfCode.Common;
char[,] map = Resources.GetInputFileLines().ParseAsArray();
var symbols = new List<Symbol>();
var numbers = new List<Number>();
for (int row = 0; row < map.Width(); row++)
{
for (int col = 0; col < map.Height(); col++)
{
var c = map[row, col];
switch (c)
{
case '.':
break;
case >= '0' and <= '9':
var number = new Number(c - '0', row, col, col);
while (++col < map.Height() && char.IsDigit(map[row, col]))
{
number = new Number(number.Value * 10 + map[row, col] - '0', number.Row, number.Col, col);
}
--col;
numbers.Add(number);
break;
default:
symbols.Add(new Symbol(c, row, col));
break;
}
}
}
IEnumerable<int> adjacentParts = numbers
.Where(number => symbols.Any(symbol => AreAdjacent(number, symbol)))
.Select(p => p.Value);
IEnumerable<long> gearScores = symbols
.Select(symbol => numbers
.Where(number => AreAdjacent(number, symbol)).ToList())
.Where(adjacent => adjacent.Count == 2)
.Select(adjacent => adjacent.Aggregate(1L, (a, p) => a * p.Value));
Console.WriteLine($"Part 1: {adjacentParts.Sum()}");
Console.WriteLine($"Part 2: {gearScores.Sum()}");
static bool AreAdjacent(Number number, Symbol symbol)
{
// Row around
if (!Around(number.Row, symbol.Row)) return false;
// Contains
if (number.Col <= symbol.Col && number.EndCol >= symbol.Col) return true;
// Starts/ends near
if (Around(number.Col, symbol.Col) || Around(number.EndCol, symbol.Col)) return true;
return false;
}
static bool Around(int x, int y) => Math.Abs(y - x) <= 1;
file record Symbol(char Sign, int Row, int Col);
file record Number(int Value, int Row, int Col, int EndCol);