(0 = {:)`(%/ ,: {.)}@,:
is another solution.
It has the same effect as
([ * 0 = ]) + % * 0 ~: ]
or
%^:(~:&0)"0
in that it keeps the original number instead of
replacing it by 0. As a side-note, I was
surprised not to find special code associated
with v1`v2}, especially if v2 has the form
u ,: v. An example from Learning J is the
"vectorial" Collatz sequence: instead of
scol=: -:`(1 + 3 * ])@.(2&|)"0
which is kind of slow, one can write
vcol=: 2&|`(-: ,: 1 + 3 * ])}
which is MUCH faster, even if both -: and
1 + 3 * ] are executed, simply because they're
executed on vectors and not scalars:
]st=: 10 timespacex 'scol i.300000'
0.545868 1.59781e8
]vt=: 10 timespacex 'vcol i.300000'
0.0209675 3.40812e7
vt%st
0.0384113 0.213299
The second approach might not be faster in other
cases where the two (or more) verbs are more
costly to execute; special code would really shine
there.
Upon further inspection of the dictionary, I came up
with this good old explicit expression which seems
to be almost as fast as the tacit % * 0 ~: ] :
a=: ?1e6#5
b=: ?1e6#5
timespacex 'a=: (b~:0)}a,:a%b'
0.042355 5.97715e7
Not quite as fast, since the ?1e6#5 aren't included
in the timing, but according to the dictionary,
special code modifies the array a in-place. It
also says that the ,: is avoided; this really would
shine if it was extended to tacit amend.
Best regards,
Louis
PS: Am I right if I say that monadic amend is an
extension of "mask" (/a,v,b/) from the original
A Programming Language?
> On 06 May 2016, at 18:03, [email protected] wrote:
>
> Send Programming mailing list submissions to
> [email protected]
>
> To subscribe or unsubscribe via the World Wide Web, visit
> http://jsoftware.com/mailman/listinfo/programming
> or, via email, send a message with subject or body 'help' to
> [email protected]
>
> You can reach the person managing the list at
> [email protected]
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Programming digest..."
>
>
> Today's Topics:
>
> 1. Re: Project Euler 1 (Martin Kreuzer)
> 2. Re: divide if not zero ('Bo Jacoby' via Programming)
> 3. Re: Project Euler 1 (Raul Miller)
> 4. Re: Project Euler 1 (Geoff Canyon)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Fri, 06 May 2016 14:11:54 +0000
> From: Martin Kreuzer <[email protected]>
> To: [email protected]
> Subject: Re: [Jprogramming] Project Euler 1
> Message-ID:
> <572ca635.0c279d0a.62eb4.ffffbe7esmtpin_added_miss...@mx.google.com>
> Content-Type: text/plain; charset="us-ascii"; format=flowed
>
> In the effort of generalizing it more, I noticed that
>
> (3 5) (0 +./ .= (|/ i.)) 10
> 1 0 0 1 0 1 1 0 0 1
>
> works fine, but collapses when only on divider is given
>
> (2) (0 +./ .= (|/ i.)) 10
> 1
>
> (looks like the resulting vector being ORed).
>
> Q1:
> Is there a possible twist to bring these two cases (one | more than
> one) together..?
>
> In continuing toward solution to PE1 (generalized) I produced this line
>
> pe1g=. 13 : '+/ (i.y) * (x) (0 +./ .= (|/ i.)) y'
>
> which seems to deliver correct results
>
> (3 5) pe1g 10
> 23
> (3 5) pe1g 1000
> 233168
>
> but still doesn't cover the special case:
>
> (2) pe1g 10
> 45
>
> *~~~~~*
>
> Going tacid using the result of the "13 cheat"
>
> pe1g=. [: +/ ([: i. ]) * 0 +./ .= (|/ i.)
>
> I end up near, but not quite at Raul's 2nd suggestion
>
> pe1=: [:+/ [:I. 0 +./ .= (|/ i.)
>
> Q2:
> Why is it, that sometimes the placeholder (]) is used to indicate the
> right hand argument, and sometimes not..?
>
> If I put two of those (i.]) in my version (as was my first thought),
> I do even get a wrong answer:
>
> pe1gf=. [: +/ ([: i. ]) * 0 +./ .= (|/ i.])
> 3 5 pe1gf 10
> 0
>
> *~~~~~*
>
> Progressing from
>
> (2) (0 = (|/ i.)) 10
> 1 0 1 0 1 0 1 0 1 0
>
> to
>
> (I.) (2) (0 = (|/ i.)) 10
> 0 2 4 6 8
>
> I now see how (I.) was used to compact it further by evaluating the
> bit mask (instead of multiplying the elements). Neat.
>
> -M
>
>
> At 2016-05-06 08:43, you wrote:
>> Let me add that, following this thread so far, I too learned a few
>> things today - and pardon me for outlining the steps for further
>> reference. I (again) did a very base level approach: 3 + 8 9 10
>> 11 12 13 5 + 8 9 10 13 14 15 3 5 + 8 9 10 |length error
>> | 3 5 +8 9 10 At that stage I realized that (/) isn't only
>> "Insert" but also used to force a "Table": 3 5 +/ 8 9 10 11 12
>> 13 13 14 15 These lines take the "Modulo" and, in a second step,
>> throw a "1" for a match [division result zero], "0"
>> otherwise): 3 5 |/ 8 9 10 2 0 1 3 4 0 3 5 (0=|/) 8 9 10 0
>> 1 0 0 0 1 I then combined these results by ORing (+.) the two
>> rows: +./ 3 5 (0=|/) 8 9 10 0 1 1 Here comes Raul for help with
>> his "first multiply, then add up" example 2 * 3 5 7 6 10
>> 14 2 +/ .* 3 5 7 30 This technique seems to work for anything
>> dyadic, e.g. if I replaced the "multipy" (*) with [third] "root"
>> (%:) I got 3 %: 2 3 4 1.25992 1.44225 1.5874 3 +/ .%: 2 3 4
>> 4.28957 As he (Raul) pointed out, if one replaces the "multiply"
>> with the "equal to zero comparison" one can rewrite thus 3 5 (0
>> +./ .=(|/)) 8 9 10 0 1 1 3 5 (0 +./ .=(|/8+i.)) 3 0 1 1 Going
>> back to the original example 3 5 (0 +./ .=(|/i.)) 20 1 0 0 1 0 1
>> 1 0 0 1 1 0 1 0 0 1 0 0 1 0 which I now understand a bit better,
>> reading from right to left, as - take the current index (i.), -
>> check the modulo result (|/), - compare with zero(0 .=), - OR the
>> table rows (+./) produced by the left vector (to get the result
>> vector). And this is a fairly general notation; playing around (this
>> is fun): 3 5 7 (0=(|/i.)) 25 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0
>> 1 0 0 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0
>> 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 3 5 7 (0 +./
>> .=(|/i.)) 25 1 0 0 1 0 1 1 1 0 1 1 0 1 0 1 1 0 0 1 0 1 1 0 0 1
>> Thanks for your patience ... -M At 2016-05-05 22:03, you wrote: > >
>> 3 5 (0 +./ .= (|/ i.)) 20 the ".=" is hard to read. Its >
>> equivalent to ". =" or in this case 3 5 (0 +./@:= (|/ i.)) 20
>> ----- > Original Message ----- From: Geoff Canyon
>> <[email protected]> To: > [email protected] Sent: Thursday,
>> May 5, 2016 5:54 PM > Subject: Re: [Jprogramming] Project Euler 1 So
>> there are a few > learning opportunities here -- euphemism for
>> things I don't > understand ;-) I get how adding 0 = transforms the
>> modulo results > into a 1 for "divisible" and 0 for "not
>> divisible": 3 5 (0 = > (|/ i.)) 20 1 0 0 1 0 0 1 0 0 1 0 0 1 0
>> 0 1 0 0 1 0 1 0 0 0 0 1 0 0 > 0 0 1 0 0 0 0 1 0 0 0 0 But I'm not
>> seeing how this combines those > results with an OR: 3 5 (0 +./ .=
>> (|/ i.)) 20 1 0 0 1 0 1 1 0 0 1 1 > 0 1 0 0 1 0 0 1 0 Maybe I'm just
>> not seeing how the forks/hooks > resolve themselves? I seem to
>> recall there was a command to get J > to box a command to show how
>> that flow works, but I don't remember > it. Or maybe that's not it
>> at all and I'm just confused. thx gc On > Wed, May 4, 2016 at 11:35
>> PM, Raul Miller <[email protected]> > wrote: > On Wed, May 4,
>> 2016 at 10:35 PM, Geoff Canyon > <[email protected]> wrote: > > So I
>> tried to write code to solve > the general case of Project Euler >
>> problem > > 1. The problem > given is to find the sum of all the
>> positive integers less > > than > 1000 that are divisible by 3 or 5.
>> Obviously the specific case > is > > highly optimizable. But I
>> wanted to solve the general, with > any number of > > divisors and
>> any upper limit. > > ... > > Here's > the code. As always, I suck at
>> J, so improvements/suggestions > are > > welcome. > > > > pe1 =:
>> +/@(([:i.]) * > 1&-@(0&i.)@*/"1@|:@(|"0 1 i.)) > > Maybe: > pe1=:
>> [:+/@I. 0 +./ > .= (|/ i.) > > ? > > Assuming email anti-spam bots
>> do not eat my > line for including an @ > character. Maybe,
>> instead: > > pe1=: > [:+/ [:I. 0 +./ .= (|/ i.) > > ... > > -- >
>> Raul > >
>> ----------------------------------------------------------------------
>>>> 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
>
>
>
> ------------------------------
>
> Message: 2
> Date: Fri, 6 May 2016 14:56:27 +0000 (UTC)
> From: "'Bo Jacoby' via Programming" <[email protected]>
> To: "[email protected]" <[email protected]>
> Subject: Re: [Jprogramming] divide if not zero
> Message-ID:
> <[email protected]>
> Content-Type: text/plain; charset=UTF-8
>
> x%y+y=0
>
>
> Den 3:37 fredag den 6. maj 2016 skrev Joe Bogner <[email protected]>:
>
>
>
>>> On 6 May 2016, at 10:53 AM, 'Pascal Jasmin' via Programming <
>> [email protected]> wrote:
>>>
>>> I would go with first version. What don't you like about it?
>
> Thanks - I don't particularly like using explicit rank. It also fails on
> the atom case
>
> It's also not particularly fast:
>
> 6!:2 '(?1e6#5) %^:(0~:])"0 (?1e6#5)'
>
> 0.703749
>
>
>
>
> On Thu, May 5, 2016 at 9:25 PM, Ric Sherlock <[email protected]> wrote:
>
>> How about:
>>
>> 3 2 4 (% * 0 ~: ]) 6 0 3
>>
>> 0.5 0 1.33333
>>
>>
>
> Nice!
>
> 6!:2 '(?1e6#5) (% * 0 ~: ]) (?1e6#5)'
>
> 0.0489602
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
>
>
>
> ------------------------------
>
> Message: 3
> Date: Fri, 6 May 2016 11:17:21 -0400
> From: Raul Miller <[email protected]>
> To: Programming forum <[email protected]>
> Subject: Re: [Jprogramming] Project Euler 1
> Message-ID:
> <CAD2jOU-AdsYZZhR=ms-iqr3chmsmgkhg1xfyubadzmlunp-...@mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> A1:
>
> This does what I think you want:
>
> (,2) (0 +./ .= (|/ i.)) 10
> 1 0 1 0 1 0 1 0 1 0
>
> I think it's reasonable to expect that the left argument always be a
> list (aka "a vector"). But, if you like, you could wrap this in code
> that guarantees vectorness. Since the rank of the right argument
> doesn't matter all that much, you could instead do it like this:
>
> (2) (0 +./ .= (|/ i.))&, 10
>
> Still... I would beware of overgeneralizing - unless you have specific
> reasons to go there, you often wind up with "solutions looking for
> problems" which then gets followed by "trying to find problems to fit
> the solutions" and before long you are out shaving yaks.
>
> Which, ok, might be a good thing if your yaks have been needing some
> grooming...
>
> A2:
>
> Try removing it..
>
> Or, if that's too crude of an answer, consider this:
>
> 9 ( - ) 3
> 6
>
> 9 ([: - ]) 3
> _3
>
> Basically, ] in a dyadic context is the right argument.
>
> 9 ( ] ) 3
> 3
>
> Combine this with trains (forks, mostly) and a ] in an odd position is
> sort of like the y argument and a [ in an odd position is sort of like
> the x argument.
>
> --
> Raul
>
> On Fri, May 6, 2016 at 10:11 AM, Martin Kreuzer <[email protected]> wrote:
>> In the effort of generalizing it more, I noticed that
>>
>> (3 5) (0 +./ .= (|/ i.)) 10
>> 1 0 0 1 0 1 1 0 0 1
>>
>> works fine, but collapses when only on divider is given
>>
>> (2) (0 +./ .= (|/ i.)) 10
>> 1
>>
>> (looks like the resulting vector being ORed).
>>
>> Q1:
>> Is there a possible twist to bring these two cases (one | more than one)
>> together..?
>>
>> In continuing toward solution to PE1 (generalized) I produced this line
>>
>> pe1g=. 13 : '+/ (i.y) * (x) (0 +./ .= (|/ i.)) y'
>>
>> which seems to deliver correct results
>>
>> (3 5) pe1g 10
>> 23
>> (3 5) pe1g 1000
>> 233168
>>
>> but still doesn't cover the special case:
>>
>> (2) pe1g 10
>> 45
>>
>> *~~~~~*
>>
>> Going tacid using the result of the "13 cheat"
>>
>> pe1g=. [: +/ ([: i. ]) * 0 +./ .= (|/ i.)
>>
>> I end up near, but not quite at Raul's 2nd suggestion
>>
>> pe1=: [:+/ [:I. 0 +./ .= (|/ i.)
>>
>> Q2:
>> Why is it, that sometimes the placeholder (]) is used to indicate the right
>> hand argument, and sometimes not..?
>>
>> If I put two of those (i.]) in my version (as was my first thought), I do
>> even get a wrong answer:
>>
>> pe1gf=. [: +/ ([: i. ]) * 0 +./ .= (|/ i.])
>> 3 5 pe1gf 10
>> 0
>>
>> *~~~~~*
>>
>> Progressing from
>>
>> (2) (0 = (|/ i.)) 10
>> 1 0 1 0 1 0 1 0 1 0
>>
>> to
>>
>> (I.) (2) (0 = (|/ i.)) 10
>> 0 2 4 6 8
>>
>> I now see how (I.) was used to compact it further by evaluating the bit mask
>> (instead of multiplying the elements). Neat.
>>
>> -M
>>
>>
>>
>> At 2016-05-06 08:43, you wrote:
>>>
>>> Let me add that, following this thread so far, I too learned a few things
>>> today - and pardon me for outlining the steps for further reference. I
>>> (again) did a very base level approach: 3 + 8 9 10 11 12 13 5 + 8 9
>>> 10 13 14 15 3 5 + 8 9 10 |length error | 3 5 +8 9 10 At that stage
>>> I realized that (/) isn't only "Insert" but also used to force a "Table":
>>> 3 5 +/ 8 9 10 11 12 13 13 14 15 These lines take the "Modulo" and, in a
>>> second step, throw a "1" for a match [division result zero], "0" otherwise):
>>> 3 5 |/ 8 9 10 2 0 1 3 4 0 3 5 (0=|/) 8 9 10 0 1 0 0 0 1 I then combined
>>> these results by ORing (+.) the two rows: +./ 3 5 (0=|/) 8 9 10 0 1 1
>>> Here comes Raul for help with his "first multiply, then add up" example
>>> 2 * 3 5 7 6 10 14 2 +/ .* 3 5 7 30 This technique seems to work for
>>> anything dyadic, e.g. if I replaced the "multipy" (*) with [third] "root"
>>> (%:) I got 3 %: 2 3 4 1.25992 1.44225 1.5874 3 +/ .%: 2 3 4 4.28957
>>> As he (Raul) pointed out, if one replaces the "multiply" with the "equal to
>>> zero comparison" one can rewrite thus 3 5 (0 +./ .=(|/)) 8 9 10 0 1 1
>>> 3 5 (0 +./ .=(|/8+i.)) 3 0 1 1 Going back to the original example 3 5 (0
>>> +./ .=(|/i.)) 20 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 0 0 1 0 which I now
>>> understand a bit better, reading from right to left, as - take the current
>>> index (i.), - check the modulo result (|/), - compare with zero(0 .=), - OR
>>> the table rows (+./) produced by the left vector (to get the result vector).
>>> And this is a fairly general notation; playing around (this is fun): 3 5
>>> 7 (0=(|/i.)) 25 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 1 0 0 0 0
>>> 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0
>>> 0 0 0 1 0 0 0 3 5 7 (0 +./ .=(|/i.)) 25 1 0 0 1 0 1 1 1 0 1 1 0 1 0 1 1
>>> 0 0 1 0 1 1 0 0 1 Thanks for your patience ... -M At 2016-05-05 22:03, you
>>> wrote: > > 3 5 (0 +./ .= (|/ i.)) 20 the ".=" is hard to read. Its >
>>> equivalent to ". =" or in this case 3 5 (0 +./@:= (|/ i.)) 20 ----- >
>>> Original Message ----- From: Geoff Canyon <[email protected]> To: >
>>> [email protected] Sent: Thursday, May 5, 2016 5:54 PM > Subject: Re:
>>> [Jprogramming] Project Euler 1 So there are a few > learning opportunities
>>> here -- euphemism for things I don't > understand ;-) I get how adding 0 =
>>> transforms the modulo results > into a 1 for "divisible" and 0 for "not
>>> divisible": 3 5 (0 = > (|/ i.)) 20 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0
>>> 1 0 1 0 0 0 0 1 0 0 > 0 0 1 0 0 0 0 1 0 0 0 0 But I'm not seeing how this
>>> combines those > results with an OR: 3 5 (0 +./ .= (|/ i.)) 20 1 0 0 1 0 1 1
>>> 0 0 1 1 > 0 1 0 0 1 0 0 1 0 Maybe I'm just not seeing how the forks/hooks >
>>> resolve themselves? I seem to recall there was a command to get J > to box a
>>> command to show how that flow works, but I don't remember > it. Or maybe
>>> that's not it at all and I'm just confused. thx gc On > Wed, May 4, 2016 at
>>> 11:35 PM, Raul Miller <[email protected]> > wrote: > On Wed, May 4, 2016
>>> at 10:35 PM, Geoff Canyon > <[email protected]> wrote: > > So I tried to
>>> write code to solve > the general case of Project Euler > problem > > 1. The
>>> problem > given is to find the sum of all the positive integers less > >
>>> than > 1000 that are divisible by 3 or 5. Obviously the specific case > is >
>>>> highly optimizable. But I wanted to solve the general, with > any number
>>> of > > divisors and any upper limit. > > ... > > Here's > the code. As
>>> always, I suck at J, so improvements/suggestions > are > > welcome. > > > >
>>> pe1 =: +/@(([:i.]) * > 1&-@(0&i.)@*/"1@|:@(|"0 1 i.)) > > Maybe: > pe1=:
>>> [:+/@I. 0 +./ > .= (|/ i.) > > ? > > Assuming email anti-spam bots do not
>>> eat my > line for including an @ > character. Maybe, instead: > > pe1=: >
>>> [:+/ [:I. 0 +./ .= (|/ i.) > > ... > > -- > Raul > >
>>> ---------------------------------------------------------------------- > >
>>> 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
>
>
> ------------------------------
>
> Message: 4
> Date: Fri, 6 May 2016 12:03:15 -0400
> From: Geoff Canyon <[email protected]>
> To: [email protected]
> Subject: Re: [Jprogramming] Project Euler 1
> Message-ID:
> <cakclktq1qkajnffzu74herpatavelwd5hfrar6-cywvjazs...@mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Fri, May 6, 2016 at 4:43 AM, Martin Kreuzer <[email protected]> wrote:
>
>> At that stage I realized that (/) isn't only "Insert" but also used to
>> force a "Table":
>>
>
> Yep, this was new to me as well, as evidenced by my original awkward |"0 1
> construction.
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
> ------------------------------
>
> End of Programming Digest, Vol 128, Issue 16
> ********************************************
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm