diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2022-02-20 23:22:10 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-20 23:22:10 +0000 |
| commit | 975eaedca80ce61d8a08765c2be3921338fb89fc (patch) | |
| tree | 35556a9899d0eab5c8facc6aeba2984a91e685ac | |
| parent | f0244dcfa028bec9b1f88f7d0fdb054dc5192344 (diff) | |
| parent | b77e7339ff36bfcd47a7c1464d43e9fd8bb935e8 (diff) | |
| download | perlweeklychallenge-club-975eaedca80ce61d8a08765c2be3921338fb89fc.tar.gz perlweeklychallenge-club-975eaedca80ce61d8a08765c2be3921338fb89fc.tar.bz2 perlweeklychallenge-club-975eaedca80ce61d8a08765c2be3921338fb89fc.zip | |
Merge pull request #5684 from E7-87-83/newt
Week 152 Task 2
| -rw-r--r-- | challenge-152/cheok-yin-fung/perl/ch-2.pl | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/challenge-152/cheok-yin-fung/perl/ch-2.pl b/challenge-152/cheok-yin-fung/perl/ch-2.pl new file mode 100644 index 0000000000..d71e2a3c4b --- /dev/null +++ b/challenge-152/cheok-yin-fung/perl/ch-2.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl +# The Weekly Challenge 152 +# Task 2 Rectangle Area +# Usage: +# $ ch-2.pl [bottom-left of R1] [top-right of R1] [BL of R2] [TR of R2] +# e.g. +# $ ch-2.pl -1 0 2 2 0 -1 4 4 (Example 1) + +use strict; +use v5.22.0; + +say rect_area(@ARGV[0..7]) + if (defined($ARGV[0]) && defined($ARGV[7]) && verify(@ARGV[0..7])); + + + +sub verify { + my @A, my @B; + ($A[0], $A[1], $A[2], $A[3], $B[0], $B[1], $B[2], $B[3]) = @_; + my $pass_A = $A[0] < $A[2] && $A[1] < $A[3]; + my $pass_B = $B[0] < $B[2] && $B[1] < $B[3]; + + die "Problem(s) in input data of the first rectangle.\n" if !$pass_A; + die "Problem(s) in input data of the second rectangle.\n" if !$pass_B; + return $pass_A && $pass_B; +} + + + +sub rect_area { + my @A, my @B; + # ($lA, $bA, $rA, $tA, $lB, $bB, $rB, $rB) + ($A[0], $A[1], $A[2], $A[3], $B[0], $B[1], $B[2], $B[3]) = @_; + + my @w = sort {$a<=>$b} ($A[0], $A[2], $B[0], $B[2]); + my @h = sort {$a<=>$b} ($A[1], $A[3], $B[1], $B[3]); + + my $area = 0; + + for my $i (0..2) { for my $j (0..2) { + my $inA = ($w[$j] >= $A[0]) && ($A[2] >= $w[$j+1]) + && ($h[$i+1] <= $A[3]) && ($A[1] <= $h[$i]); + + my $inB = ($w[$j] >= $B[0]) && ($B[2] >= $w[$j+1]) + && ($h[$i+1] <= $B[3]) && ($B[1] <= $h[$i]); + + if ($inA || $inB) { + $area += ($w[$i+1]-$w[$i])*($h[$j+1]-$h[$j]); + } + }} + +=pod + Except the case that one rectangle is inside the other rectangle, + the two rectangles can be enscribed into a larger rectangle + Dividing the large rectangle into 9 small rectangular regions, + then check one by one if a small region is inside rect A or rect B. + If yes, add the area of the small region into $area. +=cut + + return $area; +} + + + +use Test::More tests => 4; + +ok ( rect_area(-1,0,2,2,0,-1,4,4) == 22 ), "Example 1"; +ok ( rect_area(-3,-1,1,3,-1,-3,2,2) == 25), "Example 2"; +ok ( rect_area(0,0,1,1,-1,-1,4,4) == 25), "Square within Square"; +ok ( rect_area(-3,-3,0,0,0,0,4,4) == 25), "Seperated Squares"; + |
