repeat application of dyadic function

24 views
Skip to first unread message

David Pinchbeck

unread,
Aug 31, 2025, 12:42:01 PMAug 31
to fo...@jsoftware.com
Hi, I'm looking back at last year's Advent of Code, and in one of my solutions I have a dyadic function f that takes an integer x and an array Y and returns an array of the same shape as Y.  My solution has the atrocious looking code:

9 f 8 f 7 f 6 f 5 f 4 f 3 f 2 f 1 f C

What's a better way to write this?  

Thanks,
David

--
David Pinchbeck
Associate Professor of Mathematics
St. Joseph's College
Standish, ME

Henry Rich

unread,
Aug 31, 2025, 12:54:09 PMAug 31
to fo...@jsoftware.com
I don't have time to test a full answer, but here's something to look into.  Something like

C (] F.. f) >: i. 9

Henry Rich
To unsubscribe from this group and stop receiving emails from it, send an email to forum+un...@jsoftware.com.

Marcin Żołek

unread,
Aug 31, 2025, 3:39:14 PMAug 31
to fo...@jsoftware.com

An alternative (probably funnier than practical) approach is to first accumulate the function using J's gerunds, then apply noun C to the constructed verb.

NB. Example defs. C =: 42 73 17 37 f =: - NB. x bondLeft y creates a gerund representing verb with name x bonded with noun y as left argument. bondLeft =: ([: ,@< '&' ,&< (,&<~ '0'&;))"0 'f' bondLeft 3 ┌─────────────┐ │┌─┬─────────┐│ ││&│┌─────┬─┐││ ││ ││┌─┬─┐│f│││ ││ │││0│3││ │││ ││ ││└─┴─┘│ │││ ││ │└─────┴─┘││ │└─┴─────────┘│ └─────────────┘ ('f' bondLeft 3)`:6 3&f NB. We use bondLeft to create a gerund representing f composed with itself 9 times with bonded left arguments. gerund =: ]F.:('@:' ,:@:<@:(,&<) ,~) 'f'&bondLeft >: i. 9 f9 =: gerund`:6 f9 9&f@:(8&f)@:(7&f)@:(6&f)@:(5&f)@:(4&f)@:(3&f)@:(2&f)@:(01&f) f9 C _37 _68 _12 _32 NB. Check that the result is correct. 9 f 8 f 7 f 6 f 5 f 4 f 3 f 2 f 1 f C _37 _68 _12 _32


Marcin

Wiadomość napisana przez Henry Rich <henry...@gmail.com> w dniu 31.08.2025, o godz. 18:54:

Marcin Żołek

unread,
Sep 1, 2025, 5:40:35 AMSep 1
to fo...@jsoftware.com
I have noticed that my previous answer can be simplified and improved. I hope this makes the idea of accumulating the function in J using gerunds a bit clearer.

   NB. To match the comments, the verb bondLeft should have infinite rank so that it works for names longer than one character.
   bondLeft =: [: ,@< '&' ,&< (,&<~ '0'&;)

   NB. For example, it calculates sin(π / 2) = 1 in this (unnecessary) way:
   ('o.' bondLeft 1)`:6 ] 0.5p1
1

   NB. The definition of gerund can also be simplified.
   gerund =: ('@:' <@(,&<) ,~)/ 'f'&bondLeft"0 >: i. 9
   gerund`:6
9&f@:(8&f)@:(7&f)@:(6&f)@:(5&f)@:(4&f)@:(3&f)@:(2&f)@:(01&f)

It may be interesting to see how it works for smaller cases using Dissect (available in Jqt interface). The most interesting part can be seen by clicking the result in the interactive image created by Dissect which expands node representing ('@:' <@(,&<) ,~)/ to show the intermediate results. For example, (2&f)@:(1&f) case:

   load 'debug/dissect'
   dissect '(''@:'' <@(,&<) ,~)/ ''f''&bondLeft"0 >: i. 2'

Cheers,
Marcin

Wiadomość napisana przez Marcin Żołek <marcin...@students.mimuw.edu.pl> w dniu 31.08.2025, o godz. 21:38:
Reply all
Reply to author
Forward
0 new messages