diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-08-15 11:07:18 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-15 11:07:18 +0100 |
| commit | dfb6071b6c61c2f32624c6aec098ad56bf9787c2 (patch) | |
| tree | 73d2ca996324d7ea7223bcbc39a50591ab624fd5 | |
| parent | 91fc1e2a3d45918371c6aef884d0285e67ee0e16 (diff) | |
| parent | 39abbda0c80086a3a771482fce3cedf65fe2a6ea (diff) | |
| download | perlweeklychallenge-club-dfb6071b6c61c2f32624c6aec098ad56bf9787c2.tar.gz perlweeklychallenge-club-dfb6071b6c61c2f32624c6aec098ad56bf9787c2.tar.bz2 perlweeklychallenge-club-dfb6071b6c61c2f32624c6aec098ad56bf9787c2.zip | |
Merge pull request #12519 from boblied/w334
Week 334 solutions from Bob Lied
| -rw-r--r-- | challenge-334/bob-lied/README.md | 8 | ||||
| -rw-r--r-- | challenge-334/bob-lied/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-334/bob-lied/perl/ch-1.pl | 72 | ||||
| -rw-r--r-- | challenge-334/bob-lied/perl/ch-2.pl | 110 |
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 { }, + }); +} + |
