aboutsummaryrefslogtreecommitdiff
path: root/challenge-166
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-05-24 14:22:52 +0200
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2022-05-27 18:01:13 +0200
commit38fe9d67ea8576cc101c56d1672ae0f4be947ce3 (patch)
tree98ac42ea06549c38c45a61ab3172156a11d23694 /challenge-166
parent780ce6107eca4fae3e52184a89a39bed8e45f6c0 (diff)
downloadperlweeklychallenge-club-38fe9d67ea8576cc101c56d1672ae0f4be947ce3.tar.gz
perlweeklychallenge-club-38fe9d67ea8576cc101c56d1672ae0f4be947ce3.tar.bz2
perlweeklychallenge-club-38fe9d67ea8576cc101c56d1672ae0f4be947ce3.zip
Solution to task 2
Diffstat (limited to 'challenge-166')
-rwxr-xr-xchallenge-166/jo-37/perl/ch-2.pl68
1 files changed, 68 insertions, 0 deletions
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";
+ }
+}