Skip to content

Commit 2460f31

Browse files
committed
[Euler] Add solution to No. 23.
Slow on rakudo-jvm but it works.
1 parent 9c30576 commit 2460f31

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

euler/prob023-shlomif.pl

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/perl
2+
# By Shlomi Fish.
3+
#
4+
# Based on:
5+
# https://bitbucket.org/shlomif/project-euler/src/aa5eecd18f0825901afeb3c54dcda0da79ac3576/project-euler/23/euler-23-4.pl?at=default
6+
#
7+
# Solution for:
8+
#
9+
# http://projecteuler.net/problem=23
10+
#
11+
# A perfect number is a number for which the sum of its proper divisors
12+
# is exactly equal to the number. For example, the sum of the proper
13+
# divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28
14+
# is a perfect number.
15+
#
16+
# A number n is called deficient if the sum of its proper divisors is
17+
# less than n and it is called abundant if this sum exceeds n.
18+
#
19+
# As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the
20+
# smallest number that can be written as the sum of two abundant numbers
21+
# is 24. By mathematical analysis, it can be shown that all integers
22+
# greater than 28123 can be written as the sum of two abundant numbers.
23+
# However, this upper limit cannot be reduced any further by analysis
24+
# even though it is known that the greatest number that cannot be
25+
# expressed as the sum of two abundant numbers is less than this limit.
26+
#
27+
# Find the sum of all the positive integers which cannot be written as
28+
# the sum of two abundant numbers.
29+
#
30+
31+
my @divisors_sums;
32+
@divisors_sums[1] = 0;
33+
34+
my $MAX = 28_123;
35+
for (1 .. ($MAX +> 1)) -> $div
36+
{
37+
loop (my $prod = ($div +< 1); $prod <= $MAX; $prod += $div)
38+
{
39+
@divisors_sums[$prod] += $div;
40+
}
41+
}
42+
43+
# Memoized.
44+
#
45+
my @is_abundant_sum;
46+
47+
my @abundants;
48+
my $total = 0;
49+
for (1 .. $MAX) -> $num
50+
{
51+
if @divisors_sums[$num] > $num
52+
{
53+
@abundants.push($num);
54+
# The sub { ... } and return are a workaround for the fact that Rakudo
55+
# Perl 6 does not have last LABEL yet.
56+
my $c = sub {
57+
for @abundants -> $i
58+
{
59+
if ((my $s = $i + $num) > $MAX)
60+
{
61+
return;
62+
}
63+
else
64+
{
65+
if (! @is_abundant_sum[$s])
66+
{
67+
$total += $s;
68+
@is_abundant_sum[$s] = True;
69+
}
70+
}
71+
}
72+
};
73+
74+
$c();
75+
}
76+
}
77+
78+
say "Sum == ", ((((1 + $MAX) * $MAX) +> 1)-$total);

0 commit comments

Comments
 (0)