diff options
| author | arnesom <arne@bbop.org> | 2021-10-03 20:00:56 +0200 |
|---|---|---|
| committer | arnesom <arne@bbop.org> | 2021-10-03 20:00:56 +0200 |
| commit | 198c191dc4ed56fef441e29e06466e21525f67ba (patch) | |
| tree | e1808abbfaa514773bc832b30fda63c914c2dabe | |
| parent | a32879f89e56f3d1a63a2e3a5f3769d6976f58fc (diff) | |
| download | perlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.tar.gz perlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.tar.bz2 perlweeklychallenge-club-198c191dc4ed56fef441e29e06466e21525f67ba.zip | |
Arne Sommer
| -rw-r--r-- | challenge-132/arne-sommer/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/ch-1.raku | 26 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/ch-2.raku | 28 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join | 77 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join-module | 26 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join-module2 | 28 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join-module3 | 39 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join-module4 | 40 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/hash-join-sorted | 72 | ||||
| -rw-r--r-- | challenge-132/arne-sommer/raku/lib/HashJoin.rakumod | 146 | ||||
| -rwxr-xr-x | challenge-132/arne-sommer/raku/mirror-dates | 26 |
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"; |
