From 181adc7b65e1f80ccb6c0182fd7738cd05dcebeb Mon Sep 17 00:00:00 2001 From: Daniel Mantovani Date: Sat, 10 Aug 2019 18:07:23 -0300 Subject: my proposed solutions for challenge-020, p5 1 & 2 --- challenge-020/daniel-mantovani/perl5/ch-1.pl | 32 ++++++++++++++ challenge-020/daniel-mantovani/perl5/ch-2.pl | 62 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 challenge-020/daniel-mantovani/perl5/ch-1.pl create mode 100644 challenge-020/daniel-mantovani/perl5/ch-2.pl diff --git a/challenge-020/daniel-mantovani/perl5/ch-1.pl b/challenge-020/daniel-mantovani/perl5/ch-1.pl new file mode 100644 index 0000000000..e3f689ee34 --- /dev/null +++ b/challenge-020/daniel-mantovani/perl5/ch-1.pl @@ -0,0 +1,32 @@ +# Write a script to accept a string from command line and split it +# on change of character. For example, if the string is “ABBCDEEF”, +# then it should split like “A”, “BB”, “C”, “D”, “EE”, “F”. + +use strict; +use warnings; +use v5.10; +use utf8; +use Encode; +use open qw(:std :utf8); # for other languages + +# we start by reading string from command line + +my $string = Encode::decode 'utf8', $ARGV[0]; +die "Usage: $0 " unless $string; + +my $current; # this to store current char to see if changed + +while ($string) { + my $char = $1 + if $string =~ s/(.)//; # there are maaaany ways to do this, but the + # idea is to take the first char from $string and + # store it in $char + print "\n" + unless !defined $current + || $char eq $current; # new line on change of character + # note that on first pass $current will not be defined, + # so we don't get a newline before first char + $current = $char; # keep current char for next pass + print $char; +} +print "\n"; # to end last line diff --git a/challenge-020/daniel-mantovani/perl5/ch-2.pl b/challenge-020/daniel-mantovani/perl5/ch-2.pl new file mode 100644 index 0000000000..b81a4fbe0d --- /dev/null +++ b/challenge-020/daniel-mantovani/perl5/ch-2.pl @@ -0,0 +1,62 @@ +# Write a script to print the smallest pair of Amicable Numbers. +# For more information, please checkout wikipedia page. + +use strict; +use warnings; +use v5.10; + +# we start by defining a sub that sums of all divisors of a given number: + +sub sum_divisors { + my $x = shift; + my $sum = 0; + for my $d ( 1 .. $x - 1 ) { + $sum += $d unless $x % $d; + } + return $sum; +} + +# now we will start calculating sum of divisors for each integer, +# starting by integer 2. +# we will name that integer $candidate, to show that is a potential +# amicable number, and we will try to get the corresponding pair +# and see if they accomplish the given criteria + +my $candidate = 2; + +while (1) { + my $candidate2 = sum_divisors $candidate; + + # we will not consider cases where candidates are the same number + # (that wouldn't be a pair, right?). + # (Note also that this candidate would be a perfect number, something + # we saw on challenge 008-1). + # Also we don't care for candidates that are lower than the one + # we are checking, as those would have been found before + if ( $candidate < $candidate2 && $candidate == sum_divisors($candidate2) ) { + say "Found amicable numbers: $candidate & $candidate2"; + last; # challenge ask to stop on first match (i.e. smallest pair) + } + $candidate++; +} + +# commenting out line # 38 above will get you a list of first +# amicable numbers. You can check that the first 10 pairs on that +# list match the ones listed on the wiki page: +# +# $> perl ch-2.pl +# Found amicable numbers: 220 & 284 +# Found amicable numbers: 1184 & 1210 +# Found amicable numbers: 2620 & 2924 +# Found amicable numbers: 5020 & 5564 +# Found amicable numbers: 6232 & 6368 +# Found amicable numbers: 10744 & 10856 +# Found amicable numbers: 12285 & 14595 +# Found amicable numbers: 17296 & 18416 +# Found amicable numbers: 63020 & 76084 +# Found amicable numbers: 66928 & 66992 +# Found amicable numbers: 67095 & 71145 +# Found amicable numbers: 69615 & 87633 +# Found amicable numbers: 79750 & 88730 +# ^C +# $> -- cgit