Commit | Line | Data |
ac04ccd9 |
1 | package IronMunger::Calculate; |
2 | |
3 | use strict; |
4 | use warnings; |
66bdbe82 |
5 | use List::Util qw(min); |
38827ef4 |
6 | use autobox; |
38efa3f1 |
7 | use autobox::DateTime::Duration; |
f79d4b5c |
8 | use signatures; |
67e9aef2 |
9 | |
a7b549f9 |
10 | use Sub::Exporter -setup => { |
11 | exports => [ |
69941ee3 |
12 | qw(successful_sequential_posts days_remaining_to_post level_for_post_count) |
a7b549f9 |
13 | ] |
14 | }; |
15 | |
66bdbe82 |
16 | sub day_diff ($dt1, $dt2) { |
17 | $dt1 = $dt1->at if $dt1->isa('IronMunger::Post'); |
18 | $dt2 = $dt2->at if $dt2->isa('IronMunger::Post'); |
19 | $dt1->delta_days($dt2)->delta_days; |
20 | } |
21 | |
38efa3f1 |
22 | sub check_post_gap ($aperture, $days, @posts) { |
66bdbe82 |
23 | return scalar @posts if @posts <= $aperture; |
38efa3f1 |
24 | my @next_post = splice(@posts, 0, $aperture); |
e1738c74 |
25 | if (day_diff(DateTime->now, $next_post[-1]) > $days) { |
26 | while (@next_post && day_diff(DateTime->now, $next_post[-1]) > $days) { |
27 | pop @next_post; |
28 | } |
29 | return scalar(@next_post); |
30 | } |
38efa3f1 |
31 | my $success = $aperture; |
67e9aef2 |
32 | foreach my $post (@posts) { |
66bdbe82 |
33 | if (day_diff($next_post[0],$post) > $days) { |
34 | return $success; |
35 | } |
67e9aef2 |
36 | $success++; |
37 | shift(@next_post); |
38 | push(@next_post, $post); |
39 | } |
40 | return $success; |
41 | } |
38efa3f1 |
42 | |
a51e36e5 |
43 | sub check_time_remaining ($aperture, $days, @posts) { |
e1738c74 |
44 | my @consider = @posts > $aperture ? @posts[0 .. $aperture - 1] : @posts; |
45 | foreach my $cand (reverse @consider) { |
46 | my $days_ago = day_diff(DateTime->now, $cand); |
47 | return $days - $days_ago if $days > $days_ago; |
48 | } |
49 | return $days; |
a51e36e5 |
50 | } |
51 | |
a7b549f9 |
52 | sub check_both ($check, @posts) { |
66bdbe82 |
53 | return min( |
a7b549f9 |
54 | $check->(1, 10, @posts), # 10 days between posts |
55 | $check->(4, 32, @posts), # 4 posts within any given 32 days |
38efa3f1 |
56 | ); |
57 | } |
ac04ccd9 |
58 | |
a7b549f9 |
59 | sub successful_sequential_posts (@posts) { |
60 | return check_both(\&check_post_gap, @posts); |
61 | } |
62 | |
38827ef4 |
63 | sub days_remaining_to_post (@posts) { |
a7b549f9 |
64 | return check_both(\&check_time_remaining, @posts); |
65 | } |
66 | |
69941ee3 |
67 | sub level_for_post_count($count) { |
68 | return 'paper' if $count < 4; |
69 | return 'stone' if $count < 12; |
70 | return 'bronze' if $count < 36; |
71 | return 'iron'; |
72 | } |
73 | |
ac04ccd9 |
74 | 1; |