Skip to content

Commit 57bdd7d

Browse files
committed
[euler/prob029] modify algorithm
1 parent dc602bd commit 57bdd7d

File tree

1 file changed

+23
-27
lines changed

1 file changed

+23
-27
lines changed

euler/prob029-gerdr.pl

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,28 @@
88
}
99

1010
sub count-smartly(Int \A, Int \B --> Int) {
11-
# uses the same algorithm as polettix' solution
12-
13-
my %seen-bases;
14-
my $seen-values = [+] gather {
15-
16-
# visit bases which are powers of preceeding ones
17-
for 2..sqrt(A).Int -> \root {
18-
next if %seen-bases{root};
19-
20-
my %seen-exponents;
21-
my @powers = root, * * root ...^ * > A;
22-
23-
for @powers Z 1..* -> \base, \exp {
24-
next if %seen-bases{base};
25-
26-
# mark powers of \base according to their exponent
27-
# relative to \root
28-
%seen-exponents{(2..B) >>*>> exp} = True xx *;
29-
30-
# avoid double-counting
31-
%seen-bases{base} = True;
32-
}
33-
34-
take +%seen-exponents;
11+
my (%powers, %count);
12+
13+
# find bases which are powers of a preceeding root base
14+
# store decomposition into base and exponent relative to root
15+
for 2..Int(sqrt A) -> \a {
16+
for 2..* Z a**2, a**3, a**4 ...^ * > A -> \e, \p {
17+
%powers{a} //= (a) => 1;
18+
%powers{p} //= (a) => e;
3519
}
20+
}
3621

22+
# count duplicates
23+
for %powers.values -> \p {
24+
for 2..B -> \e {
25+
# raise to power e
26+
# classify by root and relative exponent
27+
++%count{p.key => p.value * e}
28+
}
3729
}
3830

39-
# without duplicates, the result would be (A - 1) * (B - 1)
40-
(A - 1 - %seen-bases) * (B - 1) + $seen-values
31+
# add +%count as one of the duplicates needs to be kept
32+
return (A - 1) * (B - 1) + %count - [+] %count.values;
4133
}
4234

4335
sub bench(|) {
@@ -47,7 +39,11 @@ (|)
4739
return result, round (end - start) * 1000;
4840
}
4941

50-
sub MAIN(Int $A = 100, Int $B = 100, Bool :$verify) {
42+
multi MAIN(Int $N, Bool :$verify) {
43+
nextwith($N, $N, :$verify)
44+
}
45+
46+
multi MAIN(Int $A = 100, Int $B = 100, Bool :$verify) {
5147
&count-smartly.wrap(&bench);
5248
&count-naively.wrap(&bench);
5349

0 commit comments

Comments
 (0)