-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay22.cs
More file actions
121 lines (102 loc) · 3.49 KB
/
Day22.cs
File metadata and controls
121 lines (102 loc) · 3.49 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System.Collections.Immutable;
using System.Data;
using System.Numerics;
using System.Runtime.InteropServices.ComTypes;
using _2024.Utils;
namespace _2024._22;
public struct Bidder(int totalAmountNumbers)
{
public long[] SecretNumbers { get; set; } = new long[totalAmountNumbers];
public int[] Prices { get; set; } = new int[totalAmountNumbers];
public int[] Differences { get; set; } = new int[totalAmountNumbers];
}
public class Day22 : Base
{
private readonly long[] _initialSecretNumbers;
public Day22(bool example) : base(example)
{
Day = "22";
_initialSecretNumbers = ReadInput().Select(long.Parse).ToArray();
}
private static long MixAndPrune(long toMix, long original)
{
original ^= toMix;
original = MathExtensions.Modulo(original, 16777216);
return original;
}
private static long EvolveSecretNumber(long number)
{
number = MixAndPrune(number * 64, number);
number = MixAndPrune(number / 32, number);
return MixAndPrune(number * 2048, number);
}
private Bidder[] _bidders = [];
// in total we will have 2001 numbers, as we start with one and generate 2000
private const int SecretNumbers = 2001;
private long SolveProblem(int stage)
{
_bidders = new Bidder[_initialSecretNumbers.Length];
foreach ((long number, int idx) in _initialSecretNumbers.Enumerate())
{
_bidders[idx] = new Bidder(SecretNumbers)
{
SecretNumbers =
{
[0] = number
},
Differences =
{
[0] = 0
},
Prices =
{
[0] = (int)(number % 10)
}
};
}
for (int it = 1; it < SecretNumbers; it++)
{
foreach(Bidder bidder in _bidders)
{
bidder.SecretNumbers[it] = EvolveSecretNumber(bidder.SecretNumbers[it - 1]);
bidder.Prices[it] = (int)(bidder.SecretNumbers[it] % 10);
bidder.Differences[it] = bidder.Prices[it] - bidder.Prices[it-1];
}
}
if (stage == 1)
{
return _bidders.Select(x => x.SecretNumbers.Last()).Sum();
}
Dictionary<ValueTuple<int, int, int, int>, int> prices = [];
// make sure to add each price difference range only once per seller
HashSet<ValueTuple<int, int, int, int>> seenRanges = [];
foreach (Bidder bidder in _bidders)
{
for (int it = 1; it < SecretNumbers - 3; it++)
{
ValueTuple<int, int, int, int> range = (bidder.Differences[it], bidder.Differences[it + 1],
bidder.Differences[it + 2], bidder.Differences[it + 3]);
if (!seenRanges.Add(range))
{
continue;
}
prices.TryAdd(range, 0);
prices[range] += bidder.Prices[it+3];
}
seenRanges.Clear();
}
return prices.Values.Max();
}
public override object PartOne()
{
return SolveProblem(1);
}
public override object PartTwo()
{
return SolveProblem(2);
}
public override void Reset()
{
_bidders = [];
}
}