diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2019-05-19 00:14:14 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-05-19 00:14:14 +0100 |
| commit | 1d61345cef518e4d7dd1666eb5eae2da376f845e (patch) | |
| tree | 00a1bb377b8d9afced06c99baf77df85ecfa2b1e /challenge-008 | |
| parent | 323f6fb1bb7f08767d0e2f5a8f8af36fba6d6785 (diff) | |
| parent | dfd2342e9a673f42aa2d2a0f1255859172738db3 (diff) | |
| download | perlweeklychallenge-club-1d61345cef518e4d7dd1666eb5eae2da376f845e.tar.gz perlweeklychallenge-club-1d61345cef518e4d7dd1666eb5eae2da376f845e.tar.bz2 perlweeklychallenge-club-1d61345cef518e4d7dd1666eb5eae2da376f845e.zip | |
Merge pull request #158 from dmanto/branch-for-challenge-008
my solutions to ch-1 & 2 in perl5
Diffstat (limited to 'challenge-008')
| -rw-r--r-- | challenge-008/daniel-mantovani/perl5/ch-1.pl | 52 | ||||
| -rw-r--r-- | challenge-008/daniel-mantovani/perl5/ch-2.pl | 55 |
2 files changed, 107 insertions, 0 deletions
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 +# |
