diff options
| author | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2022-02-20 22:27:10 +1000 |
|---|---|---|
| committer | PerlMonk-Athanasius <PerlMonk.Athanasius@gmail.com> | 2022-02-20 22:27:10 +1000 |
| commit | e7baaf61556465b0769869b03422066438dee388 (patch) | |
| tree | 2be7fc352e8d6253efd213ea76ad18f0845ec7f1 /challenge-152/athanasius/raku | |
| parent | 9c7e8b8c714868fd4e9fe7ed7eff9f141f038069 (diff) | |
| download | perlweeklychallenge-club-e7baaf61556465b0769869b03422066438dee388.tar.gz perlweeklychallenge-club-e7baaf61556465b0769869b03422066438dee388.tar.bz2 perlweeklychallenge-club-e7baaf61556465b0769869b03422066438dee388.zip | |
Perl & Raku solutions to Tasks 1 & 2 of the Weekly Challenge 152
Diffstat (limited to 'challenge-152/athanasius/raku')
| -rw-r--r-- | challenge-152/athanasius/raku/ch-1.raku | 187 | ||||
| -rw-r--r-- | challenge-152/athanasius/raku/ch-2.raku | 152 |
2 files changed, 339 insertions, 0 deletions
diff --git a/challenge-152/athanasius/raku/ch-1.raku b/challenge-152/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..ed892d456f --- /dev/null +++ b/challenge-152/athanasius/raku/ch-1.raku @@ -0,0 +1,187 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 152 +========================= + +TASK #1 +------- +*Triangle Sum Path* + +Submitted by: Mohammad S Anwar + +You are given a triangle array. + +Write a script to find the minimum sum path from top to bottom. + +Example 1: + + Input: $triangle = [ [1], [5,3], [2,3,4], [7,1,0,2], [6,4,5,2,8] ] + + 1 + 5 3 + 2 3 4 + 7 1 0 2 + 6 4 5 2 8 + + Output: 8 + + Minimum Sum Path = 1 + 3 + 2 + 0 + 2 => 8 + +Example 2: + + Input: $triangle = [ [5], [2,3], [4,1,5], [0,1,2,3], [7,2,4,1,9] ] + + 5 + 2 3 + 4 1 5 + 0 1 2 3 + 7 2 4 1 9 + + Output: 9 + + Minimum Sum Path = 5 + 2 + 1 + 0 + 1 => 9 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Interface +--------- +1. Following the Examples, I have assumed that array elements are integers. +2. The array elements are entered on the command line as a linear sequence + beginning with the top-most element and continuing down and to the right + until the final (bottom- and right-most) element. For example, the triangu- + lar array: 1 + 2 3 + 4 5 6 is entered as: raku ch-1.raku 1 2 3 4 5 6 +3. If the constant $VERBOSE is set to True (the default), the individual elem- + ents comprising the minimum sum path are shown in addition to the minimum + sum. + +Algorithm +--------- +From the Examples, it appears that a "path" is simply a selection of elements +drawn from the triangular array, with exactly one element drawn from each array +level. Hence, the solution is found by taking the smallest element from each +level, and summing these elements. + +The following test is used to determine whether the number of elements entered +on the command line is a triangular number: + + "... an integer _x_ is triangular if and only if 8_x_ + 1 is a square." [1] + +Reference +--------- +[1] https://en.wikipedia.org/wiki/Triangular_number#Triangular_roots_and_tests_ + for_triangular_numbers + +=end comment +#============================================================================== + +my Bool constant $VERBOSE = True; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 152, Task #1: Triangle Sum Path (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + #| A triangular array of integers, in linear order + + *@items where { is-triangular( .elems ) && .all ~~ Int:D } +) +#============================================================================== +{ + my Array[Int] @triangle = build-triangle( @items ); + + "Input: \$triangle = %s\n".printf: sprint-triangle( @triangle ); + + my Int @min-sum-path; + @min-sum-path.push: @triangle[ $_ ].min for 0 .. @triangle.end; + + my Int $min-sum = [+] @min-sum-path; + + "Output: $min-sum".put; + + if $VERBOSE + { + "\n Minimum Sum Path: %s = %d\n".printf: + @min-sum-path.join( ' + ' ), $min-sum; + } +} + +#------------------------------------------------------------------------------ +sub build-triangle( Array:D[Int:D] $items --> Array:D[Array:D[Int:D]] ) +#------------------------------------------------------------------------------ +{ + my Array[Int] @triangle = Array[Array[Int]].new; + my UInt $row-idx = 0; + my UInt $index = 0; + + while $index <= $items.end + { + my Int @row = Array[Int].new; + + for 1 .. $row-idx + 1 + { + @row.push: $items[ $index++ ]; + } + + @triangle.push: @row; + + ++$row-idx; + } + + return @triangle; +} + +#------------------------------------------------------------------------------ +sub sprint-triangle( Array:D[Array:D[Int:D]] $triangle --> Str:D ) +#------------------------------------------------------------------------------ +{ + my Str @rows; + + for @$triangle -> Array[Int] $row + { + @rows.push: '[' ~ @$row.join( ',' ) ~ ']'; + } + + return '[ ' ~ @rows.join( ', ' ) ~ ' ]'; +} + +#------------------------------------------------------------------------------ +sub is-triangular( UInt:D $num --> Bool:D ) +#------------------------------------------------------------------------------ +{ + my UInt $x = 8 * $num + 1; + + my UInt $root = $x.sqrt.floor; + + return $root * $root == $x; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +############################################################################## diff --git a/challenge-152/athanasius/raku/ch-2.raku b/challenge-152/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..31b1d95c17 --- /dev/null +++ b/challenge-152/athanasius/raku/ch-2.raku @@ -0,0 +1,152 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 152 +========================= + +TASK #2 +------- +*Rectangle Area* + +Submitted by: Mohammad S Anwar + +You are given coordinates bottom-left and top-right corner of two rectangles in +a 2D plane. + +Write a script to find the total area covered by the two rectangles. + +Example 1: + + Input: Rectangle 1 => (-1,0), (2,2) + Rectangle 2 => (0,-1), (4,4) + + Output: 22 + +Example 2: + + Input: Rectangle 1 => (-3,-1), (1,3) + Rectangle 2 => (-1,-3), (2,2) + + Output: 25 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2022 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Interface +--------- +Command-line input is 8 real numbers: the coordinates of the bottom-left and +top-right corners, in (x, y) order, of 2 rectangles. Rectangles must have non- +zero areas. Output is the total area covered by the 2 rectangles. If the +constant $VERBOSE is set to True (the default), the output is followed by an +explanation. + +Note re: the Windows command prompt: + +If the first number on the command line is negative, the minus sign will be +interpreted as a command-line flag, resulting in a "Usage" error. To enter a +negative number as the first argument, precede the arguments with a double +hyphen: + + raku ch-2.raku -- -1 0 2 2 0 -1 4 4 + +Algorithm +--------- +Consider 2 rectangles: + + +------------a1 + | | + | c-----K--------b1 + | | | | + a0------J-----d | + | | + | | + b0--------------+ + +The overlapping area, rectangle cJdK, has corners (J, K) where: + the x-coordinate of J is the larger of a0x and b0x; + the y-coordinate of J is the larger of a0y and b0y; + the x-coordinate of K is the smaller of a1x and b1x; and + the y-coordinate of K is the smaller of a1y and b1y. + +This holds true for all configurations of the 2 rectangles, provided that K is +above and to the right of J; otherwise, the rectangles do not overlap. + +The combined area is the sum of the areas of the 2 rectangles less the area of +their overlap (if any). + +=end comment +#============================================================================== + +my Bool constant $VERBOSE = True; + +subset Coord of Real; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 152, Task #2: Rectangle Area (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + #| 8 coordinates (real numbers) describing 2 rectangles + + *@c where { .elems == 8 && .all ~~ Coord:D && + @c[ 2 ] > @c[ 0 ] && @c[ 3 ] > @c[ 1 ] && + @c[ 6 ] > @c[ 4 ] && @c[ 7 ] > @c[ 5 ] } +) +#============================================================================== +{ + my Coord ($a0x, $a0y, $a1x, $a1y, $b0x, $b0y, $b1x, $b1y) = @c; + + "Input: Rectangle 1 => ($a0x, $a0y), ($a1x, $a1y)".put; + " Rectangle 2 => ($b0x, $b0y), ($b1x, $b1y)".put; + + my Coord $area1 = ($a1x - $a0x) * ($a1y - $a0y); + my Coord $area2 = ($b1x - $b0x) * ($b1y - $b0y); + + # Common/shared rectangle + + my Coord $c0x = ($a0x, $b0x).max; + my Coord $c0y = ($a0y, $b0y).max; + my Coord $c1x = ($a1x, $b1x).min; + my Coord $c1y = ($a1y, $b1y).min; + my Coord $area3 = ($c1x > $c0x && $c1y > $c0y) ?? + ($c1x - $c0x) * ($c1y - $c0y) !! 0; + + my Coord $total = $area1 + $area2 - $area3; + + "\nOutput: $total".put; + + if $VERBOSE + { + "\nExplanation\n-----------".put; + "The rectangles have areas of $area1 and $area2, respectively,".put; + "and a shared (i.e., overlapping) area of $area3".put; + "Total area is $area1 + $area2 - $area3 = $total".put; + } +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + + $usage.put; +} + +############################################################################## |
