Reducing sets
This week´s PWC asks us for hexadecimal words and distinctly different directories.
sub term:<pwc-166-1> {
sub less-substitutions-then ($_, $n) {
.subst(/<-[olist]>/, :g, '').chars < $n
}
'/usr/share/dict/words'.IO.words.race\
.grep({.chars ≤ 8 && .&less-substitutions-then(4)})\
.map(*.trans(<o l i s t> => <0 1 1 5 7>))\
.grep(/^ <[0..9 a..f A..F]>+ $/)\
.sort(-*.chars)\
.say;
};
Once again, we write the algorithm down. Get the words, drop anything longer then 8 chars or what would need more then 4 substitutions. Then do the substitutions and grep anything that looks like a hexadecimal numeral. Sort for good measure and output the first 100 elements.
The second task provides us with a little challenge. We need to mock listing directories and working with them. Since dir
returns a sequence of IO::Path
I can create those by hand and mixin a role that mimics some filesystem operations. I can overload dir
to provide a drop-in replacement.
sub term:<pwc-166-2> {
sub basename(IO::Path $_) { .basename ~ (.d ?? '/' !! '') }
sub pad(Str $_, $width, $padding = ' ') { .Str ~ $padding x ($width - .chars) }
sub dir(Str $name) {
sub mock-file(*@names) { @names.map({ IO::Path.new($_) but role :: { method f ( --> True ) {}; method e ( --> True ) {} } } ) }
sub mock-dir(*@names) { @names.map({ IO::Path.new($_) but role :: { method d ( --> True ) {}; method e ( --> True) {} } }) }
constant %dirs = dir_a => flat(mock-file(<Arial.ttf Comic_Sans.ttf Georgia.ttf Helvetica.ttf Impact.otf Verdana.ttf>), mock-dir(<Old_Fonts>)),
dir_b => mock-file(<Arial.ttf Comic_Sans.ttf Courier_New.ttf Helvetica.ttf Impact.otf Tahoma.ttf Verdana.ttf>),
dir_c => mock-file(<Arial.ttf Courier_New.ttf Helvetica.ttf Impact.otf Monaco.ttf Verdana.ttf>);
%dirs{$name}
}
sub dir-diff(+@dirs) {
my @content = @dirs».&dir».&basename;
my @relevant = (([∪] @content) ∖ [∩] @content).keys.sort;
my @columns = @content.map(-> @col { @relevant.map({ $_ ∈ @col ?? $_ !! '' }) });
my $col-width = [max] @columns[*;*]».chars;
put @dirs».&pad($col-width).join(' | ');
put (''.&pad($col-width, '-') xx 3).join('-+-');
.put for ([Z] @columns)».&pad($col-width)».join(' | ');
}
dir-diff(<dir_a dir_b dir_c>);
};
I’m asked to add a /
to directories and do so with a custom basename
. The rest is liberal application of set theory. Only names that don’t show up in all directories are relevant. Columns are created by matching the content of each directory against the relevant names. The width of columns is the longest string. The header is put on screen. To output the columns line by line, x and y are flipped with [Z]
.
After careful study of the solutions written in other languages, I believe it is fair to call Raku an eco-friendly language. Our keyboards are going to last at least twice a long.
-
May 30, 2022 at 14:462022.22 Complete Timeline – Rakudo Weekly News