I’ve been doing the Weekly
Challenges. The
latest
involved finding minimum paths and overlapping rectangles. (Note that
this is open until 20 February 2022.)
Task 1: Triangle Sum Path
You are given a triangle array.
Write a script to find the minimum sum path from top to bottom.
With some clarification from the examples, this isn't "descend either
left or right" – which would be quite like last week's part 2 – but
"pick one entry from each row". Which is therefore pretty simple; in
Perl:
sub tsp {
my $tree = shift;
my $mp=0;
foreach my $r (@{$tree}) {
$mp+=min(@{$r});
}
return $mp;
}
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.
The basic approach here is to take the area of each rectangle
separately, then subtract the area common to both (if any).
(If you have the outline of a simple polygon there's a rather neat
formula for the
area, but getting to a single outline would have been more work than
doing it this way.)
I'm not sure quite why, but this felt like one to do in an OOP style.
(Admittedly in a half-hearted way in PostScript; I think it should be
possible to define an object as a dict
, as Lua does in effect, and
attach methods directly to it, but I just wrote them as plain code
blocks.) Here's the JavaScript version.
When we initialise the object, we sort it so that xy1
has the lower
left coordinates and xy2
the upper right. (This isn't necessary with
the examples given, but.)
function Rect(xy1,xy2) {
let r=Object.create(Rect.methods);
r.xy1=[Math.min(xy1[0],xy2[0]),Math.min(xy1[1],xy2[1])];
r.xy2=[Math.max(xy1[0],xy2[0]),Math.max(xy1[1],xy2[1])];
return r;
}
Rect.methods = {
We need three methods apart from the constructor. First, the simple
area calculator:
area() {
let area=1;
for (let axis=0;axis<=1;axis++) {
area *= this.xy2[axis]-this.xy1[axis];
}
return area;
},
The overlap calculator (I use other
as a contrast with the self
in
most other languages; I suppose for JS I should have used that
contrasting with this
). Note that this is just as susceptible to a
per-axis approach as the area calculator above; on any given axis, the
degree of overlap is the smaller of the two high coordinates, minus
the larger of the two low coordinates. If they don't overlap at all,
this number will be zero or negative, so we make sure it's not below
zero.
overlap(other) {
let area=1;
for (let axis=0;axis<=1;axis++) {
area *= Math.max(0,
Math.min(this.xy2[axis],other.xy2[axis])-
Math.max(this.xy1[axis],other.xy1[axis])
);
}
return area;
},
And the "full area" calculator: the object's own area, plus the area
of the other rectangle, minus the overlap.
fullarea(other) {
return this.area()+other.area()-this.overlap(other);
}
}
Full code on
github.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.