aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-294/bob-lied/README6
-rw-r--r--challenge-294/bob-lied/perl/ch-1.pl70
-rw-r--r--challenge-294/bob-lied/perl/ch-2.pl85
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 { },
+ });
+}