diff options
Diffstat (limited to 'challenge-008')
62 files changed, 1343 insertions, 9 deletions
diff --git a/challenge-008/andrezgz/perl5/ch-1.pl b/challenge-008/andrezgz/perl5/ch-1.pl new file mode 100644 index 0000000000..9a4df1aa97 --- /dev/null +++ b/challenge-008/andrezgz/perl5/ch-1.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +# https://perlweeklychallenge.org/blog/perl-weekly-challenge-008/ +# Challenge #1 +# Write a script that computes the first five perfect numbers. +# A perfect number is an integer that is the sum of its positive proper divisors (all divisors except itself). +# Please check Wiki for more information. This challenge was proposed by Laurent Rosenfeld. +# https://en.wikipedia.org/wiki/Perfect_number + +use strict; +use warnings; + +# Using Euclid-Euler theorem (https://en.wikipedia.org/wiki/Euclid%E2%80%93Euler_theorem) +# we can create an even perfect number from a Mersenne prime (2^n - 1), for prime n + +my $perfect = 0; +my $n = 2; + +while ($perfect < 5) { + if (is_prime($n) && is_prime(2**$n-1)) { + print 2**($n-1) * (2**$n - 1).$/; + $perfect++; + } + $n++; +} + +sub is_prime { + my $n = shift; + return 1 == grep {$n % $_ == 0} (1 .. $n-1); +} diff --git a/challenge-008/andrezgz/perl5/ch-2.pl b/challenge-008/andrezgz/perl5/ch-2.pl new file mode 100644 index 0000000000..5962e8401a --- /dev/null +++ b/challenge-008/andrezgz/perl5/ch-2.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl + +# https://perlweeklychallenge.org/blog/perl-weekly-challenge-008/ +# Challenge #2 +# Write a function, 'center', whose argument is a list of strings, which will be lines of text. +# The function should insert spaces at the beginning of the lines of text so that if they were printed, +# the text would be centered, and return the modified lines. + +use strict; +use warnings; + +print join $/, center("This", "is", "a test of the", "center function"); + +sub center { + my @lines = @_; + my $max = 0; + map { $max = length($_) if (length($_) > $max) } @lines; + return map { ' 'x(($max-length($_))/2).$_ } @lines +} diff --git a/challenge-008/arne-sommer/blog.txt b/challenge-008/arne-sommer/blog.txt new file mode 100644 index 0000000000..18167debcc --- /dev/null +++ b/challenge-008/arne-sommer/blog.txt @@ -0,0 +1 @@ +https://perl6.eu/perfect-indentation.html diff --git a/challenge-008/arne-sommer/perl6/ch-1.p6 b/challenge-008/arne-sommer/perl6/ch-1.p6 new file mode 100755 index 0000000000..713d7eaac2 --- /dev/null +++ b/challenge-008/arne-sommer/perl6/ch-1.p6 @@ -0,0 +1,35 @@ +#! /usr/bin/env perl6 + +sub MAIN (Int $count where $count > 0 = 5) +{ + my $numbers := gather + { + for 2..Inf + { + # say ":: $_ ::"; + take $_ if is-perfect($_); + } + } + + say "The first $count perfect numbers: " ~ $numbers[0 .. $count -1].join(', ') ~ "."; + +} + +multi proper-divisors (2) { return (1); } + +multi proper-divisors (Int $number where $number > 2) +{ + return (1) if $number.is-prime; + + my @divisors = (1); + for 2 .. ($number -1) -> $candidate + { + @divisors.push: $candidate if $number %% $candidate; + } + return @divisors; +} + +sub is-perfect ($number) +{ + return $number == proper-divisors($number).sum; +} diff --git a/challenge-008/arne-sommer/perl6/ch-2.p6 b/challenge-008/arne-sommer/perl6/ch-2.p6 new file mode 100755 index 0000000000..f85ca7fe12 --- /dev/null +++ b/challenge-008/arne-sommer/perl6/ch-2.p6 @@ -0,0 +1,12 @@ +#! /usr/bin/env perl6 + +sub MAIN (*@strings) +{ + .say for center(@strings); +} + +sub center (@strings) +{ + my $max-length = @strings>>.chars.max; + return @strings.map({ .indent(($max-length - .chars) / 2) }); +} diff --git a/challenge-008/arne-sommer/perl6/perfect-divisors b/challenge-008/arne-sommer/perl6/perfect-divisors new file mode 100755 index 0000000000..f32ab5cf13 --- /dev/null +++ b/challenge-008/arne-sommer/perl6/perfect-divisors @@ -0,0 +1,20 @@ +#! /usr/bin/env perl6 + +sub MAIN ($number) +{ + say "Divisors (excluding the number itself): " ~ proper-divisors($number); +} + +multi proper-divisors (2) { return (1); } + +multi proper-divisors (Int $number where $number > 2) +{ + return (1) if $number.is-prime; + + my @divisors = (1); + for 2 .. ($number -1) -> $candidate + { + @divisors.push: $candidate if $number %% $candidate; + } + return @divisors; +} diff --git a/challenge-008/arne-sommer/perl6/perfect-numbers-test b/challenge-008/arne-sommer/perl6/perfect-numbers-test new file mode 100755 index 0000000000..62a7f6cbd2 --- /dev/null +++ b/challenge-008/arne-sommer/perl6/perfect-numbers-test @@ -0,0 +1,27 @@ +#! /usr/bin/env perl6 + +sub MAIN ($number) +{ + say "Divisors (excluding the number itself): " ~ proper-divisors($number); + + say "Is the number perfect: " ~ is-perfect($number); +} + +multi proper-divisors (2) { return (1); } + +multi proper-divisors (Int $number where $number > 2) +{ + return (1) if $number.is-prime; + + my @divisors = (1); + for 2 .. ($number -1) -> $candidate + { + @divisors.push: $candidate if $number %% $candidate; + } + return @divisors; +} + +sub is-perfect ($number) +{ + return $number == proper-divisors($number).sum; +} diff --git a/challenge-008/arne-sommer/perl6/perfect-numbers2 b/challenge-008/arne-sommer/perl6/perfect-numbers2 new file mode 100755 index 0000000000..911e4b6f78 --- /dev/null +++ b/challenge-008/arne-sommer/perl6/perfect-numbers2 @@ -0,0 +1,38 @@ +#! /usr/bin/env perl6 + +sub MAIN (Int $count where $count > 0 = 5) +{ + my $numbers := gather + { + for 2..Inf + { + # say ":: $_ ::"; + take $_ if is-perfect($_); + } + } + + say "The first $count perfect numbers: " ~ $numbers[0 .. $count -1].join(', ') ~ "."; + +} + +multi proper-divisors (2) { return (1); } + +multi proper-divisors (Int $number where $number > 2) +{ + return (1) if $number.is-prime; + + # say "N : $number"; + + my @divisors = (1); + for 2 .. ($number / 2) -> $candidate + { + # say "C: $candidate"; + @divisors.push: $candidate if $number %% $candidate; + } + return @divisors; +} + +sub is-perfect ($number) +{ + return $number == proper-divisors($number).sum; +} diff --git a/challenge-008/athanasius/perl5/ch-1.pl b/challenge-008/athanasius/perl5/ch-1.pl new file mode 100644 index 0000000000..0659e1414b --- /dev/null +++ b/challenge-008/athanasius/perl5/ch-1.pl @@ -0,0 +1,49 @@ +use strict; +use warnings; +use Const::Fast; + +const my $TARGET => 5; + +MAIN: +{ + my $count = 0; + + # It is known that if any odd number n is perfect, n > 10^1500; so only even + # numbers need be considered. By the Euclid-Euler Theorem, an even number n + # is a perfect number if and only if n = 2^(k-1)*(2^k-1), where 2^k-1 is + # prime. So the perfect numbers are a subset of the positive integers n of + # the form n = 2^(k-1)*(2^k-1), where k is a positive integer. + + for (my $k = 1; $count < $TARGET; ++$k) + { + my $n = (2 ** ($k - 1)) * (2 ** $k - 1); + + if (is_perfect($n)) + { + print "$n\n"; + ++$count; + } + } +} + +# A positive integer n is perfect if and only if n is equal to the sum of its +# positive proper divisors (factors). (Equivalently, n is perfect if and only if +# it is equal to half the sum of its divisors, where the latter include n +# itself). + +sub is_perfect +{ + my ($n) = @_; + + return 0 if $n == 1; # 1 is not a perfect number + + my $max = int(sqrt($n) + 0.5); + my $sum = 1; # Every positive integer has 1 as a factor + + for my $d (2 .. $max) + { + $sum += $d + ($n / $d) if ($n % $d) == 0; + } + + return $n == $sum; +} diff --git a/challenge-008/athanasius/perl5/ch-2.pl b/challenge-008/athanasius/perl5/ch-2.pl new file mode 100644 index 0000000000..89bd6dab3a --- /dev/null +++ b/challenge-008/athanasius/perl5/ch-2.pl @@ -0,0 +1,39 @@ +use strict; +use warnings; +use Const::Fast; + +const my $PREFIX => ' '; +const my $SPACE => ' '; + +MAIN: +{ + my @input = ('This', 'is', 'a test of the', 'center function'); + my @output = center(@input); + + print "\n"; + print $PREFIX . $_ . "\n" for @output; +} + +sub center +{ + my @lines = @_; + my $max = 0; + my @lengths; + + for my $line (@lines) + { + my $len = length $line; + push @lengths, $len; + $max = $len if $len > $max; + } + + my @centered; + + for my $i (0 .. $#lines) + { + my $spaces = int(($max - $lengths[$i]) / 2); + push @centered, ($SPACE x $spaces) . $lines[$i]; + } + + return @centered; +} diff --git a/challenge-008/daniel-mantovani/perl5/ch-1.pl b/challenge-008/daniel-mantovani/perl5/ch-1.pl new file mode 100644 index 0000000000..237514adf6 --- /dev/null +++ b/challenge-008/daniel-mantovani/perl5/ch-1.pl @@ -0,0 +1,52 @@ +# Write a script that computes the first five perfect numbers. +# A perfect number is an integer that is the $sum of its positive proper divisors (all divisors except itself). +# Please check Wiki for more information. This challenge was proposed by Laurent Rosenfeld. + +use strict; +use warnings; +use v5.10; + +# we start by defining a sub that checks if a number is perfect (i.e is equal lo the sum of all its divisors): + +sub is_perfect { + my $x = shift; + my $sum = 0; + for my $d ( 1 .. $x - 1 ) { + $sum += $d unless $x % $d; + } + return $sum == $x; +} + +# as using this formula to test all integers (or even restricted to odd numbers) will take forever, we +# use other property of perfect numbers. They have the binary form of x ones (1) followed by x-1 zeros (0) +# note that 2 ^ x - 1 will give you a binary number of x ones, and if you multiply this number for +# 2 ^ (x-1) yow will be adding x - 1 zeros to the right. + +sub get_candidate { + my $p = shift; + return undef unless ( $p && $p > 0 && $p < 33 ); + my $pwr2 = 1; + $pwr2 *= 2 while --$p; # $pwr2 will be 2 ^ ($p-1) + return ( $pwr2 * 2 - 1 ) * $pwr2; + + # this will be '1' x $p . '0' x ($p-1) in binary +} + +# now we calculate all perfect number cases starting on get_candidate(2) until we get 5 + +my $q = 5; # we need five perfect numbers +my $ones = 2; #start with 2 ones and a 0 (110, i.e, 6) +while ($q) { + my $candidate = get_candidate($ones); + $q-- && say $candidate if is_perfect($candidate); + $ones++; +} + +# note that 5 is the maximum amount of perfect numbers that you can get with 32 bit arithmetics, as the 6th +# one is 0b111111111111111110000000000000000 (17 ones and 16 zeros) +# +# calculating the first 5 takes 1.8 secs on my machine, if you want to get up to the sixth you can change $q +# assignement to 6 in line 34 (provided that your perl has 64 bit arithmetics) , but the time to complete the +# calculations increases to almost 8 min. This is because the is_perfect function has to as many divisions as +# the number is checking minus one, so for the 6 perfect number that will be 858,986,056 divisions only for +# the last check diff --git a/challenge-008/daniel-mantovani/perl5/ch-2.pl b/challenge-008/daniel-mantovani/perl5/ch-2.pl new file mode 100644 index 0000000000..4875a51070 --- /dev/null +++ b/challenge-008/daniel-mantovani/perl5/ch-2.pl @@ -0,0 +1,55 @@ + +use strict; +use warnings; +use v5.10; +use utf8; +use open qw(:std :utf8); + +# Write a function, ‘center’, whose argument is a list of strings, which will be lines of text. The function +# should insert spaces at the beginning of the lines of text so that if they were printed, the text would be +# centered, and return the modified lines. + +# For example, + +# center("This", "is", "a test of the", "center function"); +# should return the list: + +# " This", " is", " a test of the", "center function" +# because if these lines were printed, they would look like: + +# This +# is +# a test of the +# center function + +sub center { + my @list = @_; + + # size of bigger line (in chars, not in bytes): + my $sz; + + # iterate over the list replacing chars in the list, and actualize max chars + for my $i ( 0 .. $#list ) { + + # get rid of undefined lines + $list[$i] //= ''; + + # now actualize max size + $sz = !defined $sz || length $list[$i] > $sz ? length $list[$i] : $sz; + } + + # nothing to do if $sz was not defined + return @list unless defined $sz; + + # pad spaces in front in each line, to center the text + + return map { ' ' x int( ( $sz - length ) / 2 ) . $_ } @list; +} +my @list = <>; +chomp @list; +say for center @list; + +# +# you can test the example case with the following command executed in the script directory: +# $> echo -e "This\nis\na test of the\ncenter function"|perl ch-2.pl +# diff --git a/challenge-008/dave-jacoby/blog.txt b/challenge-008/dave-jacoby/blog.txt new file mode 100644 index 0000000000..c9b30ccca0 --- /dev/null +++ b/challenge-008/dave-jacoby/blog.txt @@ -0,0 +1 @@ +https://jacoby.github.io//2019/05/15/finding-perfect-numbers-in-perl.html diff --git a/challenge-008/dave-jacoby/blog1.txt b/challenge-008/dave-jacoby/blog1.txt new file mode 100644 index 0000000000..1099369d04 --- /dev/null +++ b/challenge-008/dave-jacoby/blog1.txt @@ -0,0 +1 @@ +https://jacoby.github.io//2019/05/15/centering-text-in-perl.html diff --git a/challenge-008/dave-jacoby/perl5/ch-1.pl b/challenge-008/dave-jacoby/perl5/ch-1.pl new file mode 100644 index 0000000000..6c3bd4321a --- /dev/null +++ b/challenge-008/dave-jacoby/perl5/ch-1.pl @@ -0,0 +1,32 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature qw{ say signatures }; +no warnings qw{ experimental::signatures }; + +use List::Util qw{sum}; + +say join "\n", perfect_numbers(); + +sub perfect_numbers { + my @numbers; + my $n = 0; + + while ( scalar @numbers < 5 ) { + $n++; + next unless $n % 2 == 0; # they're all even, so this halves time + my @factors = factor($n); + my $sum = sum @factors; + push @numbers, $n if $sum eq $n; + } + return @numbers; +} + +sub factor ( $n ) { + my @factors; + for my $i ( 1 .. $n - 1 ) { + push @factors, $i if $n % $i == 0; + } + return @factors; +} diff --git a/challenge-008/dave-jacoby/perl5/ch-1a.pl b/challenge-008/dave-jacoby/perl5/ch-1a.pl new file mode 100644 index 0000000000..bd4601721a --- /dev/null +++ b/challenge-008/dave-jacoby/perl5/ch-1a.pl @@ -0,0 +1,45 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature qw{ say signatures }; +no warnings qw{ experimental::signatures }; + +use List::Util qw{sum}; + +say join "\n", perfect_numbers(); + +sub perfect_numbers { + my @numbers; + my $p = 1; + + while ( scalar @numbers < 5 ) { + $p++; + next unless is_prime($p); + my $q = $p - 1; + my $o = ( 2**$q ) * ( ( 2**$p ) - 1 ); + next unless is_perfect($o); + push @numbers, $o; + } + return @numbers; +} + +sub is_perfect ( $n ) { + my @factors = factor($n); + my $sum = sum @factors; + return |
