Meanwhile I was writing Weekly Challenge #083 Task #2
...
> [X] (1,2,3).map( -> $n { $n, -$n } )
((1 2 3) (1 2 -3) (1 -2 3) (1 -2 -3) (-1 2 3) (-1 2 -3) (-1 -2 3) (-1 -2 -3))
And I'd like to mention that how powerful this is!!!
Yet Another Permutation Story
Or if you want to see a separate flipping data we could write like below
> (1,-1) X (1,-1) X (1,-1)
((1 1 1) (1 1 -1) (1 -1 1) (1 -1 -1) (-1 1 1) (-1 1 -1) (-1 -1 1) (-1 -1 -1)
OR
> [X] (1,-1) xx 3
((1 1 1) (1 1 -1) (1 -1 1) (1 -1 -1) (-1 1 1) (-1 1 -1) (-1 -1 1) (-1 -1 -1))
So, we want to make -12, 2, 10 from (-1,1,1), it could be done like..
> (12,2,10) Z* (-1,1,1)
(-12 2 10)
"[X]" is a magic! because if you want to write a subroutine does the similar task, it wasn't very happy as I introduced in Here before.
shell> cat p.raku
sub p ($len) {
if $len == 0 { () }
elsif $len == 1 { (1,-1) }
else { ((1,-1) X p($len.pred).List).map(*.flat.cache) }
}
p(3).say;
shell> raku p.raku
((1 1 1) (1 1 -1) (1 -1 1) (1 -1 -1) (-1 1 1) (-1 1 -1) (-1 -1 1) (-1 -1 -1))
If you are familiar with pattern matching in Haskell or multi method in other language previous p() can be written like this
multi sub p(0) { () }
multi sub p(1) { (1,-1) }
multi sub p ($len) {
(p(1) X p($len.pred).List).map(*.flat.cache)
}
p(3).say;
How about that? It's only preference problem but I can see that it will help you to make a code in manageable size 😄
And I'd like to mention that .cache and .List !!!
For saving your time, I'll summarise like below.
- when you are using a List or an Array returned from a subroutine and want to use on the fly, you'd better use .List; (because what you get is itemized value which is scalar. 📖) or save it into another List or another Array
- When you return any object in subroutine and you think it's going to be used in another Sequences, you'd better return as .cache!
otherwise you'll get something like this message
... snip ...
multi sub p ($len) {
(p(1) X p($len.pred).List).map(*.flat)
}
p(3).say;
The iterator of this Seq is already in use/consumed by another Seq
(you might solve this by adding .cache on usages of the Seq, or
by assigning the Seq into an array)
in block <unit> at test.raku line 7
Zip🤐
Now we have a series of sequences, we can get flipped values
We might be familiar with zip in other language and Raku as Z operator
shell> tail -n 5 p.raku
my @ex1 = (12, 2, 10);
p(3).map( -> \flipRule {
flipRule Z* @ex1
}
).say;
shell> raku p.raku
((12 2 10) (12 2 -10) (12 -2 10) (12 -2 -10) (-12 2 10) (-12 2 -10) (-12 -2 10) (-12 -2 -10))
Power of [X]
Now you can see how powerful [X] is !!!
> [X] (1,2,3).map( -> $n { $n, -$n } )
((1 2 3) (1 2 -3) (1 -2 3) (1 -2 -3) (-1 2 3) (-1 2 -3) (-1 -2 3) (-1 -2 -3))
Top comments (0)