diff options
| author | holli-holzer <holli.holzer@gmail.com> | 2019-09-17 20:35:45 +0200 |
|---|---|---|
| committer | holli-holzer <holli.holzer@gmail.com> | 2019-09-17 20:35:45 +0200 |
| commit | 79c26caafa0533b8a500825357fdfdac40100c6e (patch) | |
| tree | 3a2b2e75e368c25a679efd6697b75398a42bc06b | |
| parent | ecc3de5bb7bd780c1300ae1d3fba5379a5f82a7b (diff) | |
| download | perlweeklychallenge-club-79c26caafa0533b8a500825357fdfdac40100c6e.tar.gz perlweeklychallenge-club-79c26caafa0533b8a500825357fdfdac40100c6e.tar.bz2 perlweeklychallenge-club-79c26caafa0533b8a500825357fdfdac40100c6e.zip | |
Revised the code to make it leaner. Added comments.
| -rw-r--r-- | challenge-026/markus-holzer/perl6/ch-1.p6 | 30 | ||||
| -rw-r--r-- | challenge-026/markus-holzer/perl6/ch-2.p6 | 41 |
2 files changed, 40 insertions, 31 deletions
diff --git a/challenge-026/markus-holzer/perl6/ch-1.p6 b/challenge-026/markus-holzer/perl6/ch-1.p6 index cd39fe4cb7..85f29cab2c 100644 --- a/challenge-026/markus-holzer/perl6/ch-1.p6 +++ b/challenge-026/markus-holzer/perl6/ch-1.p6 @@ -1,21 +1,31 @@ -use v6; use Test; -multi sub infix:<+∩>( $stones, $jewels ) +# In Raku, all operators are just multi - functions. +# So we can easily define ourselves an infix left-associative element-of operator. +# It will take an `Iterable` (`Seq`, `Array`, `List`) on its left side and a `Set` on the right side. +# It returns a `Seq` of all elements of the left side that are present on the right side. + +multi sub infix:<\<∈>( Iterable $stones, Set $jewels ) returns Seq { - $stones.Str +∩ $jewels.Str + $stones.grep: * ∈ $jewels } -multi sub infix:<+∩>( Str $stones, Str $jewels ) +# Now we could call that good, but in true Raku spirit we provide additional +# versions of our operator to make using it easier. +# We don't need to repeat ourselves. We can rely on the multi-mechanism +# to do the right thing. + +multi sub infix:<\<∈>( Iterable $stones, Iterable $jewels ) returns Seq { - $stones.split( '', :skip-empty ) +∩ $jewels.split( '', :skip-empty ).Set + $stones <∈ $jewels.Set } -multi sub infix:<+∩>( Iterable $stones, Set $jewels ) +multi sub infix:<\<∈>( Str $stones, Str $jewels ) returns Str { - $stones.grep({ $_ ∈ $jewels }) + ( $stones.split( '', :skip-empty ) <∈ $jewels.split( '', :skip-empty ) ).join("") } -ok( ( "chancellor" +∩ "chocolates" ).elems == 8 ); -ok( ( "chocolatiers" +∩ "chancellor" ).elems == 9 ); -ok( ( "bottle" +∩ "beer" ).elems == 2 ); +# And here we finally use it to solve the problem +ok( ( ["b", "e", "e", "r"] <∈ ["b", "o", "t", "t", "l", "e"] ).elems == 3, "3 characters of 'beer' are also in 'bottle'" ); +ok( ( "chancellor" <∈ "chocolates" ).chars == 8, "8 characters of 'chancellor' are also in 'chocolates'" ); +ok( "chancellor" <∈ "chocolates" eq "chacello", "These characters are 'chacello'" ); diff --git a/challenge-026/markus-holzer/perl6/ch-2.p6 b/challenge-026/markus-holzer/perl6/ch-2.p6 index 0fc41be74d..2273b4f199 100644 --- a/challenge-026/markus-holzer/perl6/ch-2.p6 +++ b/challenge-026/markus-holzer/perl6/ch-2.p6 @@ -1,26 +1,25 @@ -use v6; -use Test; +# Rakus trigonometry functions operate on radians. So we must convert degrees to radians. +# That's simple enough using a new postfix operator and high school math. +multi sub postfix:<°>( Numeric $degrees ) returns Real { $degrees * π / 180 } -sub radians( $degrees ) +# This implements the "simple" version of the algorithm as described on Wikipedia. +# There already is an implementation of the complex math version (that uses `i`) +# on Rosetta-Code https://rosettacode.org/wiki/Averages/Mean_angle#Perl_6 +sub mean-angle( *@α ) returns Real { - $degrees * π / 180 -} - -sub degrees( $radians ) -{ - $radians * 180 / π -} - -sub mean-angle( *@angles ) -{ - my $inv = 1 / @angles.elems; + # Neiter inv, nor ρ will ever change, so we can define them as immutable + my \inv = 1 / @α.elems; + my \ρ = atan2( + (inv * [+] @α>>.sin), # calculate the sine of all angles, sum the result and multiply that with the factor + (inv * [+] @α>>.cos) # same, but with cosine + ); - degrees( atan2( - $inv * [+] @angles.map({ radians( $_ ).sin }), - $inv * [+] @angles.map({ radians( $_ ).cos }) - )); + ρ > 0 + ?? ρ # We always want positive values + !! ρ + 2 * π # When it isn't, we add 360° } -ok( mean-angle( 10, 10, 10 ) =~= 10 ); -ok( mean-angle( 10, 20, 30 ) =~= 20 ); -ok( mean-angle( 355, 5, 15 ) =~= 5 ); +ok( mean-angle( 10°, 10°, 10° ) =~= 10°, "The mean of 3 times alpha is alpha" ); +ok( mean-angle( 10°, 20°, 30° ) =~= 20°, "All angles in one quadrant" ); +ok( mean-angle( 355°, 5°, 15° ) =~= 5°, "Angles in multiple quadrants" ); +ok( mean-angle( 90°, 180°, 270°, 360° ) =~= 270°, "Angle is not negative" ); |
