aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarnesom <arne@bbop.org>2021-10-03 20:00:56 +0200
committerarnesom <arne@bbop.org>2021-10-03 20:00:56 +0200
commit198c191dc4ed56fef441e29e06466e21525f67ba (patch)
treee1808abbfaa514773bc832b30fda63c914c2dabe
parenta32879f89e56f3d1a63a2e3a5f3769d6976f58fc (diff)
downloadperlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.tar.gz
perlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.tar.bz2
perlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.zip
Arne Sommer
-rw-r--r--challenge-132/arne-sommer/blog.txt1
-rwxr-xr-xchallenge-132/arne-sommer/raku/ch-1.raku26
-rwxr-xr-xchallenge-132/arne-sommer/raku/ch-2.raku28
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join77
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join-module26
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join-module228
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join-module339
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join-module440
-rwxr-xr-xchallenge-132/arne-sommer/raku/hash-join-sorted72
-rw-r--r--challenge-132/arne-sommer/raku/lib/HashJoin.rakumod146
-rwxr-xr-xchallenge-132/arne-sommer/raku/mirror-dates26
11 files changed, 509 insertions, 0 deletions
diff --git a/challenge-132/arne-sommer/blog.txt b/challenge-132/arne-sommer/blog.txt
new file mode 100644
index 0000000000..91ef16738c
--- /dev/null
+++ b/challenge-132/arne-sommer/blog.txt
@@ -0,0 +1 @@
+https://raku-musings.com/mirrored-hash.html
diff --git a/challenge-132/arne-sommer/raku/ch-1.raku b/challenge-132/arne-sommer/raku/ch-1.raku
new file mode 100755
index 0000000000..1867da0bb3
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/ch-1.raku
@@ -0,0 +1,26 @@
+#! /usr/bin/env raku
+
+subset SlashDate where * ~~ /^\d\d\d\d\/\d\d\/\d\d$/;
+
+my $fmt = { sprintf "%04d/%02d/%02d", .year, .month, .day };
+
+unit sub MAIN (SlashDate $date = "2021/09/18",
+ SlashDate :$today = Date.new(DateTime.now, formatter => $fmt).Str,
+ :v($verbose));
+
+my $date-iso = $date.subst("/", "-", :g);
+
+my $earlier = Date.new($date-iso, formatter => $fmt);
+my $now = Date.new($today.subst("/", "-", :g), formatter => $fmt);
+
+die "The date ($earlier) should be earlier than today ($now)" unless $earlier < $now;
+
+my $diff = $now - $earlier;
+
+say ": Today: $now" if $verbose;
+say ": Difference: $diff days" if $verbose;
+
+my $first = $earlier.earlier(day => $diff);
+my $last = $now.later( day => $diff);
+
+say "$first, $last";
diff --git a/challenge-132/arne-sommer/raku/ch-2.raku b/challenge-132/arne-sommer/raku/ch-2.raku
new file mode 100755
index 0000000000..6f0e2607d9
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/ch-2.raku
@@ -0,0 +1,28 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use HashJoin;
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex" ],
+ [28, "Joe" ],
+ [38, "Mike" ],
+ [18, "Alex" ],
+ [25, "David" ],
+ [18, "Simon" ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart"],
+ ["Joe", "Root" ],
+ ["Mike", "Gatting"],
+ ["Joe", "Blog" ],
+ ["Alex", "Jones" ],
+ ["Simon","Duane" ],
+);
+
+my @joined = HashJoin::merge(@player_ages, 1, @player_names, 0, :$verbose);
+
+HashJoin::print-it(@joined);
diff --git a/challenge-132/arne-sommer/raku/hash-join b/challenge-132/arne-sommer/raku/hash-join
new file mode 100755
index 0000000000..493a6182eb
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join
@@ -0,0 +1,77 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex" ],
+ [28, "Joe" ],
+ [38, "Mike" ],
+ [18, "Alex" ],
+ [25, "David" ],
+ [18, "Simon" ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart"],
+ ["Joe", "Root" ],
+ ["Mike", "Gatting"],
+ ["Joe", "Blog" ],
+ ["Alex", "Jones" ],
+ ["Simon","Duane" ],
+);
+
+hash-join(@player_ages, 1, @player_names, 0);
+
+sub hash-join (@table1 is copy, $index1 is copy, @table2 is copy, $index2 is copy)
+{
+ if @table1.elems > @table2.elems
+ {
+ (@table1, @table2) = (@table2, @table1);
+ ($index1, $index2) = ($index2, $index1);
+ }
+
+ my %table1;
+
+ for @table1 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index1, 1);
+
+ say ": Table 1 Row (add): $id -> { @data.join(", ") }" if $verbose;
+ %table1{$id}.push: @data;
+ }
+
+ my %result;
+
+ for @table2 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index2, 1);
+ if $verbose
+ {
+ say ": Table 1 Row (scan): $id -> { @(%table1{$id}).join(", ") }";
+ say ": Table 2 Row (scan): $id -> { @data.join(", ") }";
+ }
+
+ for @(%table1{$id}) -> $row
+ {
+ %result{$id}.push: (@$row, @data).flat;
+ say ": Result Table Row: $id -> { @$row.join(", ") } + { @data.join(", ") }" if $verbose;
+ }
+ }
+
+ for %result.keys.sort -> $id
+ {
+ my @rows = @(%result{$id});
+
+ for @rows -> $row
+ {
+ say nicify(|($id, @$row));
+ }
+ }
+}
+
+sub nicify (*@data)
+{
+ return @data.map({ $_ ~~ Numeric ?? $_ !! '"' ~ $_ ~ '"' }).join(", ");
+}
diff --git a/challenge-132/arne-sommer/raku/hash-join-module b/challenge-132/arne-sommer/raku/hash-join-module
new file mode 100755
index 0000000000..c0330df3a9
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join-module
@@ -0,0 +1,26 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use HashJoin;
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex" ],
+ [28, "Joe" ],
+ [38, "Mike" ],
+ [18, "Alex" ],
+ [25, "David" ],
+ [18, "Simon" ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart"],
+ ["Joe", "Root" ],
+ ["Mike", "Gatting"],
+ ["Joe", "Blog" ],
+ ["Alex", "Jones" ],
+ ["Simon","Duane" ],
+);
+
+HashJoin::hash-join-sorted(@player_ages, 1, @player_names, 0, :$verbose);
diff --git a/challenge-132/arne-sommer/raku/hash-join-module2 b/challenge-132/arne-sommer/raku/hash-join-module2
new file mode 100755
index 0000000000..6f0e2607d9
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join-module2
@@ -0,0 +1,28 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use HashJoin;
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex" ],
+ [28, "Joe" ],
+ [38, "Mike" ],
+ [18, "Alex" ],
+ [25, "David" ],
+ [18, "Simon" ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart"],
+ ["Joe", "Root" ],
+ ["Mike", "Gatting"],
+ ["Joe", "Blog" ],
+ ["Alex", "Jones" ],
+ ["Simon","Duane" ],
+);
+
+my @joined = HashJoin::merge(@player_ages, 1, @player_names, 0, :$verbose);
+
+HashJoin::print-it(@joined);
diff --git a/challenge-132/arne-sommer/raku/hash-join-module3 b/challenge-132/arne-sommer/raku/hash-join-module3
new file mode 100755
index 0000000000..14293dda61
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join-module3
@@ -0,0 +1,39 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use HashJoin;
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex", "May", 29 ],
+ [28, "Joe", "August", 2 ],
+ [38, "Mike", "June", 12 ],
+ [18, "Alex", "January", 29 ],
+ [25, "David", "March", 14 ],
+ [18, "Simon", "June", 10 ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart", "Oslo" ],
+ ["Joe", "Root", "Berlin" ],
+ ["Mike", "Gatting", "London" ],
+ ["Joe", "Blog", "Bern" ],
+ ["Alex", "Jones", "Zürich" ],
+ ["Simon","Duane", "Oxford" ],
+);
+
+my @countries = (
+ ["Norway", "Oslo" ],
+ ["Germany", "Berlin" ],
+ ["England", "London" ],
+ ["Switzerland", "Bern" ],
+ ["Switzerland", "Zürich" ],
+ ["England", "Oxford" ],
+);
+
+my @joined = HashJoin::merge(@player_ages, 1, @player_names, 0, :$verbose);
+
+my @joined2 = HashJoin::merge(@joined, 5, @countries, 1);
+
+HashJoin::print-it(@joined2);
diff --git a/challenge-132/arne-sommer/raku/hash-join-module4 b/challenge-132/arne-sommer/raku/hash-join-module4
new file mode 100755
index 0000000000..c13dba2d33
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join-module4
@@ -0,0 +1,40 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use HashJoin;
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex", "May", 29 ],
+ [28, "Joe", "August", 2 ],
+ [38, "Mike", "June", 12 ],
+ [18, "Alex", "January", 29 ],
+ [25, "David", "March", 14 ],
+ [18, "Simon", "June", 10 ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart", "Oslo" ],
+ ["Joe", "Root", "Berlin" ],
+ ["Mike", "Gatting", "London" ],
+ ["Joe", "Blog", "Bern" ],
+ ["Alex", "Jones", "Zürich" ],
+ ["Simon","Duane", "Birmingham" ],
+);
+
+my @countries = (
+ ["Norway", "Oslo" ],
+ ["Germany", "Berlin" ],
+ ["England", "London" ],
+ ["Switzerland", "Bern" ],
+ ["Switzerland", "Zürich" ],
+ ["England", "Birmingham" ],
+ ["USA", "Birmingham" ],
+);
+
+my @joined = HashJoin::merge(@player_ages, 1, @player_names, 0, :$verbose);
+
+my @joined2 = HashJoin::merge(@joined, 5, @countries, 1);
+
+HashJoin::print-it(@joined2);
diff --git a/challenge-132/arne-sommer/raku/hash-join-sorted b/challenge-132/arne-sommer/raku/hash-join-sorted
new file mode 100755
index 0000000000..b94bfa0555
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/hash-join-sorted
@@ -0,0 +1,72 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (:v(:$verbose));
+
+my @player_ages = (
+ [20, "Alex" ],
+ [28, "Joe" ],
+ [38, "Mike" ],
+ [18, "Alex" ],
+ [25, "David" ],
+ [18, "Simon" ],
+);
+
+my @player_names = (
+ ["Alex", "Stewart"],
+ ["Joe", "Root" ],
+ ["Mike", "Gatting"],
+ ["Joe", "Blog" ],
+ ["Alex", "Jones" ],
+ ["Simon","Duane" ],
+);
+
+hash-join-sorted(@player_ages, 1, @player_names, 0);
+
+sub hash-join-sorted (@table1, $index1, @table2, $index2)
+{
+ my %table1;
+
+ for @table1 -> $row
+ {
+ my @data = @$row;
+ my $id = @data[$index1];
+
+ say ": Table 1 Row (add): $id -> { @data.join(", ") }" if $verbose;
+ %table1{$id}.push: @data;
+ }
+
+ my %result;
+
+ for @table2 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index2, 1);
+
+ if $verbose
+ {
+ say ": Table 1 Row (scan): $id -> { @(%table1{$id}).join(", ") }";
+ say ": Table 2 Row (scan): $id -> { @data.join(", ") }";
+ }
+
+ for @(%table1{$id}) -> $row
+ {
+ %result{$id}.push: (@$row, @data).flat;
+ say ": Result Table Row: $id -> { @$row.join(", ") } + { @data.join(", ") }" if $verbose;
+ }
+ }
+
+ for %result.keys.sort -> $id
+ {
+ my @rows = @(%result{$id});
+
+ for @rows -> $row
+ {
+ say nicify(@$row);
+ }
+ }
+}
+
+sub nicify (*@data)
+{
+ return @data.map({ $_ ~~ Numeric ?? $_ !! '"' ~ $_ ~ '"' }).join(", ");
+}
diff --git a/challenge-132/arne-sommer/raku/lib/HashJoin.rakumod b/challenge-132/arne-sommer/raku/lib/HashJoin.rakumod
new file mode 100644
index 0000000000..05705b8f5a
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/lib/HashJoin.rakumod
@@ -0,0 +1,146 @@
+unit module HashJoin;
+
+our sub merge (@table1, $index1, @table2, $index2, :$verbose)
+{
+ my %table1;
+ my @ids;
+ my %ids;
+ my %result;
+
+ for @table1 -> $row1
+ {
+ my @data1 = @$row1;
+ my $id1 = @data1[$index1];
+ @ids.push: $id1 unless any(@ids) eq $id1;
+
+ say ": Table 1 Row (scan): $id1 -> { @data1.join(", ") }" if $verbose;
+
+ for @table2 -> $row2
+ {
+ my @data2 = @$row2;
+ my $id2 = @data2.splice($index2, 1);
+ next unless $id1 eq $id2;
+
+ %ids{$id2} = True;
+ %result{$id1}.push: (@data1, @data2).flat;
+
+ say ": Result Table Row: $id1 -> { @data1.join(", ") } + { @data2.join(", ") }" if $verbose;
+ }
+ }
+
+ my @result;
+
+ for @ids -> $id
+ {
+ next unless %ids{$id};
+ @result.append: @(%result{$id});
+ }
+
+ return @result;
+}
+
+our sub hash-join-sorted (@table1, $index1, @table2, $index2, :$verbose)
+{
+ my %table1;
+
+ for @table1 -> $row
+ {
+ my @data = @$row;
+ my $id = @data[$index1];
+
+ say ": Table 1 Row (add): $id -> { @data.join(", ") }" if $verbose;
+ %table1{$id}.push: @data;
+ }
+
+ my %result;
+
+ for @table2 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index2, 1);
+
+ if $verbose
+ {
+ say ": Table 1 Row (scan): $id -> { @(%table1{$id}).join(", ") }";
+ say ": Table 2 Row (scan): $id -> { @data.join(", ") }";
+ }
+
+ for @(%table1{$id}) -> $row
+ {
+ %result{$id}.push: (@$row, @data).flat;
+ say ": Result Table Row: $id -> { @$row.join(", ") } + { @data.join(", ") }" if $verbose;
+ }
+ }
+
+ for %result.keys.sort -> $id
+ {
+ my @rows = @(%result{$id});
+
+ for @rows -> $row
+ {
+ say nicify(@$row);
+ }
+ }
+}
+
+our sub hash-join (@table1 is copy, $index1 is copy, @table2 is copy, $index2 is copy, :$verbose)
+{
+ if @table1.elems > @table2.elems
+ {
+ (@table1, @table2) = (@table2, @table1);
+ ($index1, $index2) = ($index2, $index1);
+ }
+
+ my %table1;
+
+ for @table1 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index1, 1);
+
+ say ": Table 1 Row (add): $id -> { @data.join(", ") }" if $verbose;
+ %table1{$id}.push: @data;
+ }
+
+ my %result;
+
+ for @table2 -> $row
+ {
+ my @data = @$row;
+ my $id = @data.splice($index2, 1);
+ if $verbose
+ {
+ say ": Table 1 Row (scan): $id -> { @(%table1{$id}).join(", ") }";
+ say ": Table 2 Row (scan): $id -> { @data.join(", ") }";
+ }
+
+ for @(%table1{$id}) -> $row
+ {
+ %result{$id}.push: (@$row, @data).flat;
+ say ": Result Table Row: $id -> { @$row.join(", ") } + { @data.join(", ") }" if $verbose;
+ }
+ }
+
+ for %result.keys.sort -> $id
+ {
+ my @rows = @(%result{$id});
+
+ for @rows -> $row
+ {
+ say nicify(|($id, @$row));
+ }
+ }
+}
+
+sub nicify (*@data)
+{
+ return @data.map({ $_ ~~ Numeric ?? $_ !! '"' ~ $_ ~ '"' }).join(", ");
+}
+
+our sub print-it(*@data)
+{
+ for @data -> $row
+ {
+ say nicify(@$row);
+ }
+}
diff --git a/challenge-132/arne-sommer/raku/mirror-dates b/challenge-132/arne-sommer/raku/mirror-dates
new file mode 100755
index 0000000000..1867da0bb3
--- /dev/null
+++ b/challenge-132/arne-sommer/raku/mirror-dates
@@ -0,0 +1,26 @@
+#! /usr/bin/env raku
+
+subset SlashDate where * ~~ /^\d\d\d\d\/\d\d\/\d\d$/;
+
+my $fmt = { sprintf "%04d/%02d/%02d", .year, .month, .day };
+
+unit sub MAIN (SlashDate $date = "2021/09/18",
+ SlashDate :$today = Date.new(DateTime.now, formatter => $fmt).Str,
+ :v($verbose));
+
+my $date-iso = $date.subst("/", "-", :g);
+
+my $earlier = Date.new($date-iso, formatter => $fmt);
+my $now = Date.new($today.subst("/", "-", :g), formatter => $fmt);
+
+die "The date ($earlier) should be earlier than today ($now)" unless $earlier < $now;
+
+my $diff = $now - $earlier;
+
+say ": Today: $now" if $verbose;
+say ": Difference: $diff days" if $verbose;
+
+my $first = $earlier.earlier(day => $diff);
+my $last = $now.later( day => $diff);
+
+say "$first, $last";