-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathsum_of_digits_subquadratic_algorithm.pl
More file actions
executable file
·50 lines (36 loc) · 1.14 KB
/
sum_of_digits_subquadratic_algorithm.pl
File metadata and controls
executable file
·50 lines (36 loc) · 1.14 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
#!/usr/bin/perl
# Subquadratic algorithm for computing the sum of digits of a given integer in a given base.
# Based on the FastIntegerOutput algorithm presented in the book:
#
# Modern Computer Arithmetic
# - by Richard P. Brent and Paul Zimmermann
#
use 5.020;
use strict;
use warnings;
use ntheory qw(:all);
use experimental qw(signatures);
sub FastSumOfDigits ($A, $B) {
# Find k such that B^(2k - 2) <= A < B^(2k)
my $k = (logint($A, $B) >> 1) + 1;
sub ($A, $k) {
if ($A < $B) {
return $A;
}
my ($Q, $R) = divrem($A, powint($B, $k));
my $t = ($k + 1) >> 1;
vecsum(__SUB__->($Q, $t), __SUB__->($R, $t));
}->($A, $k);
}
foreach my $B (2 .. 100) { # run some tests
my $N = factorial($B); # int(rand(~0));
my $x = vecsum(todigits($N, $B));
my $y = FastSumOfDigits($N, $B);
if ($x != $y) {
die "Error for: FastSumOfDigits($N, $B)";
}
}
say join ', ', FastSumOfDigits(5040, 10); #=> 9
say join ', ', FastSumOfDigits(5040, 11); #=> 20
say join ', ', FastSumOfDigits(5040, 12); #=> 13
say join ', ', FastSumOfDigits(5040, 13); #=> 24