diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-10-11 18:28:22 +0100 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-10-11 18:28:22 +0100 |
| commit | a2906a66ff83705e2106a75ecd3d64876dd69792 (patch) | |
| tree | 7d399f6b5227e1adc5caad66eaa157991c3966af | |
| parent | a423e086ba5eb73274640da603f9e36e7bf79506 (diff) | |
| parent | 923f540486f891685a527368432dc22e81eadfd7 (diff) | |
| download | perlweeklychallenge-club-a2906a66ff83705e2106a75ecd3d64876dd69792.tar.gz perlweeklychallenge-club-a2906a66ff83705e2106a75ecd3d64876dd69792.tar.bz2 perlweeklychallenge-club-a2906a66ff83705e2106a75ecd3d64876dd69792.zip | |
Merge branch 'master' of https://github.com/manwar/perlweeklychallenge-club
| -rw-r--r-- | challenge-081/bob-lied/README | 4 | ||||
| -rwxr-xr-x | challenge-081/bob-lied/perl/ch-1.pl | 46 | ||||
| -rwxr-xr-x | challenge-081/bob-lied/perl/ch-2.pl | 69 | ||||
| -rw-r--r-- | challenge-081/bob-lied/perl/lib/CommonBaseString.pm | 79 | ||||
| -rw-r--r-- | challenge-081/bob-lied/perl/t/CommonBaseString.t | 26 | ||||
| -rw-r--r-- | challenge-081/bob-lied/perl/t/input | 13 |
6 files changed, 235 insertions, 2 deletions
diff --git a/challenge-081/bob-lied/README b/challenge-081/bob-lied/README index 026576bd98..e698fa656a 100644 --- a/challenge-081/bob-lied/README +++ b/challenge-081/bob-lied/README @@ -1,3 +1,3 @@ -Solutions to weekly challenge 79 by Bob Lied. +Solutions to weekly challenge 81 by Bob Lied. -https://perlweeklychallenge.org/blog/perl-weekly-challenge-079/ +https://perlweeklychallenge.org/blog/perl-weekly-challenge-081/ diff --git a/challenge-081/bob-lied/perl/ch-1.pl b/challenge-081/bob-lied/perl/ch-1.pl new file mode 100755 index 0000000000..032b1efc8d --- /dev/null +++ b/challenge-081/bob-lied/perl/ch-1.pl @@ -0,0 +1,46 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# ch-1.pl +#============================================================================= +# Copyright (c) 2020, Bob Lied +#============================================================================= +# Perl Weekly Challenge 081 Task #1 > Common Base String +#============================================================================= +# You are given 2 strings, $A and $B. +# Write a script to find out common base strings in $A and $B. +# A substring of a string $S is called base string if repeated concatenation +# of the substring results in the string. +# Example 1: Input: $A = "abcdabcd" +# $B = "abcdabcdabcdabcd" +# Output: ("abcd", "abcdabcd") +# +# Example 2: Input: $A = "aaa" +# $B = "aa" +# Output: ("a") + +use strict; +use warnings; +use v5.30; + +use feature qw/ signatures /; +no warnings qw/ experimental::signatures /; + +use Getopt::Long; + +use lib "lib"; +use CommonBaseString; + +sub Usage { "Usage: $0 astring bstring" }; + +my $Verbose = 0; +GetOptions('verbose' => \$Verbose); + +my ($A, $B) = @ARGV; + +die Usage() unless $A; +die Usage() unless $B; + +my $cbs = CommonBaseString->new($A, $B); +my $result = $cbs->run(); +say "@$result"; diff --git a/challenge-081/bob-lied/perl/ch-2.pl b/challenge-081/bob-lied/perl/ch-2.pl new file mode 100755 index 0000000000..76c3ba067d --- /dev/null +++ b/challenge-081/bob-lied/perl/ch-2.pl @@ -0,0 +1,69 @@ +#!/usr/bin/env perl +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# ch-2.pl +#============================================================================= +# Copyright (c) 2020, Bob Lied +#============================================================================= +# Perl Weekly Challenge 081 Task #2 > Frequency Sort +#============================================================================= +# You are given file named input. +# Write a script to find the frequency of all the words. +# It should print the result as first column of each line should be the +# frequency of the the word followed by all the words of that frequency +# arranged in lexicographical order. Also sort the words in the ascending +# order of frequency. +# For the sake of this task, please ignore the following in the input file: +# . " ( ) , 's -- +# Keep hyphenated words and contractions, but reduce possessives to their base +# (e.g., "award-winning" and "doesn't" are words, but "Joe's" becomes "Joe" + +use strict; +use warnings; +use v5.30; + +use feature qw/ signatures /; +no warnings qw/ experimental::signatures /; + +use File::Slurper qw/ read_text /; + + +sub Usage { "Usage: $0 filename" }; + +my $InFile = shift; + +# It would be friendlier to allow stdin, but the spec says use a file. +die Usage() unless $InFile; + +# Slurp input file into one long string. +my $input = read_text($InFile); + +# Split on word separators, and convienently get rid of them. +# That might leave some empty strings, so filter those. +my @words = grep !/^$/, split(/\s|[\n\r."(),]/, $input); + +# These next two cleanups could be chained to make one pass, +# but let's keep it readable for now. +# +# Phrases separated by long dashes turn into multiple words. +@words = map { if (/--/) { split(/--/) } else { $_ } } @words; + +# Possessives reduce to the base noun. +@words = map { s/'s//; $_ } @words; + +my %counts; +$counts{$_}++ foreach @words; + +# Invert the hash to have counts as keys to lists of words. +my %countList; +for my $word ( keys %counts ) +{ + push @{$countList{ $counts{$word} }}, $word; +} + +# Numeric sort ascending on the counts. +for my $n ( sort { $a <=> $b } keys %countList ) +{ + say "$n\t", join " ", sort @{$countList{$n}} +} + diff --git a/challenge-081/bob-lied/perl/lib/CommonBaseString.pm b/challenge-081/bob-lied/perl/lib/CommonBaseString.pm new file mode 100644 index 0000000000..4c6f98901c --- /dev/null +++ b/challenge-081/bob-lied/perl/lib/CommonBaseString.pm @@ -0,0 +1,79 @@ +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +#============================================================================= +# CommonBaseString.pm +#============================================================================= +# Copyright (c) 2020, Bob Lied +#============================================================================= +# Description: +#============================================================================= + +package CommonBaseString; + +use strict; +use warnings; +use v5.30; + +use feature qw/ signatures /; +no warnings qw/ experimental::signatures /; + +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(); +our @EXPORT_OK = qw(commonPrefix); + +sub new($class, $a, $b) +{ + $class = ref($class) || $class; + my $self = { + _a => $a, + _b => $b, + }; + bless $self, $class; + return $self; +} + +# +sub commonPrefix($s, $t) +{ + my @s1 = split("", $s); + my @s2 = split("", $t); + my $prefix = ""; + my @possiblePrefixes = (); + + while ( @s1 && @s2 && ($s = shift @s1) eq ($t = shift @s2) ) + { + $prefix .= $s; + push @possiblePrefixes, $prefix; + } + return \@possiblePrefixes; +} + +sub run($self) +{ + my ($A, $B) = @{$self}{qw(_a _b)}; + my ($lenA, $lenB) = ( length($A), length($B) ); + my @thisWorks = (); + + my $prefixes = commonPrefix($A, $B); + + for my $prefix ( @$prefixes ) + { + my $lenP = length($prefix); + # Only prefixes that can be repeated to the length of both strings + # are candidates. + next unless $lenA % $lenP == 0; + next unless $lenB % $lenP == 0; + + # Number of repetitions required for each string. + my $repA = $lenA / $lenP; + my $repB = $lenB / $lenP; + + my $buildsA = ( ($prefix x $repA) eq $A ); + my $buildsB = ( ($prefix x $repB) eq $B ); + push @thisWorks, $prefix if ( $buildsA && $buildsB ); + } + + return \@thisWorks; +} + +1; diff --git a/challenge-081/bob-lied/perl/t/CommonBaseString.t b/challenge-081/bob-lied/perl/t/CommonBaseString.t new file mode 100644 index 0000000000..8c7108c572 --- /dev/null +++ b/challenge-081/bob-lied/perl/t/CommonBaseString.t @@ -0,0 +1,26 @@ +# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu: +# +#=============================================================================== +# FILE: CommonBaseString.t +# DESCRIPTION: Unit test for CommonBaseString +#=============================================================================== + +use strict; +use warnings; +use v5.30; + +use Test2::V0; +use lib "lib"; + +use CommonBaseString qw/ commonPrefix /; + +is( commonPrefix("abc", "def"), [ ], "commonPrefix length 0" ); +is( commonPrefix("aaa", "abc"), [ "a" ], "commonPrefix length 1" ); +is( commonPrefix("aaa", "aac"), [ "a", "aa" ], "commonPrefix length 2" ); +is( commonPrefix("abab", "abababab"), [ "a", "ab", "aba", "abab" ], "commonPrefix 2 possibilities" ); + +is( CommonBaseString->new("abcdabcd", "abcdabcdabcdabcd")->run, [ "abcd", "abcdabcd" ], "Example 1"); +is( CommonBaseString->new("aaa", "a")->run, [ "a" ], "Example 2"); + + +done_testing(); diff --git a/challenge-081/bob-lied/perl/t/input b/challenge-081/bob-lied/perl/t/input new file mode 100644 index 0000000000..5905c36971 --- /dev/null +++ b/challenge-081/bob-lied/perl/t/input @@ -0,0 +1,13 @@ +West Side Story + +The award-winning adaptation of the classic romantic tragedy "Romeo and +Juliet". The feuding families become two warring New York City gangs, the +white Jets led by Riff and the Latino Sharks, led by Bernardo. Their hatred +escalates to a point where neither can coexist with any form of understanding. +But when Riff's best friend (and former Jet) Tony and Bernardo's younger +sister Maria meet at a dance, no one can do anything to stop their love. Maria +and Tony begin meeting in secret, planning to run away. Then the Sharks and +Jets plan a rumble under the highway--whoever wins gains control of the +streets. Maria sends Tony to stop it, hoping it can end the violence. It goes +terribly wrong, and before the lovers know what's happened, tragedy strikes +and doesn't stop until the climactic and heartbreaking ending. |
