This is my third week participating into the weekly challenge.



Again apologies for not having the syntax highlighter on some of the solutions as the > symbols become & gt; and ruins the solution.





Easy Challenge

“Count Letters (A..Z)

Create a script that accepts one or more files specified on the command-line and count the number of times letters appeared in the files.”

Example files

The quick brown fox jumps over the lazy dog.

καλησπέρα

I used getc to grab the character from the file handle and store the character count in a hash. I used the \w (word character) for regex matching to make sure we grabbed some of the UTF-8 chars.



Then format print the letter and the count.



Perl 5 solution

#!/usr/bin/perl # Test: ./ch1.pl example1.txt example2.txt use strict; use warnings; binmode STDOUT, ':utf8'; my %counts; # Loop through each file for my $file (@ARGV) { open my $fh, "<:encoding(UTF-8)", $file or die "$file: $!

"; # Increment count for each word char while (my $char = getc($fh)) { $counts{lc($char)}++ if (lc($char) =~ /[\w]/); } } # Print each char and count for my $char (sort keys %counts) { printf("%2s %5i

", $char, $counts{$char}); }

Output

a 1 b 1 c 1 d 1 e 3 f 1 g 1 h 2 i 1 j 1 k 1 l 1 m 1 n 1 o 4 p 1 q 1 r 2 s 1 t 2 u 2 v 1 w 1 x 1 y 1 z 1 έ 1 α 2 η 1 κ 1 λ 1 π 1 ρ 1 σ 1

Raku solution

# Test: perl6 ch1.p6 example1.txt example2.txt use v6.d; sub MAIN (*@filenames) { my %counts; # Loop through each file for @filenames -> $filename { my $fh = $filename.IO.open orelse .die; # Increment count for each word char while (my $char = $fh.getc) { %counts{$char.lc}++ if ($char.lc ~~ /\w/); } } # Print each char and count for %counts.keys.sort -> $item { "%2s %5i

".printf($item, %counts{$item}); } }

Output

a 1 b 1 c 1 d 1 e 3 f 1 g 1 h 2 i 1 j 1 k 1 l 1 m 1 n 1 o 4 p 1 q 1 r 2 s 1 t 2 u 2 v 1 w 1 x 1 y 1 z 1 έ 1 α 2 η 1 κ 1 λ 1 π 1 ρ 1 σ 1

Hard Challenge

“Formatted Multiplication Table

Write a script to print 11×11 multiplication table, only the top half triangle.”

I had a lot of fun doing this one, something quite satisfying about ascii tables. So just using prinft to format the table nicely and some for loops to populate it.



For my raku solution i decided to play around with multi method. There are probably better ways of doing this, but I’m using the challenges to learn something new about raku every week.

Perl 5 solution

#!/usr/bin/perl # Test: ./ch2.pl use strict; use warnings; generate_x_table(11); # Generates the multiplication table sub generate_x_table { my $num = shift; for my $i (0..$num) { my $line = ($i == 0) ? _table_head($num) : _table_body($i, $num); print $line; } } # Returns the table head string sub _table_head { my $num = shift; my $line = sprintf ("%4s|", 'x'); for my $i (1..$num) { $line .= sprintf("%4i", $i); } return $line . "

" . '----+' . '----' x $num . "

"; } # Returns the table row string for $i sub _table_body { my ($current, $num) = @_; my $line = sprintf ("%4i|", $current); for my $i (1..$num) { $line .= ($current <= $i) ? sprintf("%4i", $i * $current) : ' ' x 4; } $line .= "

"; return $line; }

Output

x| 1 2 3 4 5 6 7 8 9 10 11 ----+-------------------------------------------- 1| 1 2 3 4 5 6 7 8 9 10 11 2| 4 6 8 10 12 14 16 18 20 22 3| 9 12 15 18 21 24 27 30 33 4| 16 20 24 28 32 36 40 44 5| 25 30 35 40 45 50 55 6| 36 42 48 54 60 66 7| 49 56 63 70 77 8| 64 72 80 88 9| 81 90 99 10| 100 110 11| 121

Raku solution

# Test: perl6 ch2.p6 use v6.d; sub MAIN () { generate-x-table(11); } # Generates the multiplication table sub generate-x-table (Int $num) { table-content($_, $num).say for (0..$num); } # Returns the table head string multi table-content(Int $current where { $current == 0}, Int $num) { my $line = "%4s|".sprintf("x"); $line ~= "%4i".sprintf($_) for (1..$num); return $line ~ "

" ~ '----+' ~ '----' x $num; } # Returns the table row string for $i multi table-content(Int $current, Int $num) { my $line = "%4i|".sprintf($current); for (1..$num) -> $i { $line ~= ($current <= $i) ?? "%4i".sprintf($i * $current) !! ' ' x 4; } return $line; }

Output

x| 1 2 3 4 5 6 7 8 9 10 11 ----+-------------------------------------------- 1| 1 2 3 4 5 6 7 8 9 10 11 2| 4 6 8 10 12 14 16 18 20 22 3| 9 12 15 18 21 24 27 30 33 4| 16 20 24 28 32 36 40 44 5| 25 30 35 40 45 50 55 6| 36 42 48 54 60 66 7| 49 56 63 70 77 8| 64 72 80 88 9| 81 90 99 10| 100 110 11| 121