aboutsummaryrefslogtreecommitdiff
path: root/challenge-152/alexander-pankoff/perl/ch-2.pl
blob: 78ec3877a6febb8c022767cf6f79cd54721e34de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw'say state signatures';
no warnings qw'experimental::signatures';

# 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

use List::Util qw(min max);

run() unless caller();

sub run() {

    say "Running example 1";
    say rectangles_area( [ [ -1, 0 ], [ 2, 2 ] ], [ [ 0, -1 ], [ 4, 4 ] ] );
    say "Running example 2";
    say rectangles_area( [ [ -3, -1 ], [ 1, 3 ] ], [ [ -1, -3 ], [ 2, 2 ] ] );
    say "Running example without overlap";
    say rectangles_area( [ [ -1, 0 ], [ 0, 1 ] ], [ [ 1, 0 ], [ 2, 1 ] ] );
}

sub rectangles_area ( $rectangle1, $rectangle2 ) {
    say "Rectangle 1 => " . show_rectangle_corners($rectangle1);
    say "Rectangle 2 => " . show_rectangle_corners($rectangle2);

    my $area1 = rectangle_area($rectangle1);
    my $area2 = rectangle_area($rectangle2);

    my $overlap_rectangle =
      find_overlapping_rectangle( $rectangle1, $rectangle2 );

    my $overlap_area = rectangle_area($overlap_rectangle);

    return $area1 + $area2 - $overlap_area;
}

sub rectangle_area($rectangle) {
    my ( $x1, $y1, $x2, $y2 ) = map { @$_ } @$rectangle;

    my $x = abs( $x1 - $x2 );
    my $y = abs( $y1 - $y2 );

    return $x * $y;

}

sub find_overlapping_rectangle ( $rectangle1, $rectangle2 ) {
    my ( $x11, $y11, $x12, $y12 ) = map { @$_ } @$rectangle1;
    my ( $x21, $y21, $x22, $y22 ) = map { @$_ } @$rectangle2;

    my $x1 = max( $x11, $x21 );
    my $y1 = max( $y11, $y21 );

    my $x2 = min( $x12, $x22 );
    my $y2 = min( $y12, $y22 );

    if ( $x1 > $x2 || $y1 > $y2 ) {
        ## no overlap, return rectangle with empty area
        return [ [ 0, 0 ], [ 0, 0 ] ];
    }

    return [ [ $x1, $y1 ], [ $x2, $y2 ] ];
}

sub show_rectangle_corners($rectangle) {
    join( ', ', map { '(' . join( ',', @$_ ) . ')' } @$rectangle );
}