-
Notifications
You must be signed in to change notification settings - Fork 0
/
2017_10.cs
97 lines (80 loc) · 2.22 KB
/
2017_10.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
95
96
97
namespace AOC.CSharp;
public static class AOC2017_10
{
public static long Solve1(string[] lines, int numCount)
{
List<int> nums = Enumerable.Range(0, numCount).ToList();
List<int> lengths = lines[0].Split(',').Select(int.Parse).ToList();
int curr = 0;
int skip = 0;
DoRound(nums, lengths, curr, skip);
return nums[0] * nums[1];
}
public static string Solve2(string[] lines)
{
return CalculateKnotHash(lines[0]);
}
public static string CalculateKnotHash(string input)
{
List<int> nums = Enumerable.Range(0, 256).ToList();
List<int> lengths = input
.Select(ch => (int)ch)
.Concat(new[] { 17, 31, 73, 47, 23 })
.ToList();
int curr = 0;
int skip = 0;
for (int i = 0; i < 64; i++)
{
(curr, skip) = DoRound(nums, lengths, curr, skip);
}
byte[] xorBytes = new byte[16];
for (int i = 0; i < 16; i++)
{
int start = i * 16;
int end = start + 15;
int xor = nums[start];
for (int j = start + 1; j <= end; j++)
{
xor ^= nums[j];
}
xorBytes[i] = (byte)xor;
}
string hex = Convert.ToHexString(xorBytes).ToLowerInvariant();
return hex;
}
private static (int curr, int skip) DoRound(
List<int> nums,
List<int> lengths,
int curr,
int skip
)
{
foreach (int length in lengths)
{
Reverse(nums, curr, length);
curr += (skip + length);
curr %= nums.Count;
skip++;
}
return (curr, skip);
}
private static void Reverse(List<int> nums, int start, int length)
{
int swaps = length / 2;
int end = (start + length - 1) % nums.Count;
for (int i = 0; i < swaps; i++)
{
(nums[start], nums[end]) = (nums[end], nums[start]);
start++;
if (start == nums.Count)
{
start = 0;
}
end--;
if (end < 0)
{
end = nums.Count - 1;
}
}
}
}