From 05130909e425e47598905389b597a601c2638085 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 22 Dec 2020 10:16:16 +0000 Subject: pushed stuff --- challenge-092/james-smith/perl/ch-1-firstpass.pl | 34 +++++++++++++++++ .../james-smith/perl/ch-1-list-iso-words.pl | 44 ++++++++++++++++++++++ challenge-092/james-smith/perl/ch-1.pl | 34 +++++++++-------- 3 files changed, 96 insertions(+), 16 deletions(-) create mode 100644 challenge-092/james-smith/perl/ch-1-firstpass.pl create mode 100644 challenge-092/james-smith/perl/ch-1-list-iso-words.pl diff --git a/challenge-092/james-smith/perl/ch-1-firstpass.pl b/challenge-092/james-smith/perl/ch-1-firstpass.pl new file mode 100644 index 0000000000..b4fc12b5e3 --- /dev/null +++ b/challenge-092/james-smith/perl/ch-1-firstpass.pl @@ -0,0 +1,34 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( iso('abc','xyz'), 1 ); +is( iso('abb','xyy'), 1 ); +is( iso('sum','add'), 0 ); +is( iso('add','sum'), 0 ); + +done_testing( ); + +sub iso { + my ($a,$b) = @_; + my %x; + my %y; + return 0 unless length $a == length $b; + my @b = split m{}, $b; + foreach ( split m{}, $a ) { + my $t = shift @b; + if( exists $x{$_} ) { ## Have we already got a map from 1st letter? + return 0 unless $x{$_} eq $t; ## Yes but it doesn't match return... + } else { + $x{$_} = $t; + return 0 if exists $y{$t} && $y{$t} ne $_; + } + $y{$t} = $_; + } + return 1; +} + diff --git a/challenge-092/james-smith/perl/ch-1-list-iso-words.pl b/challenge-092/james-smith/perl/ch-1-list-iso-words.pl new file mode 100644 index 0000000000..040b7e5db1 --- /dev/null +++ b/challenge-092/james-smith/perl/ch-1-list-iso-words.pl @@ -0,0 +1,44 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +## Usage +# +# perl ch-1-list-iso-words.pl {n} < wordlist.txt +# +# Where wordlist is a list of lowercased words with no hyphens etc +# +# {n} is optional if 0 - it lists all words +# {n} > 0 lists all words who have {n} or more repeated characters e.g. abba has two eerie has two + +my $filter = 0; +$filter = $ARGV[0] if @ARGV; +my %words; + +while() { + chomp; + ## Initialise letter cache and "counter" + next if 1 == length $_; + my($x,%m)='a'; + push @{$words{join '', ## Stitch back the word and return it.... + map { $m{$_}||=$x++ } ## Return letter from cache (or next letter) + split m{}, $_ ## Split into individual characters + }}, $_; +} + +foreach ( sort { (length($a)<=> length($b)) || (reverse($a) cmp reverse($b)) } keys %words) { + next if @{$words{$_}} <2; + if( $filter > 0 ) { + my %t; + %t = map { $_=>1 } split m{}, $_; + my $l = scalar keys %t; + next unless $l < length($_) - $filter -1; + } + printf "%4d : %4d : %5d : %20s : %s\n", + length $_, length($_)-$l, (scalar @{$words{$_}}), $_, "@{$words{$_}}"; +} + diff --git a/challenge-092/james-smith/perl/ch-1.pl b/challenge-092/james-smith/perl/ch-1.pl index b4fc12b5e3..7b6ce67bb0 100644 --- a/challenge-092/james-smith/perl/ch-1.pl +++ b/challenge-092/james-smith/perl/ch-1.pl @@ -14,21 +14,23 @@ is( iso('add','sum'), 0 ); done_testing( ); sub iso { - my ($a,$b) = @_; - my %x; - my %y; - return 0 unless length $a == length $b; - my @b = split m{}, $b; - foreach ( split m{}, $a ) { - my $t = shift @b; - if( exists $x{$_} ) { ## Have we already got a map from 1st letter? - return 0 unless $x{$_} eq $t; ## Yes but it doesn't match return... - } else { - $x{$_} = $t; - return 0 if exists $y{$t} && $y{$t} ne $_; - } - $y{$t} = $_; - } - return 1; + ## This one needs a bit of explanation.... + ## We are going to normalise the strings - by replacing first chr + ## and all its subsequent occurances with 'a', 2nd (different) character + ## with 'b' ..... + ## so above examples we get... + ## abc -> abc xyz -> abc + ## abb -> abb xyy -> abb + ## sum -> abc add -> abb + ## add -> abc sum -> abc + + my ($a,$b) = map { + ## Initialise letter cache and "counter" + my ($x,%m)='a'; + join '', ## Stitch back the word and return it.... + map { $m{$_}||=$x++ } ## Return letter from cache (or next letter) + split m{}, $_ ## Split into individual characters + } @_; + return $a eq $b ? 1 : 0; ## Check to see if generated words are isomorphic } -- cgit From 18715b2d7b5df3abcc0a144a4795b78459f556ce Mon Sep 17 00:00:00 2001 From: drbaggy Date: Tue, 22 Dec 2020 10:33:27 +0000 Subject: added a version of the call without comments as the comments make it harder to view the "beauty" of the method --- challenge-092/james-smith/perl/ch-1.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/challenge-092/james-smith/perl/ch-1.pl b/challenge-092/james-smith/perl/ch-1.pl index 7b6ce67bb0..43a1d4c5e3 100644 --- a/challenge-092/james-smith/perl/ch-1.pl +++ b/challenge-092/james-smith/perl/ch-1.pl @@ -31,6 +31,11 @@ sub iso { map { $m{$_}||=$x++ } ## Return letter from cache (or next letter) split m{}, $_ ## Split into individual characters } @_; - return $a eq $b ? 1 : 0; ## Check to see if generated words are isomorphic + return $a eq $b || 0; ## Check to see if generated words are isomorphic +} + +sub iso_without_comments { + my ($a,$b) = map { my ($x,%m)='a'; join '', map { $m{$_}||=$x++ } split m{}, $_ } @_; + return $a eq $b || 0; } -- cgit