> 4) So is there a better d verb out there - capable of running efficiently
> on a vector argument? (Or a p: or q: extension as per 0 above?)
Having thought about it for 10 seconds, I would say that for a vector
argument indicating a range of numbers (e.g. from 0 to 1-n), a sieve-like
method should do well:
count=: n{.1 1 1
find the index of the next non-zero entry j in count
if j is >: %: n end loop
count[k*i.j]=: >: count[k+i.j] [ k=. <.n%j NB. ***
at the end of the loop handle the remaining 0 entries in count (they are
primes).
*** interesting mix of notation there :-)
On Tue, Oct 21, 2014 at 11:54 AM, Mike Day <[email protected]>
wrote:
> No takers to the previous posting (below)?
>
> 0) Pari GP has a built-in function for number of divisors;
> J doesn't, although it seems a nice candidate for an extension of p: or
> q:
>
> 1) My fairly crude Pari GP function to solve this problem runs faster than
> the slightly more elegant although admittedly brute-force J verb(s).
> The Pari GP solution for the actual Project Euler problem 485 took
> just under 7 minutes, and is correct, so optimisation isn't really
> required.
> I've just received a J solution after 1 hour 20 minutes, also correct.
> Both run in interactive mode.
>
> 2) I did have a go at optimising the GP Pari, using a count array of
> d-values in the current window (of size 100 000 in the actual problem);
> that array can be considerably smaller than 100 000; I messed around
> with forward and backward pointers but it was slower, and buggy.
>
> 3) Running a smaller problem under jpm suggests that the bottleneck
> is the d (number of divisors) verb.
> S 1e6 1e4 takes about 6.5 seconds of which 6 seconds is spent in "d".
>
> 4) So is there a better d verb out there - capable of running efficiently
> on a vector argument? (Or a p: or q: extension as per 0 above?)
>
> Thanks,
>
> Mike
>
>
> On 20/10/2014 15:26, Mike Day wrote:
>
>> NB. Maximum number of divisors
>>
>> NB. Problem 485
>>
>> NB. Published on Saturday, 18th October 2014, 04:00 pm
>>
>> NB. Let d(n) be the number of divisors of n.
>>
>> NB. Let M(n,k) be the maximum value of d(j) for n ≤ j ≤ n+k-1.
>>
>> NB. Let S(u,k) be the sum of M(n,k) for 1 ≤ n ≤ u-k+1.
>>
>> NB.
>>
>> NB. You are given that S(1000,10)=17176.
>>
>> NB.
>>
>> NB. Find S(100 000 000,100 000).
>>
>>
>> NB. A brute-force J method:
>> d =: */@:(>:@{:)"2@(__&q:)
>>
>>
>> S =: +/@:(>./\ d@>:@i.)~/
>>
>>
>> timer'S 1000000 1000' NB. NOT the published problem!
>>
>> +-----+---------+
>>
>> |7.769|140671058|
>>
>> +-----+---------+
>>
>> timer'S 1000000 10000'
>>
>> +-----+---------+
>>
>> |7.147|175757800|
>>
>> +-----+---------+
>>
>>
>> These are faster in a pedestrian Pari GP script,
>> but it does use the built-in function, "numdiv":
>>
>>
>> (08:10) gp > S(1000000,1000)
>> time = 3,302 ms.
>> %5 = 140671058
>>
>>
>> (15:13) gp > S(1000000,10000)
>> time = 2,889 ms.
>> %6 = 175757800
>>
>>
>> Curious.
>>
>> Mike
>>
>>
>> PS The Pari script:
>>
>> S(u,k)= {
>> rv=vector(k,i,numdiv(i)); \\ rolling vector of "d" values
>> t=vecmax(rv);curmx=t;
>> ipos=0;
>> for(n= k+1, u,
>> oldrvi=rv[ipos+1];
>> newrvi=numdiv(n);
>> rvi=rv[ipos+1]=newrvi;
>> if(curmx<rvi, curmx=rvi,
>> if(oldrvi==curmx,curmx=vecmax(rv));
>> );
>> t+=curmx;
>> ipos=(1+ipos)%k;
>> );
>> t;
>> }
>>
>>
>>
>>
>>
>
> ---
> This email is free from viruses and malware because avast! Antivirus
> protection is active.
> http://www.avast.com
>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2014.0.4765 / Virus Database: 4040/8428 - Release Date: 10/21/14
>
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm