From 378e963f8876d4751eb375555d9cc90738ab633d Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 04:19:14 +0000 Subject: solution to 101! --- challenge-101/james-smith/perl/ch-1.pl | 41 ++++++++++++++++++++++++++++++++++ challenge-101/james-smith/perl/ch-2.pl | 35 +++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 challenge-101/james-smith/perl/ch-1.pl create mode 100644 challenge-101/james-smith/perl/ch-2.pl (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-1.pl b/challenge-101/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..ac89a45459 --- /dev/null +++ b/challenge-101/james-smith/perl/ch-1.pl @@ -0,0 +1,41 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +print_spiral( 1 .. $_ ) foreach 1..30; + +sub print_spiral { + say join q( ), map { sprintf '%2d', $_ } @{$_} foreach @{pack_spiral(@_)}; + say ''; +} + +sub pack_spiral { + my( $rows, @in ) = ( 1, @_ ); + + ## Get the value for columns & rows which have the smallest gap + ## but still multiply to size of array (we choose rows to be + ## no greater than columns as printing is neater - but for no + ## other reason... + + $rows = @in%$_ ? $rows : $_ foreach 2 .. sqrt @in; + + my ($cols,$r,$c,@out) = (@in/$rows,$rows-1,-1); + + ## We start bottom left... + ## because we use pre-inc we actually start 1 to the left of it! + ## as we "jump" before depositing the entry of the array... + + while( $rows && $cols ) { ## Do we have anything else to do? + $out[$r][++$c] = shift @in foreach 1..$cols--; # >> + $out[--$r][$c] = shift @in foreach 1..--$rows; # ^^ + last unless $rows && $cols; ## Skip if we have finished here + $out[$r][--$c] = shift @in foreach 1..$cols--; # << + $out[++$r][$c] = shift @in foreach 1..--$rows; # vv + } + + return \@out; +} diff --git a/challenge-101/james-smith/perl/ch-2.pl b/challenge-101/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..e68bdbbca8 --- /dev/null +++ b/challenge-101/james-smith/perl/ch-2.pl @@ -0,0 +1,35 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( winding_number(qw(0 1 1 0 2 2)), 0 ); +is( winding_number(qw(0 1 -1 1 0 -3)), 1 ); +is( winding_number(qw(0 1 2 0 -6 0)), 1 ); + +done_testing(); + +sub winding_number { + ## Winding number is a generic way of working out whether a point lies + ## within a polygon - as this is not difficult we can implement the + ## trick for our triangle... + ## We have to work with edges - each edge in the code is represented + ## by ($a,$b) -> ($x,$y)... We start from the edge which joins the + ## "last" node to the first and then we work our way around the circle + ## The winding number goes up or down depening on whether the edge + ## crosses the +ve axis (adding or subtracking 1 depending on the + ## direction) - this boils down to the algorithm below.. + + my @pts = @_; + my ($a,$b,$wn) = @pts[-2,-1],0; + while( my($x,$y) = splice @pts,0,2 ) { + $wn += $a<=0 ? $y>0 && $a*$y-$x*$b > 0 ? 1 : 0 + : $y<=0 && $a*$y-$x*$b <= 0 ? -1 : 0; + ($a,$b)=($x,$y); + } + return $wn?1:0; +} + -- cgit From 6fce46c86da21aa2e28fa353bc1c85c89cb9ee1c Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 05:04:19 +0000 Subject: tidied up layout --- challenge-101/james-smith/perl/ch-1.pl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-1.pl b/challenge-101/james-smith/perl/ch-1.pl index ac89a45459..18434b2b69 100644 --- a/challenge-101/james-smith/perl/ch-1.pl +++ b/challenge-101/james-smith/perl/ch-1.pl @@ -9,32 +9,34 @@ use Test::More; print_spiral( 1 .. $_ ) foreach 1..30; sub print_spiral { - say join q( ), map { sprintf '%2d', $_ } @{$_} foreach @{pack_spiral(@_)}; + say join q( ), map { sprintf '%2d', $_ } @{$_} + foreach @{pack_spiral(@_)}; say ''; } sub pack_spiral { - my( $rows, @in ) = ( 1, @_ ); + my $rows = 1; ## Get the value for columns & rows which have the smallest gap ## but still multiply to size of array (we choose rows to be ## no greater than columns as printing is neater - but for no ## other reason... - $rows = @in%$_ ? $rows : $_ foreach 2 .. sqrt @in; + $rows = @_%$_ ? $rows : $_ foreach 2 .. sqrt @_; - my ($cols,$r,$c,@out) = (@in/$rows,$rows-1,-1); + my ($cols,$r,$c,@out) = (@_/$rows,$rows-1,-1); ## We start bottom left... ## because we use pre-inc we actually start 1 to the left of it! ## as we "jump" before depositing the entry of the array... - - while( $rows && $cols ) { ## Do we have anything else to do? - $out[$r][++$c] = shift @in foreach 1..$cols--; # >> - $out[--$r][$c] = shift @in foreach 1..--$rows; # ^^ - last unless $rows && $cols; ## Skip if we have finished here - $out[$r][--$c] = shift @in foreach 1..$cols--; # << - $out[++$r][$c] = shift @in foreach 1..--$rows; # vv + ## Remember shift by default operates on @_; + + while( @_ ) { # do until empty + $out[ $r ][ ++$c ] = shift foreach 1 .. $cols--; # >> + $out[ --$r ][ $c ] = shift foreach 1 .. --$rows; # ^^ + last unless @_; # exit if empty + $out[ $r ][ --$c ] = shift foreach 1 .. $cols--; # << + $out[ ++$r ][ $c ] = shift foreach 1 .. --$rows; # vv } return \@out; -- cgit From aa52dd453a66122e8a51ebbbe27222f7c9d47667 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 05:06:12 +0000 Subject: use @_ as easier --- challenge-101/james-smith/perl/ch-2.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-2.pl b/challenge-101/james-smith/perl/ch-2.pl index e68bdbbca8..e9fbf7ed2c 100644 --- a/challenge-101/james-smith/perl/ch-2.pl +++ b/challenge-101/james-smith/perl/ch-2.pl @@ -23,9 +23,9 @@ sub winding_number { ## crosses the +ve axis (adding or subtracking 1 depending on the ## direction) - this boils down to the algorithm below.. - my @pts = @_; - my ($a,$b,$wn) = @pts[-2,-1],0; - while( my($x,$y) = splice @pts,0,2 ) { + my ( $a, $b, $wn ) = @_[ -2, -1 ], 0; + + while( my($x,$y) = splice @_, 0, 2 ) { $wn += $a<=0 ? $y>0 && $a*$y-$x*$b > 0 ? 1 : 0 : $y<=0 && $a*$y-$x*$b <= 0 ? -1 : 0; ($a,$b)=($x,$y); -- cgit From cc69036ae26a587aa9a79156029c90fe67f7069a Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 05:10:43 +0000 Subject: tidied up initialiser --- challenge-101/james-smith/perl/ch-1.pl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-1.pl b/challenge-101/james-smith/perl/ch-1.pl index 18434b2b69..b223880b14 100644 --- a/challenge-101/james-smith/perl/ch-1.pl +++ b/challenge-101/james-smith/perl/ch-1.pl @@ -15,16 +15,14 @@ sub print_spiral { } sub pack_spiral { - my $rows = 1; ## Get the value for columns & rows which have the smallest gap ## but still multiply to size of array (we choose rows to be ## no greater than columns as printing is neater - but for no ## other reason... - $rows = @_%$_ ? $rows : $_ foreach 2 .. sqrt @_; - - my ($cols,$r,$c,@out) = (@_/$rows,$rows-1,-1); + my( $rows ) = reverse grep { ! (@_ % $_) } 1 .. sqrt @_; + my( $cols, $r, $c, @out ) = ( @_/$rows, $rows-1, -1 ); ## We start bottom left... ## because we use pre-inc we actually start 1 to the left of it! -- cgit From 7fac9125976bc8d07f4f3203ad300887120c55aa Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 05:46:17 +0000 Subject: tidied up last line --- challenge-101/james-smith/perl/ch-2.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-2.pl b/challenge-101/james-smith/perl/ch-2.pl index e9fbf7ed2c..f34c8f5ebb 100644 --- a/challenge-101/james-smith/perl/ch-2.pl +++ b/challenge-101/james-smith/perl/ch-2.pl @@ -30,6 +30,6 @@ sub winding_number { : $y<=0 && $a*$y-$x*$b <= 0 ? -1 : 0; ($a,$b)=($x,$y); } - return $wn?1:0; + return $wn%2; } -- cgit From e1028616f2f800ca00c27c0bc63c419f5f041cc8 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 23 Feb 2021 05:57:05 +0000 Subject: whitespace --- challenge-101/james-smith/perl/ch-1.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'challenge-101') diff --git a/challenge-101/james-smith/perl/ch-1.pl b/challenge-101/james-smith/perl/ch-1.pl index b223880b14..c3b75a4ff6 100644 --- a/challenge-101/james-smith/perl/ch-1.pl +++ b/challenge-101/james-smith/perl/ch-1.pl @@ -21,7 +21,7 @@ sub pack_spiral { ## no greater than columns as printing is neater - but for no ## other reason... - my( $rows ) = reverse grep { ! (@_ % $_) } 1 .. sqrt @_; + my( $rows ) = reverse grep { ! (@_ % $_) } 1 .. sqrt @_; my( $cols, $r, $c, @out ) = ( @_/$rows, $rows-1, -1 ); ## We start bottom left... @@ -32,7 +32,7 @@ sub pack_spiral { while( @_ ) { # do until empty $out[ $r ][ ++$c ] = shift foreach 1 .. $cols--; # >> $out[ --$r ][ $c ] = shift foreach 1 .. --$rows; # ^^ - last unless @_; # exit if empty + last unless @_; # exit if empty $out[ $r ][ --$c ] = shift foreach 1 .. $cols--; # << $out[ ++$r ][ $c ] = shift foreach 1 .. --$rows; # vv } -- cgit