cross reduce operator magic

<div><div>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</div><div> </div><div>I've slightly rearranged the code to make it print Leyland numbers up to 1 Billion:</div><div><strong>.say for grep {$_ &lt; 1E11}, squish(sort [X[&amp;({$^a**$^b+$b**$a})]] 2..32,2..32)</strong></div><div> </div><div>The question in short is:</div><div> </div><div>How does the cross reduce work there?</div><div> </div><div>Extra info:</div><div> </div><div>That cross reduce section surely does what this half-pseudo code tries to do:</div><div><strong>map { $^a ** $^b + $b ** $a }, 2..32,32...2</strong></div><div>The tricky part here is the use of reduce operators two times in a row, once before the cross operator, once before the &amp; operator, which I guess donates a closure. How to interpret this usage of operators?</div><div> </div></div>
0
cezmisikim
10/11/2020 3:39:20 PM
perl.perl6.users 1485 articles. 0 followers. Follow

4 Replies
4 Views

Similar Articles

[PageSpeed] 19

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.html


> On Oct 11, 2020, at 10:39 AM, Cezmi Pastirma <cezmisikim@yandex.com> =
wrote:
>=20
> 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
> =20
> 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)
> =20
> The question in short is:
> =20
> 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:
> =20
> That cross reduce section surely does what this half-pseudo code tries =
to do:
> map { $^a ** $^b + $b ** $a }, 2..32,32=E2=80=A62

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=E2=80=9D 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?
> =20

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:<=E2=A8=81> ($a, $b) {
		   $a ** $b=20
		+ $b ** $a
	};
	say 2 =E2=A8=81 3;
	say 2..4 X=E2=A8=81 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_operato=
r

If any part of this was lacking in clarity, please let me know where to =
focus, and I will be glad to expound.

--=20
Hope this helps,
Bruce Gray (Util of Perlmonks)
0
robertbrucegray3
10/11/2020 7:31:44 PM
 Bruce Gray <robertbrucegray3@gmail.com> wrote:
> NOTE: 30 minutes from now is the start of the Raku Study Group of the San
> Francisco Perl Mongers.

Thanks-- though now it's 3 minutes-- but that was the info for last week.
The current one is:

  https://www.meetup.com/San-Francisco-Perl/events/273839687/

In general, you can start at the San Francisco Perl group to get the
latest meeting info:

  https://www.meetup.com/San-Francisco-Perl

> We can offer a "deep dive" into how the Leyland code works, if that would=
 be
> helpful.

I'm glad *you're* offering, I was just looking at that one going uh,
Leyland Numbers?  I haven't even heard of "squish"...




> Zoom details here:
> https://mail.pm.org/pipermail/sanfrancisco-pm/2020-October/004726.html
>
>
>> On Oct 11, 2020, at 10:39 AM, Cezmi Pastirma <cezmisikim@yandex.com>
>> wrote:
>>
>> I've got a question about a Leyland-numbers-listing Raku code which I sa=
w
>> 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 t=
o
>> do:
>> map { $^a ** $^b + $b ** $a }, 2..32,32=E2=80=A62
>
> 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=E2=80=9D 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 gues=
s
>> 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_metaoperator=
s
>
> 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:<=E2=A8=81> ($a, $b) {
> 		   $a ** $b
> 		+ $b ** $a
> 	};
> 	say 2 =E2=A8=81 3;
> 	say 2..4 X=E2=A8=81 2..4;
> 		17
> 		(8 17 32 17 54 145 32 145 512)
>
> The `X` itself is the operator-form of the `cross` routine, well-document=
ed
> here:
> 	https://docs.raku.org/routine/cross
> 	https://docs.raku.org/language/operators#index-entry-X_(cross_metaoperat=
or)
> 	https://docs.raku.org/language/operators#index-entry-cross_product_opera=
tor
>
> 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)
>
0
doomvox
10/11/2020 7:59:20 PM
PGRpdj5Xb3csIHRoYXQncyBhIHZlcnkgY29tcHJlaGVuc2l2ZSBleHBsYW5hdGlvbi4gSSd2ZSBq
dXN0IGZvdW5kIG91dCB0aGF0IEkgY291bGRuJ3QgZXZlbiBjb21wcmVoZW5kIHRoZSBmaXJzdCBy
ZWR1Y3Rpb24gb3BlcmF0b3IuIEkgd2FzIHRoaW5raW5nIGl0IHdhcyBkb2luZyBzb21lIG1hZ2lj
IG9wZXJhdGlvbnMuIEFsbCBpdCBkaWQgd2FzIGVuYWJsZSB0aGUgY3Jvc3Mgb3AgdG8gYWN0IG9u
IHRoZSAyIGxpc3RzIHdpdGhvdXQgaGF2aW5nIHRvIGJlIMKgYmV0d2VlbiDCoCB0aGVtLiBBcyBz
aW1wbGUgYXMgdGhhdC4gQW5kIHN1cmVseSBJIG1pcy10b29rIHRoZSBzZWNvbmQgYnJhY2tldCBh
cyBhIHNlY29uZCByZWR1Y3Rpb24uIE5vdyBpdCdzIGNsZWFyIHRoYXQgaXQncyBmb3IgPGEgaHJl
Zj0iaHR0cHM6Ly9kb2NzLnJha3Uub3JnL2xhbmd1YWdlL29wZXJhdG9ycyNfX190b3AiIHRpdGxl
PSJnbyB0byB0b3Agb2YgZG9jdW1lbnQiPk5lc3Rpbmcgb2YgbWV0YW9wZXJhdG9yczwvYT4gwqBB
Y3R1YWxseSBJIHdhcyBndWVzc2luZyB0aGlzIGZpbmUgZGV0YWlsIG11c3QgaGF2ZSBiZWVuIGRv
Y3VtZW50ZWQgaW4gdGhlIFJha3UgZG9jcyBidXQgSSBoYWRuJ3QgdGhlIGZhaW50ZXN0IGlkZWEg
aG93IHRvIHNlYXJjaCBmb3IgaXQgaW4gdGhlIGh1Z2UgZG9jcyBvZiBSYWt1IDopPC9kaXY+PGRp
dj7CoDwvZGl2PjxkaXY+VGhlIGN1c3RvbSBvcGVyYXRvciBkZWZpbml0aW9uIHRvIHNlcGFyYXRl
IHRoZSBDcm9zcyBmcm9tIHRoZSBPcCBpcyB2ZXJ5IHdlbGNvbWUgdG9vLiBJIGhhdmVuJ3Qgd3Jp
dHRlbiBhbnkgY3VzdG9tIG9wIGluIFJha3Ugc28gZmFyIGFuZCBpdCdzIGdvb2QgdG8gc2VlIGl0
IGluIGFjdGlvbi48L2Rpdj48ZGl2PsKgPC9kaXY+PGRpdj5UaGFuayB5b3UgZm9yIHlvdXIgdGlt
ZS4gVmVyeSBtdWNoIGFwcHJlY2lhdGVkLjwvZGl2PjxkaXY+PGJyIC8+PC9kaXY+PGRpdj48YnIg
Lz48L2Rpdj48ZGl2PjExLjEwLjIwMjAsIDIxOjMxLCAiQnJ1Y2UgR3JheSIgJmx0O3JvYmVydGJy
dWNlZ3JheTNAZ21haWwuY29tJmd0Ozo8L2Rpdj48YmxvY2txdW90ZT48cD5OT1RFOiAzMCBtaW51
dGVzIGZyb20gbm93IGlzIHRoZSBzdGFydCBvZiB0aGUgUmFrdSBTdHVkeSBHcm91cCBvZiB0aGUg
U2FuIEZyYW5jaXNjbyBQZXJsIE1vbmdlcnMuPGJyIC8+V2UgY2FuIG9mZmVyIGEgImRlZXAgZGl2
ZSIgaW50byBob3cgdGhlIExleWxhbmQgY29kZSB3b3JrcywgaWYgdGhhdCB3b3VsZCBiZSBoZWxw
ZnVsLjxiciAvPlpvb20gZGV0YWlscyBoZXJlOiA8YSBocmVmPSJodHRwczovL21haWwucG0ub3Jn
L3BpcGVybWFpbC9zYW5mcmFuY2lzY28tcG0vMjAyMC1PY3RvYmVyLzAwNDcyNi5odG1sIj5odHRw
czovL21haWwucG0ub3JnL3BpcGVybWFpbC9zYW5mcmFuY2lzY28tcG0vMjAyMC1PY3RvYmVyLzAw
NDcyNi5odG1sPC9hPjxiciAvPjxiciAvPjxiciAvPjwvcD48YmxvY2txdW90ZSBjbGFzcz0iMjEw
ZTdhODQ4ZThmY2I0NXdtaS1xdW90ZSI+wqBPbiBPY3QgMTEsIDIwMjAsIGF0IDEwOjM5IEFNLCBD
ZXptaSBQYXN0aXJtYSAmbHQ7PGEgaHJlZj0ibWFpbHRvOmNlem1pc2lraW1AeWFuZGV4LmNvbSI+
Y2V6bWlzaWtpbUB5YW5kZXguY29tPC9hPiZndDsgd3JvdGU6PGJyIC8+wqA8YnIgLz7CoEkndmUg
Z290IGEgcXVlc3Rpb24gYWJvdXQgYSBMZXlsYW5kLW51bWJlcnMtbGlzdGluZyBSYWt1IGNvZGUg
d2hpY2ggSSBzYXcgYXQgY29kZWdvbGYuc3RhY2tleGNoYW5nZS5jb20gYXQgPGEgaHJlZj0iaHR0
cHM6Ly9jb2RlZ29sZi5zdGFja2V4Y2hhbmdlLmNvbS9hLzgzMDEzLzk4MTMyIj5odHRwczovL2Nv
ZGVnb2xmLnN0YWNrZXhjaGFuZ2UuY29tL2EvODMwMTMvOTgxMzI8L2E+PGJyIC8+wqDCoDxiciAv
PsKgSSd2ZSBzbGlnaHRseSByZWFycmFuZ2VkIHRoZSBjb2RlIHRvIG1ha2UgaXQgcHJpbnQgTGV5
bGFuZCBudW1iZXJzIHVwIHRvIDEgQmlsbGlvbjo8YnIgLz7CoC5zYXkgZm9yIGdyZXAgeyRfICZs
dDsgMUUxMX0sIHNxdWlzaChzb3J0IFtYWyZhbXA7KHskXmEqKiReYiskYioqJGF9KV1dIDIuLjMy
LDIuLjMyKTxiciAvPsKgwqA8YnIgLz7CoFRoZSBxdWVzdGlvbiBpbiBzaG9ydCBpczo8YnIgLz7C
oMKgPGJyIC8+wqBIb3cgZG9lcyB0aGUgY3Jvc3MgcmVkdWNlIHdvcmsgdGhlcmU/PGJyIC8+PC9i
bG9ja3F1b3RlPjxwPjxiciAvPlRoZSByZWR1Y3Rpb24gaXMgYSByZWQgaGVycmluZyB0byBvdXIg
dW5kZXJzdGFuZGluZyBoZXJlLjxiciAvPk5vdGUgdGhhdCwgd2hlbiB5b3UgYXJlIG9ubHkgW3Jl
ZHVjaW5nXSBvbiB0d28gbGlzdHMsIGBbYW55X29wX2hlcmVdIEBhLCBAYmAgaXMgdGhlIHNhbWUg
YXMgYEBhIGFueV9vcF9oZXJlIEBiYC48YnIgLz5UaGVzZSBhcmUgZXF1aXZhbGVudDo8YnIgLz7C
oMKgwqDCoMKgwqDCoMKgc2F5IFtYK10gMi4uNCwgICAgICAxLi41OzxiciAvPsKgwqDCoMKgwqDC
oMKgwqBzYXkgICAgICAgICAyLi40IFgrIDEuLjU7PGJyIC8+VGhlIG9wZXJhdG9yIG5lZWQgbm90
IGJlIGEgbWV0YS1vcGVyYXRvcjo8YnIgLz7CoMKgwqDCoMKgwqDCoMKgc2F5IFsqXSAzLCAgNTs8
YnIgLz7CoMKgwqDCoMKgwqDCoMKgc2F5ICAgICAzICogNTs8YnIgLz48YnIgLz48L3A+PGJsb2Nr
cXVvdGUgY2xhc3M9IjIxMGU3YTg0OGU4ZmNiNDV3bWktcXVvdGUiPsKgRXh0cmEgaW5mbzo8YnIg
Lz7CoMKgPGJyIC8+wqBUaGF0IGNyb3NzIHJlZHVjZSBzZWN0aW9uIHN1cmVseSBkb2VzIHdoYXQg
dGhpcyBoYWxmLXBzZXVkbyBjb2RlIHRyaWVzIHRvIGRvOjxiciAvPsKgbWFwIHsgJF5hICoqICRe
YiArICRiICoqICRhIH0sIDIuLjMyLDMy4oCmMjxiciAvPjwvYmxvY2txdW90ZT48cD48YnIgLz5J
ZiBAYyBoYXMgMjAgZWxlbWVudHMsIGFuZCBAZCBoYXMgMzAgZWxlbWVudHMsIHRoZW4gYEBjIFgr
IEBkYCBoYXMgNjAwIGVsZW1lbnRzLjxiciAvPllvdSBjYW5ub3QgcHJvZHVjZSB0aGUgZXF1aXZh
bGVudCB3aXRoIGEgc2ltcGxlIGBtYXBgLjxiciAvPihZb3UgY291bGQgd2l0aCBhIGZsYXR0ZW5l
ZCBtYXAtd2l0aGluLWEtbWFwKTxiciAvPjxiciAvPjxiciAvPlNpbXBsaWZ5aW5nIHlvdXIgInNs
aWdodGx5IHJlYXJyYW5nZWTigJ0gY29kZTo8YnIgLz7CoMKgwqDCoMKgwqDCoMKgLnNheSBmb3Ig
Z3JlcCB7JF8gJmx0OyAxRTExfSwgc3F1aXNoKHNvcnQgW1hbJmFtcDsoeyReYSoqJF5iKyRiKiok
YX0pXV0gMi4uMzIsMi4uMzIpPGJyIC8+PGJyIC8+Li4udG8ganVzdCB0aGUgcGFydCB5b3UgYXJl
IGN1cmlvdXMgYWJvdXQsIHdlIGdldDo8YnIgLz7CoMKgwqDCoMKgwqDCoMKgc2F5IFtYWyZhbXA7
KHskXmEqKiReYiskYioqJGF9KV1dIDIuLjQsMi4uNDs8YnIgLz7CoMKgwqDCoMKgwqDCoMKgwqDC
oMKgwqDCoMKgwqDCoCg4IDE3IDMyIDE3IDU0IDE0NSAzMiAxNDUgNTEyKTxiciAvPjxiciAvPldl
IGFyZSBvbmx5IFtyZWR1Y2luZ10gb24gdHdvIGxpc3RzLCBzbyB3ZSBjYW4gcmVtb3ZlIHRoZSBy
ZWR1Y3Rpb24sIGFuZCBqdXN0IHVzZSB0aGUgWG9wOjxiciAvPsKgwqDCoMKgwqDCoMKgwqBzYXkg
Mi4uNCBYWyZhbXA7KHskXmEqKiReYiskYioqJGF9KV0gMi4uNDs8YnIgLz7CoMKgwqDCoMKgwqDC
oMKgwqDCoMKgwqDCoMKgwqDCoCg4IDE3IDMyIDE3IDU0IDE0NSAzMiAxNDUgNTEyKTxiciAvPjxi
ciAvPjxiciAvPjwvcD48YmxvY2txdW90ZSBjbGFzcz0iMjEwZTdhODQ4ZThmY2I0NXdtaS1xdW90
ZSI+wqBUaGUgdHJpY2t5IHBhcnQgaGVyZSBpcyB0aGUgdXNlIG9mIHJlZHVjZSBvcGVyYXRvcnMg
dHdvIHRpbWVzIGluIGEgcm93LCBvbmNlIGJlZm9yZSB0aGUgY3Jvc3Mgb3BlcmF0b3IsIG9uY2Ug
YmVmb3JlIHRoZSAmYW1wOyBvcGVyYXRvciwgd2hpY2ggSSBndWVzcyBkb25hdGVzIGEgY2xvc3Vy
ZS4gSG93IHRvIGludGVycHJldCB0aGlzIHVzYWdlIG9mIG9wZXJhdG9ycz88YnIgLz7CoMKgPGJy
IC8+PC9ibG9ja3F1b3RlPjxwPjxiciAvPlRoZSBzcXVhcmUgYnJhY2tldHMgYWZ0ZXIgdGhlIFgs
IEkgdGhpbmsgeW91IG1pcy10b29rIGFzIGEgc2Vjb25kIHJlZHVjdGlvbi48YnIgLz48YnIgLz5U
aG9zZSBicmFja2V0cyBhcmUganVzdCB0aGVyZSB0byBkaXNhbWJpZ3VhdGUgdGhlIGBvcGAgdGhh
dCB0aGUgYFhgIGlzIGNyb3NzaW5nIG9uLjxiciAvPsKgwqDCoMKgU2VlOiA8YSBocmVmPSJodHRw
czovL2RvY3MucmFrdS5vcmcvbGFuZ3VhZ2Uvb3BlcmF0b3JzI05lc3Rpbmdfb2ZfbWV0YW9wZXJh
dG9ycyI+aHR0cHM6Ly9kb2NzLnJha3Uub3JnL2xhbmd1YWdlL29wZXJhdG9ycyNOZXN0aW5nX29m
X21ldGFvcGVyYXRvcnM8L2E+PGJyIC8+PGJyIC8+VGhlc2UgYXJlIGVxdWl2YWxlbnQ6PGJyIC8+
wqDCoMKgwqAuc2F5IGZvciBeMiBYKyAgIF4yOzxiciAvPsKgwqDCoMKgLnNheSBmb3IgXjIgWFsr
XSBeMjs8YnIgLz48YnIgLz48YnIgLz5XZSBjYW4gY3JlYXRlIG91ciBvd24gb3BlcmF0b3IsIHRv
IGZ1cnRoZXIgc2VwYXJhdGUgdGhlIENyb3NzIGZyb20gdGhlIE9wOjxiciAvPsKgwqDCoMKgwqDC
oMKgwqBtdWx0aSBpbmZpeDombHQ74qiBJmd0OyAoJGEsICRiKSB7PCEtLSAtLT48YnIgLz7CoMKg
wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCRhICoqICRiIDxiciAvPsKgwqDCoMKg
wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgKyAkYiAqKiAkYTxiciAvPsKgwqDCoMKgwqDCoMKgwqB9
OzxiciAvPsKgwqDCoMKgwqDCoMKgwqBzYXkgMiDiqIEgMzs8YnIgLz7CoMKgwqDCoMKgwqDCoMKg
c2F5IDIuLjQgWOKogSAyLi40OzxiciAvPsKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg
MTc8YnIgLz7CoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCg4IDE3IDMyIDE3IDU0IDE0
NSAzMiAxNDUgNTEyKTxiciAvPjxiciAvPlRoZSBgWGAgaXRzZWxmIGlzIHRoZSBvcGVyYXRvci1m
b3JtIG9mIHRoZSBgY3Jvc3NgIHJvdXRpbmUsIHdlbGwtZG9jdW1lbnRlZCBoZXJlOjxiciAvPsKg
wqDCoMKgwqDCoMKgwqA8YSBocmVmPSJodHRwczovL2RvY3MucmFrdS5vcmcvcm91dGluZS9jcm9z
cyI+aHR0cHM6Ly9kb2NzLnJha3Uub3JnL3JvdXRpbmUvY3Jvc3M8L2E+PGJyIC8+wqDCoMKgwqDC
oMKgwqDCoDxhIGhyZWY9Imh0dHBzOi8vZG9jcy5yYWt1Lm9yZy9sYW5ndWFnZS9vcGVyYXRvcnMj
aW5kZXgtZW50cnktWF8oY3Jvc3NfbWV0YW9wZXJhdG9yKSI+aHR0cHM6Ly9kb2NzLnJha3Uub3Jn
L2xhbmd1YWdlL29wZXJhdG9ycyNpbmRleC1lbnRyeS1YXyhjcm9zc19tZXRhb3BlcmF0b3IpPC9h
PjxiciAvPsKgwqDCoMKgwqDCoMKgwqA8YSBocmVmPSJodHRwczovL2RvY3MucmFrdS5vcmcvbGFu
Z3VhZ2Uvb3BlcmF0b3JzI2luZGV4LWVudHJ5LWNyb3NzX3Byb2R1Y3Rfb3BlcmF0b3IiPmh0dHBz
Oi8vZG9jcy5yYWt1Lm9yZy9sYW5ndWFnZS9vcGVyYXRvcnMjaW5kZXgtZW50cnktY3Jvc3NfcHJv
ZHVjdF9vcGVyYXRvcjwvYT48YnIgLz48YnIgLz5JZiBhbnkgcGFydCBvZiB0aGlzIHdhcyBsYWNr
aW5nIGluIGNsYXJpdHksIHBsZWFzZSBsZXQgbWUga25vdyB3aGVyZSB0byBmb2N1cywgYW5kIEkg
d2lsbCBiZSBnbGFkIHRvIGV4cG91bmQuPGJyIC8+PGJyIC8+PC9wPjxzcGFuIGNsYXNzPSJmNTVi
YmI0ZWVlZjIwOGU4d21pLXNpZ24iPi0tIDxiciAvPkhvcGUgdGhpcyBoZWxwcyw8YnIgLz5CcnVj
ZSBHcmF5IChVdGlsIG9mIFBlcmxtb25rcyk8YnIgLz48L3NwYW4+PC9ibG9ja3F1b3RlPg==
0
cezmisikim
10/11/2020 9:48:56 PM
--00000000000093455e05b16e6fdb
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Since this is a golf exercize, reducing number of characters, why use the
reduction form when infix is shorter?

squish(sort [X[&({$^a**$^b+$b**$a})]] 2..31,2..31) # from original
squish(sort 2..31 X[&({$^a**$^b+$b**$a})] 2..31) # infix is 2-chars shorter

Also I am trying to do a little un-golf speed-optimizing, the Wiki page for
the sequence notes that requiring a<=3Db removes trivial duplicates. Let's
see what I can figure out in the near future...

-y


On Sun, Oct 11, 2020 at 5:55 PM Cezmi Pastirma <cezmisikim@yandex.com>
wrote:

> 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 ac=
t
> on the 2 lists without having to be  between   them. As simple as that. A=
nd
> surely I mis-took the second bracket as a second reduction. Now it's clea=
r
> that it's for Nesting of metaoperators
> <https://docs.raku.org/language/operators#___top>  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" <robertbrucegray3@gmail.com>:
>
> 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.html
>
>
>  On Oct 11, 2020, at 10:39 AM, Cezmi Pastirma <cezmisikim@yandex.com>
> wrote:
>
>  I've got a question about a Leyland-numbers-listing Raku code which I sa=
w
> 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 t=
o
> do:
>  map { $^a ** $^b + $b ** $a }, 2..32,32=E2=80=A62
>
>
> 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=E2=80=9D 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_metaoperator=
s
>
> 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:<=E2=A8=81> ($a, $b) {
>                    $a ** $b
>                 + $b ** $a
>         };
>         say 2 =E2=A8=81 3;
>         say 2..4 X=E2=A8=81 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_metaoperato=
r)
>
> https://docs.raku.org/language/operators#index-entry-cross_product_operat=
or
>
> 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)
>
>

--00000000000093455e05b16e6fdb
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr">Since t=
his is a golf exercize, reducing number of characters, why use the reductio=
n form when infix is shorter?<div><br></div><div><font face=3D"monospace">s=
quish(sort [X[&amp;({$^a**$^b+$b**$a})]] 2..31,2..31) </font># from origina=
l<br></div><div><font face=3D"monospace">squish(sort 2..31 X[&amp;({$^a**$^=
b+$b**$a})] 2..31) </font># infix is 2-chars shorter<br></div><div><br></di=
v><div>Also I am trying to do a little un-golf speed-optimizing, the Wiki p=
age for the sequence notes that requiring a&lt;=3Db removes trivial duplica=
tes. Let&#39;s see what I can figure out in the near future...</div><div><b=
r clear=3D"all"><div><div dir=3D"ltr" class=3D"gmail_signature">-y<br></div=
></div><br></div></div></div></div></div><br><div class=3D"gmail_quote"><di=
v dir=3D"ltr" class=3D"gmail_attr">On Sun, Oct 11, 2020 at 5:55 PM Cezmi Pa=
stirma &lt;<a href=3D"mailto:cezmisikim@yandex.com">cezmisikim@yandex.com</=
a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-c=
olor:rgb(204,204,204);padding-left:1ex"><div>Wow, that&#39;s a very compreh=
ensive explanation. I&#39;ve just found out that I couldn&#39;t even compre=
hend the first reduction operator. I was thinking it was doing some magic o=
perations. All it did was enable the cross op to act on the 2 lists without=
 having to be =C2=A0between =C2=A0 them. As simple as that. And surely I mi=
s-took the second bracket as a second reduction. Now it&#39;s clear that it=
&#39;s for <a href=3D"https://docs.raku.org/language/operators#___top" titl=
e=3D"go to top of document" target=3D"_blank">Nesting of metaoperators</a> =
=C2=A0Actually I was guessing this fine detail must have been documented in=
 the Raku docs but I hadn&#39;t the faintest idea how to search for it in t=
he huge docs of Raku :)</div><div>=C2=A0</div><div>The custom operator defi=
nition to separate the Cross from the Op is very welcome too. I haven&#39;t=
 written any custom op in Raku so far and it&#39;s good to see it in action=
..</div><div>=C2=A0</div><div>Thank you for your time. Very much appreciated=
..</div><div><br></div><div><br></div><div>11.10.2020, 21:31, &quot;Bruce Gr=
ay&quot; &lt;<a href=3D"mailto:robertbrucegray3@gmail.com" target=3D"_blank=
">robertbrucegray3@gmail.com</a>&gt;:</div><blockquote><p>NOTE: 30 minutes =
from now is the start of the Raku Study Group of the San Francisco Perl Mon=
gers.<br>We can offer a &quot;deep dive&quot; into how the Leyland code wor=
ks, if that would be helpful.<br>Zoom details here: <a href=3D"https://mail=
..pm.org/pipermail/sanfrancisco-pm/2020-October/004726.html" target=3D"_blan=
k">https://mail.pm.org/pipermail/sanfrancisco-pm/2020-October/004726.html</=
a><br><br><br></p><blockquote>=C2=A0On Oct 11, 2020, at 10:39 AM, Cezmi Pas=
tirma &lt;<a href=3D"mailto:cezmisikim@yandex.com" target=3D"_blank">cezmis=
ikim@yandex.com</a>&gt; wrote:<br>=C2=A0<br>=C2=A0I&#39;ve got a question a=
bout a Leyland-numbers-listing Raku code which I saw at <a href=3D"http://c=
odegolf.stackexchange.com" target=3D"_blank">codegolf.stackexchange.com</a>=
 at <a href=3D"https://codegolf.stackexchange.com/a/83013/98132" target=3D"=
_blank">https://codegolf.stackexchange.com/a/83013/98132</a><br>=C2=A0=C2=
=A0<br>=C2=A0I&#39;ve slightly rearranged the code to make it print Leyland=
 numbers up to 1 Billion:<br>=C2=A0.say for grep {$_ &lt; 1E11}, squish(sor=
t [X[&amp;({$^a**$^b+$b**$a})]] 2..32,2..32)<br>=C2=A0=C2=A0<br>=C2=A0The q=
uestion in short is:<br>=C2=A0=C2=A0<br>=C2=A0How does the cross reduce wor=
k there?<br></blockquote><p><br>The reduction is a red herring to our under=
standing here.<br>Note that, when you are only [reducing] on two lists, `[a=
ny_op_here] @a, @b` is the same as `@a any_op_here @b`.<br>These are equiva=
lent:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0say [X+] 2..4,    =
  1..5;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0say         2..4=
 X+ 1..5;<br>The operator need not be a meta-operator:<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0say [*] 3,  5;<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0say     3 * 5;<br><br></p><blockquote>=C2=A0Extra i=
nfo:<br>=C2=A0=C2=A0<br>=C2=A0That cross reduce section surely does what th=
is half-pseudo code tries to do:<br>=C2=A0map { $^a ** $^b + $b ** $a }, 2.=
..32,32=E2=80=A62<br></blockquote><p><br>If @c has 20 elements, and @d has 3=
0 elements, then `@c X+ @d` has 600 elements.<br>You cannot produce the equ=
ivalent with a simple `map`.<br>(You could with a flattened map-within-a-ma=
p)<br><br><br>Simplifying your &quot;slightly rearranged=E2=80=9D code:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0.say for grep {$_ &lt; 1E11=
}, squish(sort [X[&amp;({$^a**$^b+$b**$a})]] 2..32,2..32)<br><br>...to just=
 the part you are curious about, we get:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0say [X[&amp;({$^a**$^b+$b**$a})]] 2..4,2..4;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0(8 17 32 17 54 145 32 145 512)<br><br>We are only [reducing] on=
 two lists, so we can remove the reduction, and just use the Xop:<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0say 2..4 X[&amp;({$^a**$^b+$b**$a=
})] 2..4;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0(8 17 32 17 54 145 32 145 512)<br><br><=
br></p><blockquote>=C2=A0The tricky part here is the use of reduce operator=
s two times in a row, once before the cross operator, once before the &amp;=
 operator, which I guess donates a closure. How to interpret this usage of =
operators?<br>=C2=A0=C2=A0<br></blockquote><p><br>The square brackets after=
 the X, I think you mis-took as a second reduction.<br><br>Those brackets a=
re just there to disambiguate the `op` that the `X` is crossing on.<br>=C2=
=A0=C2=A0=C2=A0=C2=A0See: <a href=3D"https://docs.raku.org/language/operato=
rs#Nesting_of_metaoperators" target=3D"_blank">https://docs.raku.org/langua=
ge/operators#Nesting_of_metaoperators</a><br><br>These are equivalent:<br>=
=C2=A0=C2=A0=C2=A0=C2=A0.say for ^2 X+   ^2;<br>=C2=A0=C2=A0=C2=A0=C2=A0.sa=
y for ^2 X[+] ^2;<br><br><br>We can create our own operator, to further sep=
arate the Cross from the Op:<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0multi infix:&lt;=E2=A8=81&gt; ($a, $b) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0$a ** $b <br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0+ $b ** $a<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0say 2 =E2=A8=81 3;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0say 2..4 X=E2=A8=81 2..4;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A017<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0(8 17 32 17 54 145 32 145 512)<br><br>The `X` itself is t=
he operator-form of the `cross` routine, well-documented here:<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<a href=3D"https://docs.raku.org/rou=
tine/cross" target=3D"_blank">https://docs.raku.org/routine/cross</a><br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<a href=3D"https://docs.rak=
u.org/language/operators#index-entry-X_(cross_metaoperator)" target=3D"_bla=
nk">https://docs.raku.org/language/operators#index-entry-X_(cross_metaopera=
tor)</a><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<a href=3D"http=
s://docs.raku.org/language/operators#index-entry-cross_product_operator" ta=
rget=3D"_blank">https://docs.raku.org/language/operators#index-entry-cross_=
product_operator</a><br><br>If any part of this was lacking in clarity, ple=
ase let me know where to focus, and I will be glad to expound.<br><br></p><=
span>-- <br>Hope this helps,<br>Bruce Gray (Util of Perlmonks)<br></span></=
blockquote></blockquote></div>

--00000000000093455e05b16e6fdb--
0
not
10/12/2020 12:32:28 AM
Reply: