diff options
| -rw-r--r-- | challenge-333/bob-lied/README.md | 6 | ||||
| -rw-r--r-- | challenge-333/bob-lied/ch-1.pl | 61 | ||||
| -rw-r--r-- | challenge-333/bob-lied/ch-2.pl | 120 |
3 files changed, 184 insertions, 3 deletions
diff --git a/challenge-333/bob-lied/README.md b/challenge-333/bob-lied/README.md index 638a1c686d..111cb8efef 100644 --- a/challenge-333/bob-lied/README.md +++ b/challenge-333/bob-lied/README.md @@ -1,5 +1,5 @@ -# Solutions to weekly challenge 332 by Bob Lied +# Solutions to weekly challenge 333 by Bob Lied -## [PWC](https://perlweeklychallenge.org/blog/perl-weekly-challenge-332/) -## [GitHub](https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-332/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) diff --git a/challenge-333/bob-lied/ch-1.pl b/challenge-333/bob-lied/ch-1.pl new file mode 100644 index 0000000000..b049e22a70 --- /dev/null +++ b/challenge-333/bob-lied/ch-1.pl @@ -0,0 +1,61 @@ +#!/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 333 Task 1 Straight Line +#============================================================================= +# You are given a list of co-ordinates. Write a script to find out if the +# given points make a straight line. +# Example 1 Input: @list = ([2, 1], [2, 3], [2, 5]) +# Output: true +# Example 2 Input: @list = ([1, 4], [3, 4], [10, 4]) +# Output: true +# Example 3 Input: @list = ([0, 0], [1, 1], [2, 3]) +# Output: false +# Example 4 Input: @list = ([1, 1], [1, 1], [1, 1]) +# Output: true +# Example 5 Input: @list = ([1000000, 1000000], [2000000, 2000000], [3000000, 3000000]) +# Output: true +#============================================================================= + +use v5.42; + + +use Getopt::Long; +my $DoTest = false; + +GetOptions("test" => \$DoTest); +#============================================================================= + +exit(!runTest()) if $DoTest; + +# Use as ch-1.pl 1,1 2,2 3,3 + +my @point = map { [split ',', $_] } @ARGV; +die "Need three points" unless @point == 3; + +say isLine(@point) ? "true" : "false"; + +#============================================================================= +## https://math.stackexchange.com/questions/701862/how-to-find-if-the-points-fall-in-a-straight-line-or-not +sub isLine(@point) +{ + my @x = map { $_->[0] } @point; + my @y = map { $_->[1] } @point; + + return ($y[1] - $y[0]) * ( $x[2] - $x[0] ) == ( $y[2] - $y[0] ) * ( $x[1] - $x[0] ) +} + +sub runTest +{ + use Test2::V0; + + is( isLine( [2,1],[2,3],[ 2,5] ), true, "Example 1"); + is( isLine( [1,4],[3,4],[10,4] ), true, "Example 2"); + is( isLine( [0,0],[1,1],[ 2,3] ), false, "Example 3"); + is( isLine( [1,1],[1,1],[ 1,1] ), true, "Example 4"); + is( isLine( [1000000, 1000000], [2000000, 2000000], [3000000, 3000000] ), true, "Example 5"); + + done_testing; +} diff --git a/challenge-333/bob-lied/ch-2.pl b/challenge-333/bob-lied/ch-2.pl new file mode 100644 index 0000000000..d05efc9a27 --- /dev/null +++ b/challenge-333/bob-lied/ch-2.pl @@ -0,0 +1,120 @@ +#!/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 333 Task 2 Duplicate Zeroes +#============================================================================= +# You are given an array of integers. Write a script to duplicate each +# occurrence of zero, shifting the remaining elements to the right. +# The elements beyond the length of the original array are not written. +# Example 1 Input: @ints = (1, 0, 2, 3, 0, 4, 5, 0) +# Output: (1, 0, 0, 2, 3, 0, 0, 4) +# Each zero is duplicated. +# Elements beyond the original length (like 5 and last 0) are discarded. +# Example 2 Input: @ints = (1, 2, 3) +# Output: (1, 2, 3) +# No zeros exist, so the array remains unchanged. +# Example 3 Input: @ints = (1, 2, 3, 0) +# Output: (1, 2, 3, 0) +# Example 4 Input: @ints = (0, 0, 1, 2) +# Output: (0, 0, 0, 0) +# Example 5 Input: @ints = (1, 2, 0, 3, 4) +# Output: (1, 2, 0, 0, 3) +#============================================================================= + +use v5.42; + + +use Getopt::Long; +my $Verbose = false; +my $DoTest = false; +my $Benchmark = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark); +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; + +say '(', join(", ", dupSplice(@ARGV)->@*), ')'; +# say '(', join(", ", dupCut(@ARGV)->@*), ')'; +#say '(', join(", ", duplicateZero(@ARGV)->@*), ')'; + +#============================================================================= +sub duplicateZero(@int) +{ + my @out; + my $length = @int; + while ( defined(my $n = shift @int) && @out < $length) + { + push @out, $n; + push @out, 0 if $n == 0 && @out < $length; + } + return \@out; +} + +sub dupCut(@int) +{ + my @out = map { $_ == 0 ? (0,0) : ($_) } @int; + splice(@out, scalar(@int) ); + return \@out; +} + +sub dupSplice(@int) +{ + my $length = @int; + for ( reverse 0 .. $#int ) + { + splice(@int, $_, 1, 0,0) if $int[$_] == 0; + } + splice(@int, $length); + return \@int; +} + +sub runTest +{ + use Test2::V0; + + is( duplicateZero( 1,0,2,3,0,4,5,0), [1,0,0,2,3,0,0,4], "Example 1"); + is( duplicateZero( 1,2,3 ), [1,2,3 ], "Example 2"); + is( duplicateZero( 1,2,3,0 ), [1,2,3,0 ], "Example 3"); + is( duplicateZero( 0,0,1,2 ), [0,0,0,0 ], "Example 4"); + is( duplicateZero( 1,2,0,3,4 ), [1,2,0,0,3 ], "Example 5"); + + is( dupCut( 1,0,2,3,0,4,5,0), [1,0,0,2,3,0,0,4], "Example 1 cut"); + is( dupCut( 1,2,3 ), [1,2,3 ], "Example 2 cut"); + is( dupCut( 1,2,3,0 ), [1,2,3,0 ], "Example 3 cut"); + is( dupCut( 0,0,1,2 ), [0,0,0,0 ], "Example 4 cut"); + is( dupCut( 1,2,0,3,4 ), [1,2,0,0,3 ], "Example 5 cut"); + + is( dupSplice( 1,0,2,3,0,4,5,0), [1,0,0,2,3,0,0,4], "Example 1 splice"); + is( dupSplice( 1,2,3 ), [1,2,3 ], "Example 2 splice"); + is( dupSplice( 1,2,3,0 ), [1,2,3,0 ], "Example 3 splice"); + is( dupSplice( 0,0,1,2 ), [0,0,0,0 ], "Example 4 splice"); + is( dupSplice( 1,2,0,3,4 ), [1,2,0,0,3 ], "Example 5 splice"); + + done_testing; +} + +sub runBenchmark($repeat) +{ + use Benchmark qw/cmpthese/; + + my @int = map { int(rand(20)) + 1 } 1 .. 100; + $int[$_] = 0 for map { int(rand(100)) } 1..10; + # my @int = (0) x 100; + + cmpthese($repeat, { + copy => sub { duplicateZero(@int) }, + cut => sub { dupCut(@int) }, + splice => sub { dupSplice(@int) }, + }); +} |
