aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Lied <boblied+github@gmail.com>2025-08-13 19:21:27 -0500
committerBob Lied <boblied+github@gmail.com>2025-08-13 19:21:27 -0500
commit39abbda0c80086a3a771482fce3cedf65fe2a6ea (patch)
tree325a41872d2df9e435665fda4b81a6039db6eb3e
parent730e172acb159a2fc320a78a6250083328ef1067 (diff)
downloadperlweeklychallenge-club-39abbda0c80086a3a771482fce3cedf65fe2a6ea.tar.gz
perlweeklychallenge-club-39abbda0c80086a3a771482fce3cedf65fe2a6ea.tar.bz2
perlweeklychallenge-club-39abbda0c80086a3a771482fce3cedf65fe2a6ea.zip
Week 334 solutions and blog reference
-rw-r--r--challenge-334/bob-lied/README.md8
-rw-r--r--challenge-334/bob-lied/blog.txt1
-rw-r--r--challenge-334/bob-lied/perl/ch-1.pl72
-rw-r--r--challenge-334/bob-lied/perl/ch-2.pl110
4 files changed, 187 insertions, 4 deletions
diff --git a/challenge-334/bob-lied/README.md b/challenge-334/bob-lied/README.md
index 111cb8efef..44956b4173 100644
--- a/challenge-334/bob-lied/README.md
+++ b/challenge-334/bob-lied/README.md
@@ -1,5 +1,5 @@
-# Solutions to weekly challenge 333 by Bob Lied
+# Solutions to weekly challenge 334 by Bob Lied
-## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-333/)
-## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-333/bob-lied)
-[Blog](https://dev.to/boblied/pwc-331-332-odd-last-date-letters-binary-word-list-buddy-ib6)
+## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-334/)
+## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-334/bob-lied)
+[Blog](https://dev.to/boblied/pwc-334-first-we-do-the-range-sum-then-we-take-manhattan-3n62)
diff --git a/challenge-334/bob-lied/blog.txt b/challenge-334/bob-lied/blog.txt
new file mode 100644
index 0000000000..15049b99e4
--- /dev/null
+++ b/challenge-334/bob-lied/blog.txt
@@ -0,0 +1 @@
+https://dev.to/boblied/pwc-334-first-we-do-the-range-sum-then-we-take-manhattan-3n62
diff --git a/challenge-334/bob-lied/perl/ch-1.pl b/challenge-334/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..86a69de3dd
--- /dev/null
+++ b/challenge-334/bob-lied/perl/ch-1.pl
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge 334 Task 1 Range Sum
+#=============================================================================
+# You are given a list integers and pair of indices. Write a script
+# to return the sum of integers between the given indices (inclusive).
+# Example 1 Input: @ints = (-2, 0, 3, -5, 2, -1), $x = 0, $y = 2
+# Output: 1
+# Example 2 Input: @ints = (1, -2, 3, -4, 5), $x = 1, $y = 3
+# Output: -3
+# Example 3 Input: @ints = (1, 0, 2, -1, 3), $x = 3, $y = 4
+# Output: 2
+# Example 4 Input: @ints = (-5, 4, -3, 2, -1, 0), $x = 0, $y = 3
+# Output: -2
+# Example 5 Input: @ints = (-1, 0, 2, -3, -2, 1), $x = 0, $y = 2
+# Output: 1
+#=============================================================================
+
+use v5.42;
+
+
+use Getopt::Long;
+my $DoTest = false;
+
+my $X;
+my $Y;
+
+GetOptions("test" => \$DoTest, "x:i" => \$X, "y:i" => \$Y);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => $DEBUG,
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+
+$X //= 0;
+$Y //= $#ARGV;
+say rangeSum($X, $Y, \@ARGV);
+
+#=============================================================================
+sub rangeSum($x, $y, $ints)
+{
+ use List::Util qw/sum0/;
+ if ( $x > $y ) { ($x, $y) = ($y, $x) }
+
+ return sum0 map { $_ // 0 } $ints->@[$x .. $y];
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( rangeSum(0,2, [-2, 0, 3, -5, 2, -1] ), 1, "Example 1");
+ is( rangeSum(1,3, [1,-2,3,-4,,5 ] ), -3, "Example 2");
+ is( rangeSum(3,4, [1,0,2,-1,3 ] ), 2, "Example 3");
+ is( rangeSum(0,3, [-5,4,-3,2,-1,0 ] ), -2, "Example 4");
+ is( rangeSum(0,2, [-1,0,3,-3,-2,1 ] ), 2, "Example 5");
+
+ is( rangeSum(0,0, [ 9,0,3,-3,-2,1 ] ), 9, "Singleton");
+ is( rangeSum(1,9, [ 0 ] ), 0, "Out of range");
+ is( rangeSum(1,9, [ 0,1,2,3 ] ), 6, "Partial range");
+ is( rangeSum(3,2, [ 0,1,2,3 ] ), 5, "Backwards?");
+
+ done_testing;
+}
diff --git a/challenge-334/bob-lied/perl/ch-2.pl b/challenge-334/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..6c6a8cdfe2
--- /dev/null
+++ b/challenge-334/bob-lied/perl/ch-2.pl
@@ -0,0 +1,110 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# Copyright (c) 2025, Bob Lied
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge 334 Task 2 Nearest Valid Point
+#=============================================================================
+# You are given current location as two integers: x and y. You are also
+# given a list of points on the grid. A point is considered valid if it
+# shares either the same x-coordinate or the same y-coordinate as the
+# current location. Write a script to return the index of the valid point
+# that has the smallest Manhattan distance to the current location.
+# If multiple valid points are tied for the smallest distance, return
+# the one with the lowest index. If no valid points exist, return -1.
+# The Manhattan distance between two points (x1, y1) and (x2, y2)
+# is calculated as: |x1 - x2| + |y1 - y2|
+#
+# Example 1 Input: $x = 3, $y = 4, @points ([1, 2], [3, 1], [2, 4], [2, 3])
+# Output: 2
+# Valid points: [3, 1] (same x), [2, 4] (same y)
+# Manhattan distances: [3, 1] => |3-3| + |4-1| = 3
+# [2, 4] => |3-2| + |4-4| = 1
+# Closest valid point is [2, 4] at index 2.
+#
+# Example 2 Input: $x = 2, $y = 5, @points ([3, 4], [2, 3], [1, 5], [2, 5])
+# Output: 3
+# Example 3 Input: $x = 1, $y = 1, @points ([2, 2], [3, 3], [4, 4])
+# Output: -1
+# No point shares x or y with (1, 1).
+# Example 4 Input: $x = 0, $y = 0, @points ([0, 1], [1, 0], [0, 2], [2, 0])
+# Output: 0
+# Example 5 Input: $x = 5, $y = 5, @points ([5, 6], [6, 5], [5, 4], [4, 5])
+# Output: 0
+#=============================================================================
+
+use v5.42;
+
+
+use Getopt::Long;
+my $Verbose = false;
+my $DoTest = false;
+my $Benchmark = 0;
+
+my $X = 0;
+my $Y = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark,
+ "x:i" => \$X, "y:i" => \$Y);
+my $logger;
+{
+ use Log::Log4perl qw(:easy);
+ Log::Log4perl->easy_init({ level => ($Verbose ? $DEBUG : $INFO ),
+ layout => "%d{HH:mm:ss.SSS} %p{1} %m%n" });
+ $logger = Log::Log4perl->get_logger();
+}
+#=============================================================================
+
+exit(!runTest()) if $DoTest;
+exit( runBenchmark($Benchmark) ) if $Benchmark;
+
+# Usage: perl ch-2.pl -x 0 -y 0 1,1 2,0 0,3 1,1
+my @POINT = map { [split(',', $_)] } @ARGV;
+say nvp($X, $Y, \@POINT);
+
+#=============================================================================
+sub nvp($x, $y, $point)
+{
+ my $minIndex;
+ my $minDistance;
+ for my ($i, $p) (indexed reverse @$point)
+ {
+ next unless $p->[0] == $x || $p->[1] == $y;
+
+
+ # Literally: my $d = abs($x - $p->[0]) + abs( $y - $p->[1] );
+ # We only need to do one abs() call because one of those differences
+ # must be zero.
+ my $d = abs($x - $p->[0] + $y - $p->[1] );
+ $minDistance //= $d;
+ if ( $d <= $minDistance )
+ {
+ $minIndex = $i;
+ $minDistance = $d;
+ }
+ }
+ return $minIndex // -1;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( nvp(3,4, [ [1, 2], [3, 1], [2, 4], [2, 3] ]), 2, "Example 1");
+ is( nvp(2,5, [ [3, 4], [2, 3], [1, 5], [2, 5] ]), 3, "Example 2");
+ is( nvp(1,1, [ [2, 2], [3, 3], [4, 4] ]), -1, "Example 3");
+ is( nvp(0,0, [ [0, 1], [1, 0], [0, 2], [2, 0] ]), 0, "Example 4");
+ is( nvp(5,5, [ [5, 6], [6, 5], [5, 4], [4, 5] ]), 0, "Example 5");
+
+ done_testing;
+}
+
+sub runBenchmark($repeat)
+{
+ use Benchmark qw/cmpthese/;
+
+ cmpthese($repeat, {
+ label => sub { },
+ });
+}
+