aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-152/duncan-c-white/README85
-rwxr-xr-xchallenge-152/duncan-c-white/perl/ch-1.pl75
-rwxr-xr-xchallenge-152/duncan-c-white/perl/ch-2.pl62
3 files changed, 173 insertions, 49 deletions
diff --git a/challenge-152/duncan-c-white/README b/challenge-152/duncan-c-white/README
index b4889e4611..2bc85c8535 100644
--- a/challenge-152/duncan-c-white/README
+++ b/challenge-152/duncan-c-white/README
@@ -1,74 +1,61 @@
-TASK #1 - Binary Tree Depth
+TASK #1 - Triangle Sum Path
-You are given binary tree.
+You are given a triangle array.
-Write a script to find the minimum depth.
-
-The minimum depth is the number of nodes from the root to the nearest
-leaf node (node without any children).
+Write a script to find the minimum sum path from top to bottom.
Example 1:
- Input: '1 | 2 3 | 4 5'
+ 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
- 1
- / \
- 2 3
- / \
- 4 5
+ Output: 8
- Output: 2
+ Minimum Sum Path = 1 + 3 + 2 + 0 + 2 => 8
Example 2:
- Input: '1 | 2 3 | 4 * * 5 | * 6'
+ Input: $triangle = [ [5], [2,3], [4,1,5], [0,1,2,3], [7,2,4,1,9] ]
- 1
- / \
- 2 3
- / \
- 4 5
- \
- 6
- Output: 3
+ 5
+ 2 3
+ 4 1 5
+ 0 1 2 3
+ 7 2 4 1 9
-MY NOTES: well, if I built a binary tree from the input, it would be quite
-simple to find the minimum depth. But there must be a way to solve the
-problem using only the input syntax. Something like: split into rows on '|'.
-Each row has 2 * (rowno-1) elements (starting at row 1). If a row hasn't
-got that many elements, pad it with '*'s. Now, find the first non-full row,
-ie. with one or more '*'s. Take the row a pair of elements at a time. If
-any pair are both '*'s, then the min depth is rowno-1. Otherwise proceed
-to the next row, and keep going down the rows.
+ Output: 9
+ Minimum Sum Path = 5 + 2 + 1 + 0 + 1 => 9
-TASK #2 - Rob The House
+MY NOTES: So it appears at each row, we simply pick the minimum value.
+It doesn't have to be adjacent, or even close to, the one we picked
+on the row above. Ok, so that's easy! Actually, parsing the input
+may be the hardest part.
-You are planning to rob a row of houses, always starting with the first
-and moving in the same direction. However, you can't rob two adjacent
-houses.
-Write a script to find the highest possible gain that can be achieved.
+TASK #2 - Rectangle Area
-Example 1:
+You are given coordinates bottom-left and top-right corner of two rectangles in a 2D plane.
- Input: @valuables = (2, 4, 5);
- Output: 7
+Write a script to find the total area covered by the two rectangles.
-If we rob house 0 we get 2 and then the only house we can rob is house
-2 where we have 5. So the total valuables in this case is (2 + 5) = 7.
+Example 1:
+ Input: Rectangle 1 => (-1,0), (2,2)
+ Rectangle 2 => (0,-1), (4,4)
-Example 2:
+ Output: 22
- Input: @valuables = (4, 2, 3, 6, 5, 3);
- Output: 13
+Example 2:
-The best choice would be to first rob house 0 then rob house 3 then finally
-house 5. This would give us 4 + 6 + 3 =13.
+ Input: Rectangle 1 => (-3,-1), (1,3)
+ Rectangle 2 => (-1,-3), (2,2)
+ Output: 25
-MY NOTES: Hmm.. some sort of recursive "find all paths" method.
-It always helps to pick the right function purpose and name.
-I think the recursive function we need is:
-my $maxvaluables = maxrobbery( startpos ), invoked as my $max=maxrobbery(0)?
+MY NOTES: Of course the tricky bit here is when the rectangles overlap.
diff --git a/challenge-152/duncan-c-white/perl/ch-1.pl b/challenge-152/duncan-c-white/perl/ch-1.pl
new file mode 100755
index 0000000000..41cd93daf3
--- /dev/null
+++ b/challenge-152/duncan-c-white/perl/ch-1.pl
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+#
+# TASK #1 - Triangle Sum Path
+#
+# 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
+#
+# MY NOTES: So it appears at each row, we simply pick the minimum value.
+# It doesn't have to be adjacent, or even close to, the one we picked
+# on the row above. Ok, so that's easy! Actually, parsing the input
+# may be the hardest part. Let's choose a simplified input format:
+# each argument is a separate row, and a row looks like '7,2,4,1,9'
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Getopt::Long;
+use List::Util qw(min);
+#use Data::Dumper;
+
+my $debug=0;
+die "Usage: triangle-sum-path [--debug] 'triangle row 1' ['triangle row 2...'\n"
+ unless GetOptions( "debug"=>\$debug ) && @ARGV>0;
+
+#
+# my $sum = sum_minimum( @rowstr );
+# Given an array of row strings, with elements in one row being
+# comma separated numbers, pick the minimum of each row and sum
+# them, returning the total.
+#
+sub sum_minimum
+{
+ my( @rowstr ) = @_;
+ my $result = 0;
+ foreach my $row (@rowstr)
+ {
+ my @row = split(/,/, $row);
+ $result += min( @row );
+ }
+ return $result;
+}
+
+
+my $sum = sum_minimum( @ARGV );
+say $sum;
diff --git a/challenge-152/duncan-c-white/perl/ch-2.pl b/challenge-152/duncan-c-white/perl/ch-2.pl
new file mode 100755
index 0000000000..d8003ba3e1
--- /dev/null
+++ b/challenge-152/duncan-c-white/perl/ch-2.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+#
+# TASK #2 - Rectangle Area
+#
+# 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
+#
+# MY NOTES: Of course the tricky bit here is when the rectangles overlap.
+#
+
+use strict;
+use warnings;
+use feature 'say';
+use Getopt::Long;
+use Function::Parameters;
+use List::Util qw(min max);
+#use Data::Dumper;
+
+my $debug=0;
+
+die "Usage: rectangle-area x1,y1 x2,y2 x3,y3 x4,y4\n" unless @ARGV==4;
+my( $x1, $y1 ) = split( /,/, shift );
+
+my( $x2, $y2 ) = split( /,/, shift );
+my( $x3, $y3 ) = split( /,/, shift );
+my( $x4, $y4 ) = split( /,/, shift );
+
+# make sure that x1 <= x2. y1 <= y2, x3 <= x4, y3 <= y4
+($x1,$x2) = ($x2,$x1) if $x1 > $x2;
+($y1,$y2) = ($y2,$y1) if $y1 > $y2;
+($x3,$x4) = ($x4,$x3) if $x3 > $x4;
+($y3,$y4) = ($y4,$y3) if $y3 > $y4;
+
+my $r1area = ($x2-$x1)*($y2-$y1);
+my $r2area = ($x4-$x3)*($y4-$y3);
+say "r1 area: $r1area, r2 area: $r2area" if $debug;
+
+# overlap:
+my $oxd = min($x2,$x4) - max($x1,$x3);
+my $oyd = min($y2,$y4) - max($y1,$y3);
+my $oarea = ($oxd>0 && $oyd>0) ? $oxd * $oyd : 0;
+
+say "overlapping area: $oarea" if $debug;
+
+my $total = $r1area + $r2area - $oarea;
+
+say $total;