aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-05-27 18:01:55 +0200
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-05-27 18:01:55 +0200
commitc7179e9e7ed4a10bbdd5227a5ee47a92bcbef234 (patch)
tree98ac42ea06549c38c45a61ab3172156a11d23694
parentfcd2d4bdde323600dd7022afb0c5374c3d324795 (diff)
parent38fe9d67ea8576cc101c56d1672ae0f4be947ce3 (diff)
downloadperlweeklychallenge-club-c7179e9e7ed4a10bbdd5227a5ee47a92bcbef234.tar.gz
perlweeklychallenge-club-c7179e9e7ed4a10bbdd5227a5ee47a92bcbef234.tar.bz2
perlweeklychallenge-club-c7179e9e7ed4a10bbdd5227a5ee47a92bcbef234.zip
Solutions to challenge 166
-rwxr-xr-xchallenge-166/jo-37/perl/ch-1.pl17
-rwxr-xr-xchallenge-166/jo-37/perl/ch-2.pl68
2 files changed, 85 insertions, 0 deletions
diff --git a/challenge-166/jo-37/perl/ch-1.pl b/challenge-166/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..1453c835a7
--- /dev/null
+++ b/challenge-166/jo-37/perl/ch-1.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl
+
+use v5.16;
+use warnings;
+
+$ARGV[0] ||= '../../../data/dictionary.txt';
+
+while (<>) {
+ chomp;
+ tr/olist/01157/;
+ next unless /^[0-9a-f]{2,8}$/;
+ # Allow a maximum of two lesser comprehensible letters.
+ # Force global match into list context, then convert to scalar.
+ # See "Goatse" in perlsecret.
+ next if 2 < (() = /[157]/g);
+ say "0x\u$_";
+}
diff --git a/challenge-166/jo-37/perl/ch-2.pl b/challenge-166/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..3b395a8df2
--- /dev/null
+++ b/challenge-166/jo-37/perl/ch-2.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+use v5.16;
+use warnings;
+use autodie;
+use List::Util qw(max pairgrep);
+use experimental 'signatures';
+
+
+die <<EOS unless @ARGV;
+usage: $0 dir...
+
+dir...
+ Compare content of given directories
+
+EOS
+
+
+### Input and Output
+
+print_diff(\@ARGV, dir_diff(@ARGV));
+
+
+### Implementation
+
+# Build a hash with the file names found in any directory as keys and an
+# array indicating the files' presence within the directories. Files
+# contained in all directories are filtered out. Equally named files
+# and directories are regarded as different objects. File contents are
+# not compared.
+sub dir_diff (@dirs) {
+ my %files;
+ # Loop over the directories.
+ while (my ($i, $dir) = each @dirs) {
+ opendir(my $dh, $dir);
+ # Loop over the directory's files.
+ while (readdir $dh) {
+ # Append "/" to directories.
+ $_ .= '/' if -d "$dir/$_";
+ # Set an indicator for the current directory.
+ $files{$_}[$i] = 1;
+ }
+ closedir $dh;
+ }
+
+ # Exclude files that exist in all directories.
+ +{pairgrep {@dirs > grep $_, @$b} %files};
+}
+
+# Print the directory diff in a terse matrix format: "X" indicates the
+# presence of a file in a directory.
+sub print_diff ($dir, $diff) {
+ my $dlen = max map length, @$dir;
+ my $flen = max 0, map length, keys %$diff;
+
+ # Table header
+ printf "%${flen}s" . (" | %${dlen}s" x @$dir) . "\n",
+ '', @$dir;
+ printf "%${flen}s" . ("-+-%${dlen}s" x @$dir) . "\n",
+ '-' x $flen, ('-' x $dlen) x @$dir;
+
+ # Table rows
+ for my $file (sort keys %$diff) {
+ printf "%-${flen}s", $file;
+ printf " | %${dlen}s", 'X' x !!$diff->{$file}[$_] for 0 .. $#$dir;
+ print "\n";
+ }
+}