-
Notifications
You must be signed in to change notification settings - Fork 10
/
Day23.cs
93 lines (75 loc) · 2.49 KB
/
Day23.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
using System;
using System.Runtime.CompilerServices;
using AdventOfCode.CSharp.Common;
namespace AdventOfCode.CSharp.Y2020.Solvers;
public class Day23 : ISolver
{
public static void Solve(ReadOnlySpan<byte> input, Solution solution)
{
input = input.TrimEnd((byte)'\n');
int[] part1Cups = new int[input.Length];
int startingCup = input[0] - '1';
int prevCup = startingCup;
foreach (byte c in input)
{
int digit = c - '1';
part1Cups[prevCup] = digit;
prevCup = digit;
}
int[] part2Cups = new int[1000000];
Array.Copy(part1Cups, part2Cups, part1Cups.Length);
part2Cups[prevCup] = part1Cups.Length;
for (int i = part1Cups.Length; i < 1000000; i++)
{
part2Cups[i] = i + 1;
}
// link final cups back to the starting cup
part1Cups[prevCup] = startingCup;
part2Cups[1000000 - 1] = startingCup;
int cur = startingCup;
for (int i = 0; i < 100; i++)
{
cur = Iterate(part1Cups, cur);
}
SolvePart1AndSubmit(part1Cups, solution.GetPart1Writer());
cur = startingCup;
for (int i = 0; i < 10000000; i++)
{
cur = Iterate(part2Cups, cur);
}
long part2 = GetPart2Answer(part2Cups);
solution.SubmitPart2(part2);
static void SolvePart1AndSubmit(int[] cups, SolutionWriter solutionWriter)
{
int digit = cups[0];
for (int i = 0; i < cups.Length - 1; i++)
{
solutionWriter.Write((char)(digit + '1'));
digit = cups[digit];
}
solutionWriter.Complete();
}
static long GetPart2Answer(int[] cups) => (long)(cups[0] + 1) * (cups[cups[0]] + 1);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Iterate(int[] cups, int cur)
{
int move1 = cups[cur];
int move2 = cups[move1];
int move3 = cups[move2];
int next = cups[move3];
cups[cur] = next;
int destination = cur - 1;
if (destination < 0)
destination = cups.Length - 1;
while (destination == move1 || destination == move2 || destination == move3)
{
destination--;
if (destination < 0)
destination = cups.Length - 1;
}
cups[move3] = cups[destination];
cups[destination] = move1;
return next;
}
}