-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday20.c3
115 lines (107 loc) · 2.23 KB
/
day20.c3
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
module day20;
import std::io;
import std::math;
import std::collections::map;
import std::collections::list;
def LongList = List(<long>);
fn void load_crypto(LongList* list, LongList* pos, long key)
{
File f = file::open("crypto.txt", "rb")!!;
defer (void)f.close();
while (!f.eof())
{
@pool()
{
String line = io::treadline(&f)!!;
list.push(key * line.to_long()!!);
pos.push((int)pos.len());
};
}
}
fn long value_at_pos(LongList list, LongList pos, long i) @inline
{
foreach (long j, loc : pos)
{
if (loc == i) return list.get(j);
}
assert(false);
}
macro print_order(LongList pos)
{
foreach (x : pos)
{
io::printf("%s ", x);
}
io::printn();
}
fn void print_list(LongList list, LongList pos)
{
print_order(pos);
long len = list.len();
for (long i = 0; i < len; i++)
{
io::printf("%s ", value_at_pos(list, pos, i));
}
io::printn();
}
fn void solve(int key, int mixes)
{
LongList list;
LongList pos;
list.new_init();
pos.new_init();
defer pos.free();
defer list.free();
load_crypto(&list, &pos, key);
long len = list.len();
long mod = len - 1;
for (int mix = 0; mix < mixes; mix++)
{
foreach (int i, long loc : pos)
{
long value = list.get(i);
if (value == 0) continue;
long new_position = (value + loc) % mod;
if (new_position < 1) new_position += mod;
long index = 0;
// "Remove"
foreach (j, &loc_ref : pos)
{
long l = *loc_ref;
if (l == loc)
{
*loc_ref = new_position;
index = j;
continue;
}
if (l > loc) (*loc_ref)--;
}
// "Insert"
foreach (j, &loc_ref : pos)
{
long l = *loc_ref;
if (j == index) continue;
if (l >= new_position) (*loc_ref)++;
}
}
}
long zero_place = 0;
foreach (long i, val : list)
{
if (val == 0)
{
zero_place = i;
break;
}
}
long zero_loc = pos.get(zero_place);
long x1000 = value_at_pos(list, pos, (zero_loc + 1000) % len);
long x2000 = value_at_pos(list, pos, (zero_loc + 2000) % len);
long x3000 = value_at_pos(list, pos, (zero_loc + 3000) % len);
io::printfn("Total: %d + %d + %d = %d", x1000, x2000, x3000, x1000 + x2000 + x3000);
}
fn void main()
{
solve(1, 1);
solve(811589153, 10);
}