diff options
| -rw-r--r-- | challenge-269/bruce-gray/raku/ch-1.raku | 27 | ||||
| -rw-r--r-- | challenge-269/bruce-gray/raku/ch-2.raku | 101 |
2 files changed, 128 insertions, 0 deletions
diff --git a/challenge-269/bruce-gray/raku/ch-1.raku b/challenge-269/bruce-gray/raku/ch-1.raku new file mode 100644 index 0000000000..67f6c12277 --- /dev/null +++ b/challenge-269/bruce-gray/raku/ch-1.raku @@ -0,0 +1,27 @@ +sub task1_combinations_bit-twiddling ( @ns --> Bool ) { + return so @ns.grep(* != 0).combinations(2).map({ [+|] .list }).any +& 1 == 0; +} + +# The task can be reduced to: are there at least two even numbers. +sub task1_reduced_count { @^ns.grep( * %% 2 ) >= 2 } # Concise +sub task1_reduced_head { @^ns.grep( * %% 2 ).head(2) == 2 } # Conceptually faster. + + +constant @subs = + :&task1_combinations_bit-twiddling, + :&task1_reduced_count, + :&task1_reduced_head, +; +constant @tests = + ( True , ( 1, 2, 3, 4, 5 ) ), + ( True , ( 2, 3, 8, 16 ) ), + ( False , ( 1, 2, 5, 7, 9 ) ), + + # ( False , ( 0, 0 ) ), # On 2nd read, this is disallowed by the task description. +; +use Test; plan +@subs * +@tests; +for @subs -> ( :key($sub_name), :value(&task1) ) { + for @tests -> ( $expected, @in ) { + is task1(@in), $expected, "$sub_name : @in[]"; + } +}
\ No newline at end of file diff --git a/challenge-269/bruce-gray/raku/ch-2.raku b/challenge-269/bruce-gray/raku/ch-2.raku new file mode 100644 index 0000000000..c118837ff6 --- /dev/null +++ b/challenge-269/bruce-gray/raku/ch-2.raku @@ -0,0 +1,101 @@ +sub task2_basic ( @ns ) { + my ( $a, $b, @rest ) = @ns; + my @arr1 = $a; + my @arr2 = $b; + + # ( @arr1.tail > @arr2.tail ?? @arr1 !! @arr2 ).push($_) for @rest; + for @rest -> $n { + if @arr1.tail > @arr2.tail { push @arr1, $n } + else { push @arr2, $n } + } + + return flat( @arr1, @arr2 ); +} +sub task2_single_r_array ( @ns ) { + my @r = [ @ns[0] ], [ @ns[1] ]; + + for @ns.skip(2) -> $n { + # @r[ (0,1).max({ @r[$_].tail }) ].push: $n; + @r.max(+*.tail).push: $n; + } + + return @r».<>.flat; +} +sub task2_binding ( [ $a, $b, *@rest ] ) { + my @arr1 = $a; + my @arr2 = $b; + + # ( @arr1, @arr2 ).max( *.tail ).push($_) for @rest; + + for @rest -> $n { + my @target_array := ( @arr1, @arr2 ).max( *.tail ); + @target_array.push: $n; + } + + return flat( @arr1, @arr2 ); +} +sub task2_live_capture ( [ $a, $b, *@rest ] ) { + my @arr1 = $a; + my @arr2 = $b; + + my @as = ( @arr1, @arr2 ); + + for @rest -> $n { + push @as.max( *.tail ), $n; + } + + return flat( @arr1, @arr2 ); +} +sub task2_three_pointers ( @ns is copy ) { + my ( $i1, $i2, $i ) = 0, 1, 2; # Wait, $i will always be $i2 + 1, so I will simplify it in the next sub. + + while $i <= @ns.end { + # say @ns, ( $i1, $i2, $i ); + if @ns[$i1] > @ns[$i2] { + my $t = @ns.splice($i, 1); + @ns.splice($i1+1, 0, $t); + $i1++; + $i2++; + $i++; + } + else { + $i2++; + $i++; + } + } + + return @ns.List; +} +sub task2_one_pointer ( @ns is copy ) { + my $i1 = 0; # $i1 and $i2 divide @ns into three segments + + for @ns.keys.skip(1) -> $i2 { + if @ns[$i1] > @ns[$i2] { + @ns.splice( $i1+1, 0, @ns.splice($i2+1, 1) ); + $i1++; + } + } + + return @ns.List; +} + + +constant @subs = + :&task2_basic, + :&task2_single_r_array, + :&task2_binding, + :&task2_live_capture, + :&task2_three_pointers, + :&task2_one_pointer, +; +constant @tests = + ( ( 2, 1, 3, 4, 5 ) , ( 2, 3, 4, 5, 1 ) ), + ( ( 3, 2, 4 ) , ( 3, 4, 2 ) ), + ( ( 5, 4, 3, 8 ) , ( 5, 3, 4, 8 ) ), +; +use Test; plan +@subs * +@tests; +for @subs -> ( :key($sub_name), :value(&task2) ) { + for @tests -> ( @in, @expected ) { + is-deeply task2(@in), @expected, "$sub_name : @in[]"; + } +} |
