-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day05.cs
89 lines (75 loc) · 2.71 KB
/
Day05.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
77
78
79
80
81
82
83
84
85
86
87
88
89
using AdventOfCode.CSharp.Common;
using System;
namespace AdventOfCode.CSharp.Y2015.Solvers;
public class Day05 : ISolver
{
public static void Solve(ReadOnlySpan<byte> input, Solution solution)
{
int part1 = 0;
int part2 = 0;
foreach (Range lineRange in input.SplitLines())
{
ReadOnlySpan<byte> line = input[lineRange];
int numVowels = 0;
bool containsPair = false;
bool containsForbiddenPair = false;
// bitset which keeps track of seen characters.
// this is used to help with finding repeat pairs.
int seenChars = 0;
bool containsRepeatPair = false;
bool containsPalindromicTriple = false;
byte prev2 = (byte)'\0';
byte prev = (byte)'\0';
for (int i = 0; i < line.Length; i++)
{
// Part 1 Rules
byte cur = line[i];
if (cur is (byte)'a' or (byte)'e' or (byte)'i' or (byte)'o' or (byte)'u')
{
numVowels++;
}
if (cur == prev)
{
containsPair = true;
}
if ((prev is (byte)'a' or (byte)'c' or (byte)'p' or (byte)'x') && cur == prev + 1)
{
containsForbiddenPair = true;
}
// Part 2 Rules
// check if we have seen the current and previous letter before
// if we have, scan the line for a repeat pair
int prevBitMask = 1 << (prev - 'a');
if ((seenChars & prevBitMask) > 0 && (seenChars & 1 << (cur - 'a')) > 0)
{
for (int j = 0; j < i - 2; j++)
{
if (line[j] == prev && line[j + 1] == cur)
{
containsRepeatPair = true;
}
}
}
if (prev2 == cur)
{
containsPalindromicTriple = true;
}
// we only add a letter to the seen characters two iterations after it first appears
// to avoid scanning the line for an overlap.
seenChars |= prevBitMask;
prev2 = prev;
prev = cur;
}
if (numVowels >= 3 && containsPair && !containsForbiddenPair)
{
part1++;
}
if (containsRepeatPair && containsPalindromicTriple)
{
part2++;
}
}
solution.SubmitPart1(part1);
solution.SubmitPart2(part2);
}
}