aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-004/athanasius/perl5/ch-1.pl2
-rw-r--r--challenge-004/athanasius/perl5/ch-2.pl72
2 files changed, 74 insertions, 0 deletions
diff --git a/challenge-004/athanasius/perl5/ch-1.pl b/challenge-004/athanasius/perl5/ch-1.pl
new file mode 100644
index 0000000000..434e378932
--- /dev/null
+++ b/challenge-004/athanasius/perl5/ch-1.pl
@@ -0,0 +1,2 @@
+use bignum 'bpi';
+print "\n", bpi(-s __FILE__), "\n";
diff --git a/challenge-004/athanasius/perl5/ch-2.pl b/challenge-004/athanasius/perl5/ch-2.pl
new file mode 100644
index 0000000000..8c6339a41b
--- /dev/null
+++ b/challenge-004/athanasius/perl5/ch-2.pl
@@ -0,0 +1,72 @@
+use strict;
+use warnings;
+use Data::Dump qw( pp );
+
+# Usage: perl Challenge_2.pl <filename> <letters>
+#
+# <letters> may be given in "words" separated by whitespace; the whitespace will
+# be ignored
+
+scalar @ARGV >= 2
+ or die "\nUsage: perl $0 <filename> <letters>, stopped";
+
+my ($filename, @letters) = @ARGV;
+
+open my $fh, '<', $filename
+ or die "Cannot open file '$filename' for reading, stopped";
+
+my %words_found;
+my %letters;
+++$letters{$_} for map { lc } split //, join('', @letters);
+
+while (my $line = <$fh>)
+{
+ $line =~ s/\s//g; # Remove all whitespace (incl. trailing newline)
+ my $word = lc $line; # Convert to lower case to make case insensitive
+
+ if (exists $words_found{$word})
+ {
+ ++$words_found{$word};
+ }
+ else
+ {
+ my @word_letters = sort map { lc } split //, $word;
+ ++$words_found{$word} if is_submultiset(@word_letters);
+ }
+}
+
+close $fh
+ or die "Cannot close file '$filename', stopped";
+
+# Display results
+
+if (scalar keys %words_found == 0)
+{
+ print "\nNo words found\n";
+}
+else
+{
+ print "\nWords found:\n", pp(\%words_found), "\n";
+}
+
+# Return 1 if the given letters are a sub-multiset of the multiset @letters
+# 0 otherwise
+
+sub is_submultiset
+{
+ my %word_letters;
+
+ for (@_)
+ {
+ return 0 unless exists $letters{$_};
+ ++$word_letters{$_};
+ }
+
+ for (keys %word_letters)
+ {
+ return 0 if $word_letters{$_} > $letters{$_};
+ }
+
+ return 1;
+}
+