NOTE: 30 minutes from now is the start of the Raku Study Group of the San Francisco Perl Mongers.
We can offer a "deep dive" into how the Leyland code works, if that would be helpful.
Zoom details here: https://mail.pm.org/pipermail/sanfrancisco-pm/2020-October/004726.htmlOn Oct 11, 2020, at 10:39 AM, Cezmi Pastirma <cezmisi...@yandex.com> wrote:
I've got a question about a Leyland-numbers-listing Raku code which I saw at codegolf.stackexchange.com at https://codegolf.stackexchange.com/a/83013/98132
I've slightly rearranged the code to make it print Leyland numbers up to 1 Billion:
.say for grep {$_ < 1E11}, squish(sort [X[&({$^a**$^b+$b**$a})]] 2..32,2..32)
The question in short is:
How does the cross reduce work there?
The reduction is a red herring to our understanding here.
Note that, when you are only [reducing] on two lists, `[any_op_here] @a, @b` is the same as `@a any_op_here @b`.
These are equivalent:
say [X+] 2..4, 1..5;
say 2..4 X+ 1..5;
The operator need not be a meta-operator:
say [*] 3, 5;
say 3 * 5;Extra info:
That cross reduce section surely does what this half-pseudo code tries to do:
map { $^a ** $^b + $b ** $a }, 2..32,32…2
If @c has 20 elements, and @d has 30 elements, then `@c X+ @d` has 600 elements.
You cannot produce the equivalent with a simple `map`.
(You could with a flattened map-within-a-map)
Simplifying your "slightly rearranged” code:
.say for grep {$_ < 1E11}, squish(sort [X[&({$^a**$^b+$b**$a})]] 2..32,2..32)
...to just the part you are curious about, we get:
say [X[&({$^a**$^b+$b**$a})]] 2..4,2..4;
(8 17 32 17 54 145 32 145 512)
We are only [reducing] on two lists, so we can remove the reduction, and just use the Xop:
say 2..4 X[&({$^a**$^b+$b**$a})] 2..4;
(8 17 32 17 54 145 32 145 512)The tricky part here is the use of reduce operators two times in a row, once before the cross operator, once before the & operator, which I guess donates a closure. How to interpret this usage of operators?
--
The square brackets after the X, I think you mis-took as a second reduction.
Those brackets are just there to disambiguate the `op` that the `X` is crossing on.
See: https://docs.raku.org/language/operators#Nesting_of_metaoperators
These are equivalent:
.say for ^2 X+ ^2;
.say for ^2 X[+] ^2;
We can create our own operator, to further separate the Cross from the Op:
multi infix:<⨁> ($a, $b) {
$a ** $b
+ $b ** $a
};
say 2 ⨁ 3;
say 2..4 X⨁ 2..4;
17
(8 17 32 17 54 145 32 145 512)
The `X` itself is the operator-form of the `cross` routine, well-documented here:
https://docs.raku.org/routine/cross
https://docs.raku.org/language/operators#index-entry-X_(cross_metaoperator)
https://docs.raku.org/language/operators#index-entry-cross_product_operator
If any part of this was lacking in clarity, please let me know where to focus, and I will be glad to expound.
Hope this helps,
Bruce Gray (Util of Perlmonks)
Wow, that's a very comprehensive explanation. I've just found out that I couldn't even comprehend the first reduction operator. I was thinking it was doing some magic operations. All it did was enable the cross op to act on the 2 lists without having to be between them. As simple as that. And surely I mis-took the second bracket as a second reduction. Now it's clear that it's for Nesting of metaoperators Actually I was guessing this fine detail must have been documented in the Raku docs but I hadn't the faintest idea how to search for it in the huge docs of Raku :)
The custom operator definition to separate the Cross from the Op is very welcome too. I haven't written any custom op in Raku so far and it's good to see it in action.
Thank you for your time. Very much appreciated.
11.10.2020, 21:31, "Bruce Gray" <robertbrucegr...@gmail.com>:
- cross reduce operator magic Cezmi Pastirma
- Re: cross reduce operator magic Bruce Gray
- Re: cross reduce operator magic Joseph Brenner
- Re: cross reduce operator magic Cezmi Pastirma