Linda, here is a suggestion:
factrs=: */&>@{@((^ i.@>:)&.>/)@q:~&__
factrs 60
1 5
3 15
2 10
6 30
4 20
12 60
factrs1=: */&>@:{@:((^ i.@:>:)&.>/)@:q:~&__
factrs1 60
1 5
3 15
2 10
6 30
4 20
12 60
Now you can worry less about ranks.
Kip
Sent from my iPad
On Feb 16, 2013, at 9:13 PM, "Linda Alvord" <[email protected]> wrote:
> 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
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm