From 9b2be2ba1121ac6a5ea2ec93374a8beb846e2b19 Mon Sep 17 00:00:00 2001 From: Alexander Pankoff Date: Wed, 24 Nov 2021 18:40:27 +0100 Subject: Add implementation for challenge 140 task 01 --- challenge-140/alexander-pankoff/perl/ch-1.pl | 54 ++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 challenge-140/alexander-pankoff/perl/ch-1.pl diff --git a/challenge-140/alexander-pankoff/perl/ch-1.pl b/challenge-140/alexander-pankoff/perl/ch-1.pl new file mode 100644 index 0000000000..37981f5430 --- /dev/null +++ b/challenge-140/alexander-pankoff/perl/ch-1.pl @@ -0,0 +1,54 @@ +use strict; +use warnings; +use feature qw'say signatures'; +no warnings 'experimental::signatures'; + +use List::Util qw(max); + +run() unless caller(); + +sub run() { + my $a = prompt_for_binary('a'); + my $b = prompt_for_binary('b'); + + say "Result:"; + say( add_binarys( $a, $b ) ); + +} + +sub add_binarys ( $a, $b ) { + + my @a_digits = reverse split( '', $a ); + my @b_digits = reverse split( '', $b ); + + # we walk the digits of the binary numbers starting with the least + # significant digit, add the digits individually, carry the carry around + # with us and build our result from the back + my ( $out, $carry ) = ( '', 0 ); + for ( 0 .. max( $#a_digits, $#b_digits ) ) { + my $res; + ( $res, $carry ) = + add_binary_digits( $a_digits[$_] // 0, $b_digits[$_] // 0, $carry ); + $out = $res . $out; + } + + return $carry ? $carry . $out : $out; +} + +sub add_binary_digits ( $a, $b, $carry ) { + my $c = $a + $b + $carry; + + return $c >= 3 ? ( 1, 1 ) : $c == 2 ? ( 0, 1 ) : ( $c, 0 ); + +} + +sub prompt_for_binary($name) { + say "Enter binary number $name"; + chomp( my $number = ); + if ( $number !~ m/^[01]+$/ ) { + say "Invalid binary number."; + return prompt_for_binary($name); + } + + return $number; +} -- cgit From f689e98205eb99b05d49063e5b2b2eccbaca945a Mon Sep 17 00:00:00 2001 From: Alexander Pankoff Date: Wed, 24 Nov 2021 18:40:37 +0100 Subject: Add operator overloading to challenge 140-01 --- challenge-140/alexander-pankoff/perl/ch-1.pl | 87 +++++++++++++++++++--------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/challenge-140/alexander-pankoff/perl/ch-1.pl b/challenge-140/alexander-pankoff/perl/ch-1.pl index 37981f5430..139791fb6b 100644 --- a/challenge-140/alexander-pankoff/perl/ch-1.pl +++ b/challenge-140/alexander-pankoff/perl/ch-1.pl @@ -3,7 +3,8 @@ use warnings; use feature qw'say signatures'; no warnings 'experimental::signatures'; -use List::Util qw(max); +use Carp; +use List::Util; run() unless caller(); @@ -12,43 +13,77 @@ sub run() { my $b = prompt_for_binary('b'); say "Result:"; - say( add_binarys( $a, $b ) ); + say Binary->new($a) + $b; +} +sub prompt_for_binary($name) { + say "Enter binary number $name"; + chomp( my $number = ); + + if ( $number !~ m/^[01]+$/ ) { + say "Invalid binary number."; + return prompt_for_binary($name); + } + + return $number; } -sub add_binarys ( $a, $b ) { +package Binary { + use overload '+' => 'add'; + use overload '""' => sub { ${ shift() } }; - my @a_digits = reverse split( '', $a ); - my @b_digits = reverse split( '', $b ); + sub new ( $class, $number ) { + if ( $number !~ m/^[01]+$/ ) { + Carp::confess("Invalid binary number: $number"); + } - # we walk the digits of the binary numbers starting with the least - # significant digit, add the digits individually, carry the carry around - # with us and build our result from the back - my ( $out, $carry ) = ( '', 0 ); - for ( 0 .. max( $#a_digits, $#b_digits ) ) { - my $res; - ( $res, $carry ) = - add_binary_digits( $a_digits[$_] // 0, $b_digits[$_] // 0, $carry ); - $out = $res . $out; + return bless \$number, $class; } - return $carry ? $carry . $out : $out; + sub add { + my ( $self, $other ) = @_; + if ( ref $other ) { + if ( UNIVERSAL::isa( $other, ref $self ) ) { + return Binary->new( + BinaryUtil::add_binarys( ${$self}, ${other} ) ); + } + else { + Carp::confess( "Can't add a ", ref $other, " to a ", + ref $self ); + } + } + else { + $self->add( Binary->new($other) ); + } + } } -sub add_binary_digits ( $a, $b, $carry ) { - my $c = $a + $b + $carry; +package BinaryUtil { - return $c >= 3 ? ( 1, 1 ) : $c == 2 ? ( 0, 1 ) : ( $c, 0 ); + sub add_binarys ( $a, $b ) { -} + my @a_digits = reverse split( '', $a ); + my @b_digits = reverse split( '', $b ); + + # we walk the digits of the binary numbers starting with the least + # significant digit, add the digits individually, carry the carry around + # with us and build our result from the back + my ( $out, $carry ) = ( '', 0 ); + for ( 0 .. List::Util::max( $#a_digits, $#b_digits ) ) { + my $res; + ( $res, $carry ) = add_binary_digits( $a_digits[$_] // 0, + $b_digits[$_] // 0, $carry ); + $out = $res . $out; + } + + return $carry ? $carry . $out : $out; + } + + sub add_binary_digits ( $a, $b, $carry ) { + my $c = $a + $b + $carry; + + return $c >= 3 ? ( 1, 1 ) : $c == 2 ? ( 0, 1 ) : ( $c, 0 ); -sub prompt_for_binary($name) { - say "Enter binary number $name"; - chomp( my $number = ); - if ( $number !~ m/^[01]+$/ ) { - say "Invalid binary number."; - return prompt_for_binary($name); } - return $number; } -- cgit From eb542331dece11bdd537961e3773df6ccb794e59 Mon Sep 17 00:00:00 2001 From: Alexander Pankoff Date: Fri, 26 Nov 2021 18:31:41 +0100 Subject: Add implementation for challenge 140 task 02 --- challenge-140/alexander-pankoff/perl/ch-2.pl | 80 ++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 challenge-140/alexander-pankoff/perl/ch-2.pl diff --git a/challenge-140/alexander-pankoff/perl/ch-2.pl b/challenge-140/alexander-pankoff/perl/ch-2.pl new file mode 100644 index 0000000000..b0cb877ed5 --- /dev/null +++ b/challenge-140/alexander-pankoff/perl/ch-2.pl @@ -0,0 +1,80 @@ +use strict; +use warnings; +use feature qw'say signatures'; +no warnings 'experimental::signatures'; + +use constant DEBUG => $ENV{DEBUG} // 0; + +run() unless caller(); + +sub run() { + my $i = prompt_for_integer('i'); + my $j = prompt_for_integer('j'); + my $k = prompt_for_integer('k'); + + my $matrix = multiplication_matrix( $i, $j ); + my @sorted_matrix = sort_multiplication_matrix($matrix); + my $res = $sorted_matrix[ $k - 1 ]; + + if (DEBUG) { + say "Since the multiplication of $i x $j is as below:"; + + say render_matrix($matrix); + say "The sorted multiplication table:"; + say join( ' ', @sorted_matrix ); + + say "Now the " . to_ordinal($k) . " element in the table is '$res'"; + + } + + say $res; + +} + +sub multiplication_matrix ( $i, $j ) { + [ + map { + my $row = $_; + [ + map { + my $col = $_; + $col * $row; + + } ( 1 .. $j ) + ]; + } ( 1 .. $i ) + ]; +} + +sub sort_multiplication_matrix($matrix) { + sort { $a <=> $b } map { @$_ } @$matrix; +} + +sub render_matrix($matrix) { + my $max = $matrix->[-1][-1]; + my $width = length $max; + my $format_str = "%$width" . 'd'; + + join( + "\n", + map { + join( " ", map { sprintf( $format_str, $_ ) } @$_ ) + } @$matrix + ); +} + +sub to_ordinal($n) { + return ( $n == 1 ) ? "1st" : $n == 2 ? "2nd" : $n == 3 ? "3rd" : $n . 'th'; +} + +sub prompt_for_integer($name) { + say "Enter integer number $name greater or equal to 1."; + chomp( my $number = ); + + if ( $number !~ m/^\d+$/ || $number < 1 ) { + say "Invalid integer."; + return prompt_for_integer($name); + } + + return $number; +} -- cgit From 350f79e0e32e3cf4fe60ca54378e9fe4e3feeab2 Mon Sep 17 00:00:00 2001 From: Alexander Pankoff Date: Fri, 26 Nov 2021 18:40:06 +0100 Subject: Check for to large 'k' values --- challenge-140/alexander-pankoff/perl/ch-2.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/challenge-140/alexander-pankoff/perl/ch-2.pl b/challenge-140/alexander-pankoff/perl/ch-2.pl index b0cb877ed5..5b663dae91 100644 --- a/challenge-140/alexander-pankoff/perl/ch-2.pl +++ b/challenge-140/alexander-pankoff/perl/ch-2.pl @@ -12,6 +12,12 @@ sub run() { my $j = prompt_for_integer('j'); my $k = prompt_for_integer('k'); + my $max = $i * $j; + + if ( $k > $max ) { + die "Index 'k' ($k) is larger than the table. Max: $max\n"; + } + my $matrix = multiplication_matrix( $i, $j ); my @sorted_matrix = sort_multiplication_matrix($matrix); my $res = $sorted_matrix[ $k - 1 ]; -- cgit