I am trying to write  factrs in simple J.  I hit two snags:

   factrs=: */&>@{@((^ i.@>:)&.>/)@q:~&__
   5!:6 <'factrs'
((((((*/)&>)@{)@(((^ (i.@>:))&.>)/))@q:)~)&__
   factrs 500
1  5  25 125
2 10  50 250
4 20 100 500
   
   f=:((((((*/)&>)@{)@(((^ (i.@>:))&.>)/))@q:)~)&__
   g=:(((^ (i.@>:))&.>)/)
   g
(^ i.@>:)&.>/
   g 500
500
   
   f=:((((((*/)&>)@{)@g)@q:)~)&__
   h=:(((*/)&>)@{)
   h
*/&>@{
   h 500
500
   
   f=:(((h@g)@q:)~)&__
   f 
h@g@q:~&__
   
   gg=: 13 :'(<( ^ [: i. >:)>)/ y'
   hh=:  13 :'*/"1>"0{y'
   
   ff=:(((hh@g)@q:)~)&__
   ff 500
1  5  25 125
2 10  50 250
4 20 100 500
   
   ff=:(((hh@gg)@q:)~)&__
   ff 500
|length error: gg
|       ff 500
|[-24] c:\users\owner\j701-user\temp\52.ijs
   
I can't understand  gg  well enough to adjust the rank.

What does  &__  mean?

Linda


-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Raul Miller
Sent: Monday, February 11, 2013 3:28 PM
To: [email protected]
Subject: Re: [Jprogramming] Recursive programming (and scoping therein)

After reading this, and finally noticing the comment about remel in the
original post, I am uncomfortable with this treatment of remel.

A scheme 'alist' is like two J lists, one a list of keys which we search to
get an index into the other.  If the types are compatible (probably valid
for integers or boxes), this could be a two dimensional array where one of
the dimensions is 2.

But the original code is not using an alist, as near as I can tell -- it's
just using a list of divisors.  In this context, I think remel would
logically be replaced by dyadic use of J's -. primitive.
Except, this does not work as near as I can tell.  I'm not sure if that's
because remel is expected to modify the original alist, or if that's because
remel is really meant to treat the alist as a stack where it's removing not
only the matching element but all previous elements (which is what the J
implementation does).

But ignoring that, and using the original supplied definition, here's how I
would translate the original code to J:

allfactors =: af q:

remel =: [ }.~ [: >: i.

af=: dyad define
  divisors=. y
  num=. x
  if.0=#divisors do.,num end.
  uniquefactors=. ~.divisors
  ;num;(num&% af divisors&remel)&.> uniquefactors
)

I have not tried to optimize this for efficiency because the recursive
process itself is too inefficient to be worth bothering with.

For reference, here's one of the implementations from that rosetta code link
I posted earlier:

   factrs=: */&>@{@((^ i.@>:)&.>/)@q:~&__
   factrs 12
1  3
2  6
4 12

Obviously you would want to ravel that result before treating it as a list.

   ,@factrs 12
1 3 2 6 4 12

Anyways, I believe that this approach should be more efficient than the use
of remel (or whatever that should be) in recursion.

--
Raul

On Mon, Feb 11, 2013 at 12:01 PM, Marshall Lochbaum <[email protected]>
wrote:
> I assume the problems you're having are in getting num and divisors to 
> work inside the lambda clause. J can handle this fine--just use tacit 
> code rather than an explicit function for the lambda. Here is the same 
> code in J.
>
> remel =: ([ }.~ [: >: i.)"_ 0
>
> allfactors =: af q:
>
> af =: [ , 4 : 0 ^: (*@#@])
>   x (% af&.>(;@:) y <@remel ]) ~.y
> )
>
> af uses a bit of refactoring to avoid having to write the case where y
> (divisors) is empty explicitly. We know we want to tack x (num) to the 
> beginning of the list regardless of what happens in the function. Once 
> we have made this choice with the [ , at the beginning of af's 
> definition, we see that the rest of the function should just return an 
> empty list if passed an empty list for y. Therefore we add ^:(*@#@]) 
> to af. This means the explicit portion is only executed if y has 
> nonzero length. Otherwise it will do nothing, that is, return y which 
> is the empty list we want.
>
> The inside of the function is fairly straightforward. We compute the 
> nub of y to use as the right argument. Then y <@remel ] gives a boxed 
> list of terms (remel divisors x), and % with left argument x and right 
> argument ~.y gives the terms (/ num x). We apply af to them using 
> af&.> to give a list of boxed results and combine these into a single 
> list with ; .
>
> af can also be written in a completely tacit form, although in this 
> form we can't easily juggle the three terms num, divisors, and (unique 
> divisors). The easiest way out of this is just to compute the nub of 
> divisors twice.
>
> af =: [ , ((%~.) $:&.>(;@:) (<@remel ~.)@]) ^: (*@#@])
>
> This verb uses $: for self-reference, but is largely the same as the 
> other form of af.
>
> I realize that methods like these aren't really equivalent to proper 
> scoping rules, but I think most of the time they are good enough.
>
> Marshall
>
> On Mon, Feb 11, 2013 at 01:04:31PM +0000, Alex Giannakopoulos wrote:
>> Are there any resources on recursive programming in J?  Couldn't find 
>> much by searching.
>> I would particularly like to know about scoping, and also so-called 
>> free variables.
>>
>> It seems to me that the enforced naming of variables as 'x' and 'y' 
>> might cause problems in nested functions, necessitating awkward 
>> renaming and copying.
>>
>> I will give a little example here (my apologies to those unfamiliar 
>> with
>> Scheme.)
>> I am trying to write a routine that will return ALL the factors of a 
>> number, not just the prime ones.
>> I do this by using an auxiliary routine that takes the number to 
>> factor and a list of numbers still to combine.
>>
>> ;; function (unique numlist) corresponds to J's ~.
>> ;; function (remel alist elem) corresponds to J's   [ }.~ [: >: i.
>> ;; function (primefactors n) corresponds to J's   q:
>>
>> (define (allfactors n) (af n (primefators n))
>>
>> (define (af num divisors)
>>   (if (null? divisors) (list num)
>>       (let ((uniquefactors (unique divisors)))
>>            (flatten
>>            (cons num
>>                  (map (lambda(x) (af (/ num x) (remel divisors x)))
>>                       uniquefactors))))))
>>
>> Now I tried to express this in J, but can't even get to first base, 
>> because of the scoping problems I mentioned.
>> I realise that recursion is not the primary mode for programming J, 
>> and a good solution may instead use something like running totals 
>> (\), but for the time being I am stuck.
>> Any suggestions gratefully received.
>> ---------------------------------------------------------------------
>> - For information about J forums see 
>> http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to