-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstats.rb
executable file
·100 lines (93 loc) · 4.2 KB
/
stats.rb
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
#!/usr/bin/env ruby
#
# Prints my stats as a CSV.
#
# ./stats.rb > stats.csv
# or
# ./stats.rb | tee stats.csv
#
# It can fetch the overall stats from adventofcode.com, since they are public
# data. But getting personal times requires authentication. I don't know how
# to do that, so I copy my stats in this script as they become available.
#
require 'net/http'
STATS_REGEX = %r{<a href="/\d+/day/\d+">\s*(?<day>\d+)\s+<span class="stats-both">\s*(?<both>\d+)</span>\s*<span class="stats-firstonly">\s*(?<firstonly>\d+)</span>}
uri = URI.parse('https://adventofcode.com/2024/stats')
response = Net::HTTP.get_response(uri)
overall_stats = response.body
.lines
.map { |line| STATS_REGEX.match(line) }.compact
.map { |match| match[1..] }
.map { |row| row.map(&:to_i) }
.reduce([]) do |memo, row|
day = row[0]
first_and_second_puzzles = row[1]
first_puzzle_only = row[2]
memo[day] = {
finished_first_puzzle: first_and_second_puzzles + first_puzzle_only,
finished_second_puzzle: first_and_second_puzzles,
}
memo
end
# https://adventofcode.com/2024/leaderboard/self
personal_times = '''
25 01:27:22 5229 0 01:31:43 3798 0
24 01:12:16 4506 0 22:34:51 9476 0
23 01:29:47 5112 0 03:09:55 5501 0
22 20:46:15 18822 0 22:04:55 15777 0
21 23:18:24 12227 0 >24h 12104 0
20 02:17:40 5741 0 05:20:26 6342 0
19 00:21:14 2799 0 00:34:45 2676 0
18 01:46:03 6772 0 02:30:39 7318 0
17 01:30:13 5932 0 >24h 18638 0
16 08:32:13 13539 0 13:45:57 13062 0
15 01:18:21 5806 0 02:56:57 4319 0
14 00:50:25 5423 0 02:03:36 5686 0
13 01:46:43 8352 0 01:56:43 5392 0
12 02:10:03 9939 0 05:58:52 9622 0
11 01:45:52 12897 0 02:55:24 10107 0
10 13:44:37 34717 0 13:50:59 33627 0
9 10:58:59 32764 0 12:01:24 23435 0
8 11:55:12 35875 0 12:32:25 34046 0
7 12:26:35 39538 0 12:37:46 36628 0
6 10:18:48 44271 0 11:14:52 27499 0
5 15:34:14 61170 0 17:02:23 54206 0
4 04:59:46 31579 0 05:14:54 26847 0
3 08:44:00 60274 0 09:42:38 53287 0
2 08:58:05 61493 0 09:28:22 44660 0
1 21:55:06 104725 0 22:04:35 98763 0
'''.lines
.map(&:chomp)
.reject { |line| line.empty? }
.map(&:split)
.map { |row| [row[0], row[2], row[5]] }
.map { |row| row.map(&:to_i) }
.map do |day, my_first_puzzle_rank, my_second_puzzle_rank|
total_first_puzzle = overall_stats[day][:finished_first_puzzle]
total_second_puzzle = overall_stats[day][:finished_second_puzzle]
[
day,
'',
my_first_puzzle_rank.positive? ? my_first_puzzle_rank : '',
total_first_puzzle,
my_first_puzzle_rank.positive? ? ((1.0 - (my_first_puzzle_rank.to_f / total_first_puzzle)) * 100).to_i : '0',
'',
my_second_puzzle_rank.positive? ? my_second_puzzle_rank : '',
total_second_puzzle,
my_second_puzzle_rank.positive? ? ((1.0 - (my_second_puzzle_rank.to_f / total_second_puzzle)) * 100).to_i : '0',
]
end
File.open('stats.csv', 'w', 0644) do |f|
f.puts 'Day,,Part 1 Rank,Part 1 Total,Part 1 Percentile,,Part 2 Rank,Part 2 Total,Part 2 Percentile'
personal_times.each do |row|
f.puts row.join(',')
end
end
File.open('stats.md', 'w', 0644) do |f|
f.puts '| Day | | Part 1 Rank | Part 1 Total | Part 1 Percentile | | Part 2 Rank | Part 2 Total | Part 2 Percentile |'
f.puts '|:---:|--|:-----------:|:------------:|:-----------------:|--|:-----------:|:------------:|:-----------------:|'
personal_times.each do |row|
row[0] = format('[%d](day%02d)', row[0], row[0])
f.puts '| ' + row.join(' | ') + ' |'
end
end