See

http://code.jsoftware.com/wiki/Vocabulary/SpecialCombinations#Assignments_In_Place_.28AIP.29

a=: (b~:0)}a,:a%b

is not in-place because it doesn't match the template.  In fact, it isn't 
handled by special code at all, see

http://code.jsoftware.com/wiki/Vocabulary/SpecialCombinations#Selections

To get the fast code you must have only names, not expressions:

a =: c}a,:b

Henry Rich


On 5/6/2016 6:56 PM, Louis de Forcrand wrote:
(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

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

Reply via email to