aboutsummaryrefslogtreecommitdiff
path: root/challenge-152
diff options
context:
space:
mode:
authorE7-87-83 <fungcheokyin@gmail.com>2022-02-21 03:37:58 +0800
committerE7-87-83 <fungcheokyin@gmail.com>2022-02-21 03:37:58 +0800
commitce4353477c8001d22b0a7879fa8181514fcfb278 (patch)
tree0d1a8e529010d80a6b6c6513b4ec4fefec0d8d15 /challenge-152
parent4aa638fcef37d8c29930d8d07157b6f14beb862a (diff)
downloadperlweeklychallenge-club-ce4353477c8001d22b0a7879fa8181514fcfb278.tar.gz
perlweeklychallenge-club-ce4353477c8001d22b0a7879fa8181514fcfb278.tar.bz2
perlweeklychallenge-club-ce4353477c8001d22b0a7879fa8181514fcfb278.zip
Week 152 Task 2
Diffstat (limited to 'challenge-152')
-rw-r--r--challenge-152/cheok-yin-fung/perl/ch-2.pl71
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..d138469ec0
--- /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 one rectangle is inside the other rectangle,
+ the two rectangles can be enscribed into a larger rectangle
+ I divided the larger rectangle into 9 small rectangular regions;
+ then check if each small regions 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";
+