Geoff,

thanks for such a fun little problem.

I know you have a complete solution - but I still wanted to investigate if it could be done any faster.

The main constraint to take advantage of is that, although the sum of the primes needs to be an arbitrarily large number and use 'bigmath', the individual primes must fit within a normal LC number.

Therefore, we can use a running sub-total, and only when that approaches the upper limit of a normal integer add that to the overall total (with bigMath).

So something like  (changed lines marked with "|")

   repeat with C = 1 to 999999999999
      read from file fPath for 1 line
      if it > fld 1 then exit repeat
|      add char 1 to -2 of it to subtotal
|      if subtotal > 999999999999 then   -- that's 12 of them :=-)
|         put bAdd2(T,subtotal) into T
|         put 0 into subtotal
|      end if
      if the seconds > S then
         put the seconds + 1 into S
         put T && it && C into fld 2
         unlock screen
         lock screen
      end if
   end repeat
|   put bAdd2(T,subtotal) into T
   put T && it && C - 1 into fld 2


I didn't have a list of primes on hand, so I used a synthetic little benchmark using random large numbers, and got a speed-up of between 50x and 100x. I suspect the benfit in the real case would be towards the lower end of that range, if my guess about magnitude of the primes is correct.


We could also replace 'bAdd' with 'bAddSmall' which takes one arbitrarily large number and one normal LC number and adds them; I would guess this would give at most 5-10% improvement, so I haven't bothered actually trying it :-)

-- Alex.

On 12/11/2015 06:26, Geoff Canyon wrote:
I re-wrote the algorithm a bit to tweak for speed, then ran it successfully
for primes up to 3 billion (a couple hours), and got the wrong answer
because my big addition function was broken :-/

So I broke the problem in two: first generate the list of primes, then do
the addition.

For the primes I generated the list up to 100,000, stored that, and then
used a simpler (by one command) routine to generate the primes to 10
billion in a few hours. Here's that:

on mouseUp
    put the long seconds into ST
    repeat for each line i in line 2 to -1 of the primeList of this stack
       put 2*i & comma after P[i^2]
    end repeat
    put 2 into pList
    put fld "path" into fPath
    open file fPath for write
    put 0 into S
    put fld 1 into endPoint
    if endPoint mod 2 = 0 then subtract 1 from endPoint
    repeat with i = 3 to endPoint step 2
       if P[i] is empty then
          put cr & i after pList
       else
          repeat for each item x in P[i]
             put x & comma after P[i + x]
          end repeat
       end if
       if the seconds > S then
          put the seconds + 5 into S
          put i into fld 2
          write pList to file fPath
          put empty into pList
          unlock screen
          lock screen
       end if
       delete variable P[i]
    end repeat
    put i into fld 2
    write pList to file fPath
    close file fPath
    put the long seconds - ST
end mouseUp

That's ~5gb of primes...

Then I re-wrote the addition function to use a simpler, slower method,
tested it, and let it go. An hour or so later, and I had my answer
(validated against the site with the challenge). If anyone sees the problem
with bAdd, I'm all ears. I didn't look too closely, since I just wanted to
get the code running to solve the problem. It works for all the test cases
I tried, but it seems to fail on the boundary between 14 and 15 digit
numbers.


on mouseUp
    put fld "path" into fPath
    open file fPath for read
    put 0 into T
    put 0 into S
    repeat with C = 1 to 999999999999
       read from file fPath for 1 line
       if it > fld 1 then exit repeat
       put bAdd2(T,char 1 to -2 of it) into T
       if the seconds > S then
          put the seconds + 1 into S
          put T && it && C into fld 2
          unlock screen
          lock screen
       end if
    end repeat
    put T && it && C - 1 into fld 2
    close file fPath
end mouseUp

function bAdd x,y
    put 0 into c
    repeat with i = 14 to max(length(x),length(y)) step 14
       add char -i to 13 - i of x + char -i to 13 - i of y to c
       put char -14 to -1 of c before r
       delete char -14 to -1 of c
    end repeat
    return c & r
end bAdd

function bAdd2 x,y
    put 0 into c
    repeat with i = 1 to max(length(x),length(y))
       put char -i of x + char -i of y + c into c
       put char -1 of c before r
       delete char -1 of c
    end repeat
    return c & r
end bAdd2
_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to