diff options
| author | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2021-02-28 23:34:47 +1000 |
|---|---|---|
| committer | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2021-02-28 23:34:47 +1000 |
| commit | 94c912a2a48371980cbc6986fe81840e987153f5 (patch) | |
| tree | 2c093bae033f3ca36ade6de8700c9e5ab724040d | |
| parent | 37247271a1d6f0cefa14b7847b3fecf4b1dd7894 (diff) | |
| download | perlweeklychallenge-club-94c912a2a48371980cbc6986fe81840e987153f5.tar.gz perlweeklychallenge-club-94c912a2a48371980cbc6986fe81840e987153f5.tar.bz2 perlweeklychallenge-club-94c912a2a48371980cbc6986fe81840e987153f5.zip | |
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #101
On branch branch-for-challenge-101
Changes to be committed:
new file: challenge-101/athanasius/perl/ch-1.pl
new file: challenge-101/athanasius/perl/ch-2.pl
new file: challenge-101/athanasius/raku/ch-1.raku
new file: challenge-101/athanasius/raku/ch-2.raku
| -rw-r--r-- | challenge-101/athanasius/perl/ch-1.pl | 297 | ||||
| -rw-r--r-- | challenge-101/athanasius/perl/ch-2.pl | 205 | ||||
| -rw-r--r-- | challenge-101/athanasius/raku/ch-1.raku | 305 | ||||
| -rw-r--r-- | challenge-101/athanasius/raku/ch-2.raku | 182 |
4 files changed, 989 insertions, 0 deletions
diff --git a/challenge-101/athanasius/perl/ch-1.pl b/challenge-101/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..464e868175 --- /dev/null +++ b/challenge-101/athanasius/perl/ch-1.pl @@ -0,0 +1,297 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 101 +========================= + +Task #1 +------- +*Pack a Spiral* + +Submitted by: Stuart Little + +You are given an array @A of items (integers say, but they can be anything). + +Your task is to pack that array into an MxN matrix spirally counterclockwise, +as tightly as possible. + + 'Tightly' means the absolute value |M-N| of the difference has to be as + small as possible. + +Example 1: + + Input: @A = (1,2,3,4) + + Output: + + 4 3 + 1 2 + + Since the given array is already a 1x4 matrix on its own, but that's not as + tight as possible. Instead, you'd spiral it counterclockwise into + + 4 3 + 1 2 + +Example 2: + + Input: @A = (1..6) + + Output: + + 6 5 4 + 1 2 3 + + or + + 5 4 + 6 3 + 1 2 + + Either will do as an answer, because they're equally tight. + +Example 3: + + Input: @A = (1..12) + + Output: + + 9 8 7 6 + 10 11 12 5 + 1 2 3 4 + + or + + 8 7 6 + 9 12 5 + 10 11 4 + 1 2 3 + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +use strict; +use warnings; +use Const::Fast; +use enum qw( RIGHT UP LEFT DOWN ); +use Regexp::Common qw( number ); + +const my $USAGE => +"Usage: + perl $0 [<A> ...] + + [<A> ...] A non-empty array of integers and/or integer ranges: I..J\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 101, Task #1: Pack a Spiral (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + # (1) Populate and validate the array + + my @A = get_array(); + + printf "Input: \@A = (%s)\n", join ',', @A; + + # (2) Find M <= N such that M * N == @A.elems and |M - N| is a minimum + + my ($M, $N) = find_dimensions( \@A ); + + # (3) Create and populate the M x N matrix + + my $matrix = pack_matrix( \@A, $M, $N ); + + # (4) Print the matrix + + print "\nOutput:\n\n"; + + print_matrix( $matrix ); +} + +#------------------------------------------------------------------------------ +sub get_array +#------------------------------------------------------------------------------ +{ + scalar @ARGV > 0 or error( 'Empty array' ); + + my @A; + + for my $item (@ARGV) + { + if (my ($lhs, $rhs) = $item =~ / ^ (.+) \.\. (.+) $ /x) + { + for ($lhs, $rhs) + { + / ^ $RE{num}{int} $ /x + or error( qq[Item "$_" is not an integer] ); + } + + push @A, $lhs .. $rhs; + } + else + { + $item =~ / ^ $RE{num}{int} $ /x + or error( qq[Item "$item" is not an integer] ); + + push @A, $item; + } + } + + return @A; +} + +#------------------------------------------------------------------------------ +sub find_dimensions +#------------------------------------------------------------------------------ +{ + my ($A) = @_; + my ($M, $N) = (1, scalar @$A); + my $root = int sqrt $N; + + if ($root * $root == $N) + { + ($M, $N) = ($root, $root); + } + else + { + for my $div1 (reverse 2 .. $root) + { + my $div2 = int($N / $div1); + + if ($div1 * $div2 == $N) + { + ($M, $N) = ($div1, $div2); + last; + } + } + } + + return $M, $N; +} + +#------------------------------------------------------------------------------ +sub pack_matrix +#------------------------------------------------------------------------------ +{ + my ($A, $M, $N) = @_; + my $max_row = $M - 1; + my $min_row = 0; + my $max_col = $N - 1; + my $min_col = 0; + my $row = $max_row; + my $col = -1; + my $dir = RIGHT; + my @matrix; + + for my $item (@$A) + { + if ($dir == RIGHT) + { + if (++$col > $max_col) + { + $col = $max_col; + $dir = UP; + --$row; + --$max_row; + } + } + elsif ($dir == UP) + { + if (--$row < $min_row) + { + $row = $min_row; + $dir = LEFT; + --$col; + --$max_col; + } + } + elsif ($dir == LEFT) + { + if (--$col < $min_col) + { + $col = $min_col; + $dir = DOWN; + ++$row; + ++$min_row; + } + } + else # DOWN + { + if (++$row > $max_row) + { + $row = $max_row; + $dir = RIGHT; + ++$col; + ++$min_col; + } + } + + $matrix[ $row ][ $col ] = $item; + } + + return \@matrix; +} + +#------------------------------------------------------------------------------ +sub print_matrix +#------------------------------------------------------------------------------ +{ + my ($matrix) = @_; + my $max_row = $#$matrix; + my $max_col = $#{ $matrix->[ 0 ] }; + my @widths; + + # (1) Calculate maximum column widths + + for my $col (0 .. $max_col) + { + my $max = length $matrix->[ 0 ][ $col ]; + + for my $row (1 .. $max_row) + { + my $len = length $matrix->[ $row ][ $col ]; + + $max = $len if $len > $max; + } + + push @widths, $max; + } + + # (2) Print the matrix + + for my $row (0 .. $max_row) + { + print ' ' x 5; + + for my $col (0 .. $max_col) + { + printf " %*d", $widths[ $col ], $matrix->[ $row ][ $col ]; + } + + print "\n"; + } +} + +#------------------------------------------------------------------------------ +sub error +#------------------------------------------------------------------------------ +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +############################################################################### diff --git a/challenge-101/athanasius/perl/ch-2.pl b/challenge-101/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..1497525933 --- /dev/null +++ b/challenge-101/athanasius/perl/ch-2.pl @@ -0,0 +1,205 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 101 +========================= + +Task #2 +------- +*Origin-containing Triangle* + +Submitted by: Stuart Little + +You are given three points in the plane, as a list of six co-ordinates: +A=(x1,y1), B=(x2,y2) and C=(x3,y3). + +Write a script to find out if the triangle formed by the given three co- +ordinates contain origin (0,0). + +Print 1 if found otherwise 0. + +Example 1: + + Input: A=(0,1), B=(1,0) and C=(2,2) + + Output: 0 because that triangle does not contain (0,0). + +Example 2: + + Input: A=(1,1), B=(-1,1) and C=(0,-3) + + Output: 1 because that triangle contains (0,0) in its interior. + +Example 3: + + Input: A=(0,1), B=(2,0) and C=(-6,0) + + Output: 1 because (0,0) is on the edge connecting B and C. + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +The algorithm in subroutine collinear() is adapted from: + + Eric W. Weisstein, "Collinear". MathWorld--A Wolfram Web Resource: + https://mathworld.wolfram.com/Collinear.html + +The algorithm in subroutine point_in_triangle() is adapted from: + + "1st method: barycentric coordinate system" + in Cédric Jules, "Accurate point in triangle test". Totologic blog: + http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html + +=cut +#============================================================================== + +use strict; +use warnings; +use Const::Fast; +use Regexp::Common qw( number ); + +const my $VERBOSE => 1; +const my $USAGE => +"Usage: + perl $0 [<coords> ...] + + [<coords> ...] X-Y co-ordinates of the 3 vertices of a triangle\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 101, Task #2: Origin-containing Triangle (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my ($A, $B, $C) = parse_command_line(); + + print 'Input: A=(', $A->[ 0 ], ',', $A->[ 1 ], + '), B=(', $B->[ 0 ], ',', $B->[ 1 ], + ') and C=(', $C->[ 0 ], ',', $C->[ 1 ], ")\n\n"; + + my ($result, $explanation) = contains_origin( $A, $B, $C ); + + printf "Output: $result%s\n", $VERBOSE ? ' because ' . $explanation : ''; +} + +#------------------------------------------------------------------------------ +sub contains_origin +#------------------------------------------------------------------------------ +{ + my ($A, $B, $C) = @_; + + for my $point ($A, $B, $C) + { + return (1, '(0,0) is a vertex of the triangle') + if $point->[ 0 ] == 0 && $point->[ 1 ] == 0; + } + + my $origin = [ 0, 0 ]; + + return (1, '(0,0) is on the edge connecting A and B') + if collinear( $A, $B, $origin ); + + return (1, '(0,0) is on the edge connecting A and C') + if collinear( $A, $C, $origin ); + + return (1, '(0,0) is on the edge connecting B and C') + if collinear( $B, $C, $origin ); + + return (1, 'that triangle contains (0,0) in its interior') + if point_in_triangle( $A, $B, $C ); + + return (0, 'that triangle does not contain (0,0)'); +} + +#------------------------------------------------------------------------------ +sub point_in_triangle +#------------------------------------------------------------------------------ +{ + my ($A, $B, $C) = @_; + + my $den = ($B->[1] - $C->[1]) * ($A->[0] - $C->[0]) + + ($C->[0] - $B->[0]) * ($A->[1] - $C->[1]); + + my $x = (($B->[1] - $C->[1]) * -$C->[0] + + ($C->[0] - $B->[0]) * -$C->[1]) / $den; + + my $y = (($C->[1] - $A->[1]) * -$C->[0] + + ($A->[0] - $C->[0]) * -$C->[1]) / $den; + + my $z = 1 - $x - $y; + + return 0 <= $x <= 1 && + 0 <= $y <= 1 && + 0 <= $z <= 1; +} + +#------------------------------------------------------------------------------ +sub parse_command_line +#------------------------------------------------------------------------------ +{ + my $args = scalar @ARGV; + $args == 6 or error( "Expected 6 command-line arguments, found $args" ); + + for (@ARGV) + { + / ^ $RE{num}{real} $ /x or error( qq[Item "$_" is not a real number] ); + } + + my @A = @ARGV[ 0, 1 ]; + my @B = @ARGV[ 2, 3 ]; + my @C = @ARGV[ 4, 5 ]; + + # The 3 points defining a triangle must be distinct ... + + error( 'Points A and B are identical' ) + if $A[ 0 ] == $B[ 0 ] && $A[ 1 ] == $B[ 1 ]; + + error( 'Points A and C are identical' ) + if $A[ 0 ] == $C[ 0 ] && $A[ 1 ] == $C[ 1 ]; + + error( 'Points B and C are identical' ) + if $B[ 0 ] == $C[ 0 ] && $B[ 1 ] == $C[ 1 ]; + + # ... and not collinear + + error( 'Points A, B, and C are collinear' ) if collinear( \@A, \@B, \@C ); + + return (\@A, \@B, \@C); +} + +#------------------------------------------------------------------------------ +sub collinear +#------------------------------------------------------------------------------ +{ + my ($A, $B, $C) = @_; + + return $A->[0] * ($B->[1] - $C->[1]) + + $B->[0] * ($C->[1] - $A->[1]) + + $C->[0] * ($A->[1] - $B->[1]) == 0; +} + +#------------------------------------------------------------------------------ +sub error +#------------------------------------------------------------------------------ +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +############################################################################### diff --git a/challenge-101/athanasius/raku/ch-1.raku b/challenge-101/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..8722464417 --- /dev/null +++ b/challenge-101/athanasius/raku/ch-1.raku @@ -0,0 +1,305 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 101 +========================= + +Task #1 +------- +*Pack a Spiral* + +Submitted by: Stuart Little + +You are given an array @A of items (integers say, but they can be anything). + +Your task is to pack that array into an MxN matrix spirally counterclockwise, +as tightly as possible. + + 'Tightly' means the absolute value |M-N| of the difference has to be as + small as possible. + +Example 1: + + Input: @A = (1,2,3,4) + + Output: + + 4 3 + 1 2 + + Since the given array is already a 1x4 matrix on its own, but that's not as + tight as possible. Instead, you'd spiral it counterclockwise into + + 4 3 + 1 2 + +Example 2: + + Input: @A = (1..6) + + Output: + + 6 5 4 + 1 2 3 + + or + + 5 4 + 6 3 + 1 2 + + Either will do as an answer, because they're equally tight. + +Example 3: + + Input: @A = (1..12) + + Output: + + 9 8 7 6 + 10 11 12 5 + 1 2 3 4 + + or + + 8 7 6 + 9 12 5 + 10 11 4 + 1 2 3 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 101, Task #1: Pack a Spiral (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + *@A where { @A.elems > 0 } #= A non-empty array of integers and/or + #= integer ranges: I..J +) +#============================================================================== +{ + # (1) Populate and validate the array + + my Int @a = get-array( @A ); + + "Input: \@A = (%s)\n".printf: @a.join: ','; + + # (2) Find M <= N such that M * N == @A.elems and |M - N| is a minimum + + my UInt ($M, $N) = find-dimensions( @a ); + + # (3) Create and populate the M x N matrix + + my Array[Int] @matrix = pack-matrix( @a, $M, $N ); + + # (4) Print the matrix + + "\nOutput:\n".put; + + print-matrix( @matrix ); +} + +#------------------------------------------------------------------------------ +sub get-array( Array:D[IntStr:D] $A --> Array:D[Int:D] ) +#------------------------------------------------------------------------------ +{ + my Int @a; + + for @$A -> Str $item + { + if $item ~~ / ^ (.+) \.\. (.+) $ / + { + $0.Int ~~ Int:D or error( qq[Item "$0" is not an integer] ); + $1.Int ~~ Int:D or error( qq[Item "$1" is not an integer] ); + @a.append: $0 .. $1; + } + else + { + $item ~~ Int:D or error( qq[Item "$item" is not an integer] ); + @a.push: $item.Int; + } + } + + return @a; +} + +#------------------------------------------------------------------------------ +sub find-dimensions( Array:D[Int:D] $A --> List:D[UInt:D, UInt:D] ) +#------------------------------------------------------------------------------ +{ + my UInt ($M, $N) = 1, $A.elems; + + unless $N.is-prime + { + my UInt $root = $N.sqrt.Int; + + if $root * $root == $N + { + ($M, $N) = $root, $root; + } + else + { + for (2 .. $root).reverse -> UInt $div1 + { + my UInt $div2 = ($N / $div1).Int; + + if $div1 * $div2 == $N + { + ($M, $N) = $div1, $div2; + last; + } + } + } + } + + return $M, $N; +} + +#------------------------------------------------------------------------------ +sub pack-matrix +( + Array:D[Int:D] $A, + UInt:D $M, + UInt:D $N +--> Array:D[Array:D[Int:D]] +) +#------------------------------------------------------------------------------ +{ + enum DIR < RIGHT UP LEFT DOWN >; + + my Array[Int] @matrix = Array[Int].new xx $M; + my UInt $max-row = $M - 1; + my UInt $min-row = 0; + my UInt $max-col = $N - 1; + my UInt $min-col = 0; + my Int $row = $max-row; + my Int $col = -1; + my DIR $dir = RIGHT; + + for @$A -> Int $item + { + given $dir + { + when RIGHT + { + if ++$col > $max-col + { + $col = $max-col; + $dir = UP; + --$row; + --$max-row; + } + } + + when UP + { + if --$row < $min-row + { + $row = $min-row; + $dir = LEFT; + --$col; + --$max-col; + } + } + + when LEFT + { + if --$col < $min-col + { + $col = $min-col; + $dir = DOWN; + ++$row; + ++$min-row; + } + } + + when DOWN + { + if ++$row > $max-row + { + $row = $max-row; + $dir = RIGHT; + ++$col; + ++$min-col; + } + } + } + + @matrix[ $row; $col ] = $item; + } + + return @matrix; +} + +#------------------------------------------------------------------------------ +sub print-matrix( Array:D[Array:D[Int:D]] $matrix ) +#------------------------------------------------------------------------------ +{ + my UInt @widths; + my UInt $max-row = $matrix.end; + my UInt $max-col = $matrix[ 0 ].end; + + # (1) Calculate maximum column widths + + for 0 .. $max-col -> UInt $col + { + my UInt $max = $matrix[ 0; $col ].chars; + + for 1 .. $max-row -> UInt $row + { + $max = ( $max, $matrix[ $row; $col ].chars ).max; + } + + @widths.push: $max; + } + + # (2) Print the matrix + + for 0 .. $max-row -> UInt $row + { + (' ' x 5).print; + + for 0 .. $max-col -> UInt $col + { + " %*d".printf: @widths[ $col ], $matrix[ $row; $col ]; + } + + ''.put; + } +} + +#------------------------------------------------------------------------------ +sub error( Str:D $message ) +#------------------------------------------------------------------------------ +{ + "ERROR: $message".put; + + USAGE(); + + exit; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################## diff --git a/challenge-101/athanasius/raku/ch-2.raku b/challenge-101/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..a49cf7b631 --- /dev/null +++ b/challenge-101/athanasius/raku/ch-2.raku @@ -0,0 +1,182 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 101 +========================= + +Task #2 +------- +*Origin-containing Triangle* + +Submitted by: Stuart Little + +You are given three points in the plane, as a list of six co-ordinates: +A=(x1,y1), B=(x2,y2) and C=(x3,y3). + +Write a script to find out if the triangle formed by the given three co- +ordinates contain origin (0,0). + +Print 1 if found otherwise 0. + +Example 1: + + Input: A=(0,1), B=(1,0) and C=(2,2) + + Output: 0 because that triangle does not contain (0,0). + +Example 2: + + Input: A=(1,1), B=(-1,1) and C=(0,-3) + + Output: 1 because that triangle contains (0,0) in its interior. + +Example 3: + + Input: A=(0,1), B=(2,0) and C=(-6,0) + + Output: 1 because (0,0) is on the edge connecting B and C. + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +The algorithm in subroutine collinear() is adapted from: + + Eric W. Weisstein, "Collinear". MathWorld--A Wolfram Web Resource: + https://mathworld.wolfram.com/Collinear.html + +The algorithm in subroutine point-in-triangle() is adapted from: + + "1st method: barycentric coordinate system" + in Cédric Jules, "Accurate point in triangle test". Totologic blog: + http://totologic.blogspot.com/2014/01/accurate-point-in-triangle-test.html + +=end comment +#============================================================================== + +my Bool constant $VERBOSE = True; + +subset Point of List where (Real, Real); + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 101, Task #2: Origin-containing Triangle (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + #| X-Y co-ordinates of the 3 vertices of a triangle + *@coords where { @coords.elems == 6 && .all ~~ Real:D } +) +#============================================================================== +{ + my Point $A = [ @coords[ 0 ].Real, @coords[ 1 ].Real ]; + my Point $B = [ @coords[ 2 ].Real, @coords[ 3 ].Real ]; + my Point $C = [ @coords[ 4 ].Real, @coords[ 5 ].Real ]; + + # The 3 points defining a triangle must be distinct, and not collinear + + error( 'Identical points' ) if $A eq $B || $A eq $C || $B eq $C; + error( 'Collinear points' ) if collinear( $A, $B, $C ); + + "Input: A=($A[0],$A[1]), B=($B[0],$B[1]) and C=($C[0],$C[1])\n".put; + + my (Bool $result, Str $explanation) = contains-origin( $A, $B, $C ); + + "Output: %d%s\n".printf: $result ?? 1 !! 0, + $VERBOSE ?? ' because ' ~ $explanation !! ''; +} + +#------------------------------------------------------------------------------ +sub contains-origin +( + Point:D $A, + Point:D $B, + Point:D $C, +--> List:D[Bool:D, Str:D] +) +#------------------------------------------------------------------------------ +{ + for $A, $B, $C -> Point $point + { + return True, '(0,0) is a vertex of the triangle' + if $point[0] == 0 && $point[1] == 0; + } + + my Point $origin = [ 0, 0 ]; + + return True, '(0,0) is on the edge connecting A and B' + if collinear( $A, $B, $origin ); + + return True, '(0,0) is on the edge connecting A and C' + if collinear( $A, $C, $origin ); + + return True, '(0,0) is on the edge connecting B and C' + if collinear( $B, $C, $origin ); + + return True, 'that triangle contains (0,0) in its interior' + if point-in-triangle( $A, $B, $C ); + + return False, 'that triangle does not contain (0,0)'; +} + +#------------------------------------------------------------------------------ +sub point-in-triangle( Point:D $A, Point:D $B, Point:D $C --> Bool:D ) +#------------------------------------------------------------------------------ +{ + my Real $d = ($B[1] - $C[1]) * ($A[0] - $C[0]) + + ($C[0] - $B[0]) * ($A[1] - $C[1]); + + my Real $x = (($B[1] - $C[1]) * -$C[0] + ($C[0] - $B[0]) * -$C[1]) / $d; + + my Real $y = (($C[1] - $A[1]) * -$C[0] + ($A[0] - $C[0]) * -$C[1]) / $d; + + my Real $z = 1 - $x - $y; + + return 0 <= $x <= 1 && + 0 <= $y <= 1 && + 0 <= $z <= 1; +} + +#------------------------------------------------------------------------------ +sub collinear( Point:D $A, Point:D $B, Point:D $C --> Bool:D ) +#------------------------------------------------------------------------------ +{ + return $A[0] * ($B[1] - $C[1]) + + $B[0] * ($C[1] - $A[1]) + + $C[0] * ($A[1] - $B[1]) == 0; +} + +#------------------------------------------------------------------------------ +sub error( Str:D $message ) +#------------------------------------------------------------------------------ +{ + "ERROR: $message".put; + + USAGE(); + + exit; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################## |
