-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday4.c3
93 lines (89 loc) · 2.17 KB
/
day4.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
/*
* Advent of Code 2023 day 4
*/
import std::io;
import std::time;
import std::collections::list;
import std::ascii;
import std::math;
fn void main()
{
io::printn("Advent of code, day 4.");
@pool()
{
// Simple benchmarking with Clock, "mark" returns the last duration and resets the clock
Clock c = clock::now();
io::printfn("* Winnings 1: %d - completed in %s", part1(), c.mark());
io::printfn("* Winnings 2: %d - completed in %s", part2(), c.mark());
};
}
fn int matches_for_line(String line)
{
// Split on ':' and keep the second, then split on | and keep
// The parts.
String[] data = line.tsplit(": ", 2)[1].tsplit("| ", 2);
assert(data.len == 2);
uint winning_numbers = data[0].len / 3;
uint numbers = (data[1].len + 1) / 3;
int matches;
for (int i = 0; i < numbers; i++)
{
// Slice the number, eg " 9" or "48"
String number = data[1][i * 3:2];
// Check every number by string comparison
// – this works because of the tabular nature
// of the data.
for (int j = 0; j < winning_numbers; j++)
{
String win = data[0][j * 3:2];
if (number == win) matches++;
}
}
return matches;
}
fn long part1()
{
File f = file::open("day4.txt", "rb")!!;
defer (void)f.close();
long winnings;
while (try line = io::treadline(&f))
{
int matches = matches_for_line(line);
if (!matches) continue;
// The winnings are 2^(matches - 1)
winnings += 1L << (matches - 1);
}
return winnings;
}
fn long part2()
{
File f = file::open("day4.txt", "rb")!!;
defer (void)f.close();
long winnings;
List(<int>) matches;
matches.temp_init(1024);
// Store all the matches in a single sweep.
while (try line = io::treadline(&f))
{
matches.push(matches_for_line(line));
}
// Create an array to store the cards, where zero = 1 card
int[] cards = mem::temp_alloc_array(int, matches.len());
long total_cards;
foreach (i, copies : cards)
{
// How many actual cards do we have?
int total = copies + 1;
// Add to the sum.
total_cards += total;
// Lookup the wins
int wins = matches[i];
// Add copies to the following cards.
for (int j = 0; j < wins; j++)
{
cards[i + j + 1] += total;
}
}
// We return the cards we've summed.
return total_cards;
}