-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathDay04.cs
94 lines (79 loc) · 2.56 KB
/
Day04.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
90
91
92
93
94
using System;
using System.Linq;
using System.Text;
using AdventOfCode.CSharp.Common;
namespace AdventOfCode.CSharp.Y2016.Solvers;
public class Day04 : ISolver
{
private static readonly byte[][] s_rotations =
Enumerable.Range(0, 26).Select(i => Encoding.ASCII.GetBytes(Rotate("north", -i))).ToArray();
public static void Solve(ReadOnlySpan<byte> input, Solution solution)
{
int part1 = 0;
int part2 = -1;
int[] letterCounts = new int[26];
foreach (Range lineRange in input.SplitLines())
{
ReadOnlySpan<byte> line = input[lineRange];
int nameLength = line.LastIndexOf((byte)'-');
ReadOnlySpan<byte> name = line.Slice(0, nameLength);
var reader = new SpanReader(line.Slice(nameLength + 1));
int sectorId = reader.ReadPosIntUntil('[');
ReadOnlySpan<byte> checkSum = reader.ReadUntil(']');
foreach (byte c in name)
{
if (c != '-')
{
letterCounts[c - 'a']++;
}
}
if (IsChecksumCorrect(letterCounts, checkSum))
{
part1 += sectorId;
if (part2 == -1 && name.IndexOf(s_rotations[sectorId % 26]) != -1)
{
part2 = sectorId;
}
}
Array.Clear(letterCounts, 0, 26);
}
solution.SubmitPart1(part1);
solution.SubmitPart2(part2);
}
private static bool IsChecksumCorrect(int[] letterCounts, ReadOnlySpan<byte> checksum)
{
int prev = -1;
int prevCount = int.MaxValue;
foreach (byte c in checksum)
{
int letter = c - 'a';
int count = letterCounts[letter];
if (prevCount < count || (prevCount == count && letter < prev))
{
return false;
}
prev = letter;
prevCount = count;
letterCounts[letter] = -1;
}
for (int i = 0; i < 26; i++)
{
int count = letterCounts[i];
if (count > prevCount || (count == prevCount && i < prev))
{
return false;
}
}
return true;
}
private static string Rotate(string str, int amount)
{
return string.Create(str.Length, str, (chars, str) =>
{
for (int i = 0; i < str.Length; i++)
{
chars[i] = (char)(((str[i] - 'a' + amount + 26) % 26) + 'a');
}
});
}
}