diff options
| -rw-r--r-- | challenge-294/bob-lied/README | 6 | ||||
| -rw-r--r-- | challenge-294/bob-lied/perl/ch-1.pl | 70 | ||||
| -rw-r--r-- | challenge-294/bob-lied/perl/ch-2.pl | 85 |
3 files changed, 158 insertions, 3 deletions
diff --git a/challenge-294/bob-lied/README b/challenge-294/bob-lied/README index 8d15f83c17..25a29631e8 100644 --- a/challenge-294/bob-lied/README +++ b/challenge-294/bob-lied/README @@ -1,4 +1,4 @@ -Solutions to weekly challenge 293 by Bob Lied +Solutions to weekly challenge 294 by Bob Lied -https://perlweeklychallenge.org/blog/perl-weekly-challenge-293/ -https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-293/bob-lied +https://perlweeklychallenge.org/blog/perl-weekly-challenge-294/ +https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-294/bob-lied diff --git a/challenge-294/bob-lied/perl/ch-1.pl b/challenge-294/bob-lied/perl/ch-1.pl new file mode 100644 index 0000000000..9025347618 --- /dev/null +++ b/challenge-294/bob-lied/perl/ch-1.pl @@ -0,0 +1,70 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# Copyright (c) 2024, Bob Lied +#============================================================================= +# ch-1.pl Perl Weekly Challenge 294 Task 1 Consecutive Sequence +#============================================================================= +# You are given an unsorted array of integers, @ints. +# Write a script to return the length of the longest consecutive elements +# sequence. Return -1 if none found. The algorithm must runs in O(n) time. +# Example 1 Input: @ints = (10, 4, 20, 1, 3, 2) +# Output: 4 +# The longest consecutive sequence (1, 2, 3, 4). +# Example 2 Input: @ints = (0, 6, 1, 8, 5, 2, 4, 3, 0, 7) +# Output: 9 +# Example 3 Input: @ints = (10, 30, 20) +# Output: -1 +#============================================================================= + +use v5.40; + + +use Getopt::Long; +my $Verbose = false; +my $DoTest = false; +my $Benchmark = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark); +exit(!runTest()) if $DoTest; +exit( runBenchmark($Benchmark) ) if $Benchmark; + +say consecutive(@ARGV); + +sub consecutive(@ints) +{ + my %int = map { $_ => $_ } @ints; + my $maxLen = 0; + + while ( defined(my $n = shift @ints) ) + { + if ( ! exists( $int{$n-1} ) ) + { + # $n is the start of a possible sequence + my $len = 1; + $len++ while ( exists( $int{++$n} ) ); + $maxLen = $len if $len > $maxLen; + } + } + return $maxLen > 1 ? $maxLen : -1; +} + +sub runTest +{ + use Test2::V0; + + is( consecutive(10, 4,20, 1, 3, 2), 4, "Example 1"); + is( consecutive( 0, 6, 1, 8, 5, 2, 4, 3, 0, 7), 9, "Example 2"); + is( consecutive(10,20,30), -1, "Example 3"); + + done_testing; +} + +sub runBenchmark($repeat) +{ + use Benchmark qw/cmpthese/; + + cmpthese($repeat, { + label => sub { }, + }); +} diff --git a/challenge-294/bob-lied/perl/ch-2.pl b/challenge-294/bob-lied/perl/ch-2.pl new file mode 100644 index 0000000000..fa078ba1a0 --- /dev/null +++ b/challenge-294/bob-lied/perl/ch-2.pl @@ -0,0 +1,85 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# Copyright (c) 2024, Bob Lied +#============================================================================= +# ch-2.pl Perl Weekly Challenge 294 Task 2 Next Permutation +#============================================================================= +# You are given an array of integers, @ints. +# Write a script to find out the next permutation of the given array. +# The next permutation of an array of integers is the next lexicographically +# greater permutation of its integer. +# Example 1 Input: @ints = (1, 2, 3) +# Output: (1, 3, 2) +# Permutations of (1, 2, 3) arranged lexicographically: +# (1, 2, 3) (1, 3, 2) (2, 1, 3) (2, 3, 1) (3, 1, 2) (3, 2, 1) +# +# Example 2 Input: @ints = (2, 1, 3) +# Output: (2, 3, 1) +# Example 3 Input: @ints = (3, 1, 2) +# Output: (3, 2, 1) +#============================================================================= + +use v5.40; + +use List::MoreUtils qw/last_index/; + + +use Getopt::Long; +my $Verbose = false; +my $DoTest = false; +my $Benchmark = 0; + +GetOptions("test" => \$DoTest, "verbose" => \$Verbose, "benchmark:i" => \$Benchmark); +exit(!runTest()) if $DoTest; +exit( runBenchmark($Benchmark) ) if $Benchmark; + +say "(", join(", ", nextPerm(@ARGV)->@*), ")"; + +sub nextPerm(@ints) +{ + my $pivot = -1; + for my $p ( reverse 0 .. ($#ints-1) ) + { + if ( $ints[$p] lt $ints[$p+1] ) + { + $pivot = $p; + last; + } + } + if ( $pivot < 0 ) + { + return [ sort @ints ]; + } + my $successor = last_index { $_ gt $ints[$pivot] } @ints; + + ($ints[$pivot], $ints[$successor]) = ($ints[$successor], $ints[$pivot]); + + @ints[$pivot+1 .. $#ints] = reverse @ints[$pivot+1 .. $#ints]; + + return \@ints; +} + +sub runTest +{ + use Test2::V0; + + is( nextPerm(1,2,3), [1,3,2], "Example 1"); + is( nextPerm(2,1,3), [2,3,1], "Example 2"); + is( nextPerm(3,1,2), [3,2,1], "Example 3"); + + is( nextPerm(3,2,1), [1,2,3], "Roll over"); + + is( nextPerm(1,3,5,4,2), [1,4,2,3,5], "1 3 5 4 2"); + + done_testing; +} + +sub runBenchmark($repeat) +{ + use Benchmark qw/cmpthese/; + + cmpthese($repeat, { + label => sub { }, + }); +} |
