diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2025-02-08 19:37:42 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-08 19:37:42 +0000 |
| commit | 07276cdf06f7ac9646bc88c5c417191894c4ef53 (patch) | |
| tree | 37578ce177b11a62a09c683d627d3d0208c9aff3 | |
| parent | 9da701c4cdcd5e30f92fc90201187fee65604a8a (diff) | |
| parent | d90b8ac31ce7f559d252c6f39032b2d388bb2a9e (diff) | |
| download | perlweeklychallenge-club-07276cdf06f7ac9646bc88c5c417191894c4ef53.tar.gz perlweeklychallenge-club-07276cdf06f7ac9646bc88c5c417191894c4ef53.tar.bz2 perlweeklychallenge-club-07276cdf06f7ac9646bc88c5c417191894c4ef53.zip | |
Merge pull request #11540 from boblied/w307
Week 307 solutions
| -rw-r--r-- | challenge-307/bob-lied/README | 6 | ||||
| -rw-r--r-- | challenge-307/bob-lied/perl/ch-1.pl | 76 | ||||
| -rw-r--r-- | challenge-307/bob-lied/perl/ch-2.pl | 128 |
3 files changed, 207 insertions, 3 deletions
diff --git a/challenge-307/bob-lied/README b/challenge-307/bob-lied/README index 3a6c40ed45..b3605f1ed5 100644 --- a/challenge-307/bob-lied/README +++ b/challenge-307/bob-lied/README @@ -1,4 +1,4 @@ -Solutions to weekly challenge 306 by Bob Lied +Solutions to weekly challenge 307 by Bob Lied -https://perlweeklychallenge.org/blog/perl-weekly-challenge-306/ -https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-306/bob-lied +https://perlweeklychallenge.org/blog/perl-weekly-challenge-307/ +https://github.com/boblied/perlweeklychallenge-club/tree/master/challenge-307/bob-lied diff --git a/challenge-307/bob-lied/perl/ch-1.pl b/challenge-307/bob-lied/perl/ch-1.pl new file mode 100644 index 0000000000..5cfc13335a --- /dev/null +++ b/challenge-307/bob-lied/perl/ch-1.pl @@ -0,0 +1,76 @@ +#!/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 307 Task 1 Check Order +#============================================================================= +# You are given an array of integers, @ints. +# Write a script to re-arrange the given array in an increasing order and +# return the indices where it differs from the original array. +# Example 1 Input: @ints = (5, 2, 4, 3, 1) +# Output: (0, 2, 3, 4) +# Before: (5, 2, 4, 3, 1) +# After : (1, 2, 3, 4, 5) +# Difference at indices: (0, 2, 3, 4) +# Example 2 Input: @ints = (1, 2, 1, 1, 3) +# Output: (1, 3) +# Before: (1, 2, 1, 1, 3) +# After : (1, 1, 1, 2, 3) +# Difference at indices: (1, 3) +# Example 3 Input: @ints = (3, 1, 3, 2, 3) +# Output: (0, 1, 3) +# Before: (3, 1, 3, 2, 3) +# After : (1, 2, 3, 3, 3) +# Difference at indices: (0, 1, 3) +#============================================================================= + +use v5.40; + + +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(', ', checkOrder(@ARGV)->@*), ')'; + +#============================================================================= +sub checkOrder(@ints) +{ + my @sorted = sort { $a <=> $b } @ints; + return [ grep { $ints[$_] != $sorted[$_] } 0 .. $#ints ]; +} + +sub runTest +{ + use Test2::V0; + + is( checkOrder(5,2,4,3,1), [0,2,3,4], "Example 1"); + is( checkOrder(1,2,1,1,3), [1,3 ], "Example 2"); + is( checkOrder(3,1,3,2,3), [0,1,3 ], "Example 3"); + + done_testing; +} + +sub runBenchmark($repeat) +{ + use Benchmark qw/cmpthese/; + + cmpthese($repeat, { + label => sub { }, + }); +} diff --git a/challenge-307/bob-lied/perl/ch-2.pl b/challenge-307/bob-lied/perl/ch-2.pl new file mode 100644 index 0000000000..5b5a7c84a9 --- /dev/null +++ b/challenge-307/bob-lied/perl/ch-2.pl @@ -0,0 +1,128 @@ +#!/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 307 Task 2 Find Anagrams +#============================================================================= +# You are given a list of words, @words. +# Write a script to find any two consecutive words and if they are anagrams, +# drop the first word and keep the second. You continue this until there is +# no more anagrams in the given list and return the count of final list. +# Example 1 Input: @words = ("acca", "dog", "god", "perl", "repl") +# Output: 3 +# Step 1: "dog" and "god" are anagrams, so drop "dog" and keep "god" +# => ("acca", "god", "perl", "repl") +# Step 2: "perl" and "repl" are anagrams, so drop "perl" and keep "repl" +# => ("acca", "god", "repl") +# +# Example 2 Input: @words = ("abba", "baba", "aabb", "ab", "ab") +# Output: 2 +# Step 1: "abba" and "baba" are anagrams, so drop "abba" and keep "baba" +# => ("baba", "aabb", "ab", "ab") +# Step 2: "baba" and "aabb" are anagrams, so drop "baba" and keep "aabb" +# => ("aabb", "ab", "ab") +# Step 3: "ab" and "ab" are anagrams, so drop "ab" and keep "ab" +# => ("aabb", "ab") +#============================================================================= + +use v5.40; + + +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 findAnagram_general(@ARGV); + +#============================================================================= +use Memoize; +memoize("canonical"); +sub canonical($word) +{ + join "", sort split //, $word +} + +sub findAnagram(@words) +{ + my @out = ( $words[0] ); + for my $i ( 0 .. $#words-1 ) + { + if ( canonical($words[$i]) eq canonical($words[$i+1]) ) + { + $out[-1] = $words[$i+1]; + } + else + { + push @out, $words[$i+1] + } + } + return scalar(@out); +} + +sub fa(@words) +{ + my @out = ( my $first = shift @words ); + while ( defined(my $second = shift @words) ) + { + if ( canonical($first) eq canonical($second) ) + { + $out[-1] = $second; + } + else + { + push @out, $second; + } + $first = $second; + } + return scalar(@out); +} + +# If the anagrams can appear anywhere, it amounts to finding all the unique ones. +# Despite the hashing overhead, this is twice as fast as the loops over pairs. +sub findAnagram_general(@words) +{ + my %base; + $base{ canonical($_) }++ for @words; + return scalar %base; + +} + +sub runTest +{ + use Test2::V0; + + is( findAnagram("acca", "dog", "god", "perl", "repl"), 3, "Example 1"); + is( findAnagram("abba", "baba", "aabb", "ab", "ab" ), 2, "Example 2"); + + is( fa("acca", "dog", "god", "perl", "repl"), 3, "Example 1"); + is( fa("abba", "baba", "aabb", "ab", "ab" ), 2, "Example 2"); + + done_testing; +} + +sub runBenchmark($repeat) +{ + use Benchmark qw/cmpthese/; + my @words = ( "aa" .. "iz", 'aa' .. 'iz'); + + cmpthese($repeat, { + forloop => sub { findAnagram(@words) }, + shifting => sub { fa(@words) }, + general => sub { findAnagram_general(@words) }, + }); +} |
