var sum



: projecteuler1

0 sum !

1

repeat

dup 3 mod 0 n:= if

dup

sum n:+!

else

dup 5 mod 0 n:= if

dup

sum n:+!

then

then

n:1+

dup 1000 n:< while!

drop sum @ ;



projecteuler1 . cr

bye

use of a 'var' when one could have used the stack

manual counted looping instead of using loop

repetition of code fragments without factorization

with: n

: sum-multiples \ sum x -- sum'

dup 3 mod 0 =

over 5 mod 0 = or

if + else drop then ;



0 ' sum-multiples 3 999 loop . cr bye

with: n

: div? \ n m -- f

mod not ;



: sum-multiples \ sum x -- sum'

dup 3 div?

over 5 div? or

if + else drop then ;



0 ' sum-multiples 3 999 loop . cr bye

with: n

: div? \ n m -- f

mod not ;



: sum-multiples \ sum x -- sum'

dup 3 div?

over 5 div? or

if + else drop then ;



: push

t:parent swap t:push ;



( 0 ' sum-multiples 3 500 loop push ) t:task

( 0 ' sum-multiples 501 999 loop push ) t:task

2 a:close t:wait

t:pop t:pop n:+ . cr bye

\ create an array of [3..999]

' noop 3 999 a:generate



\ remove non-multiples

( dup 3 mod 0 = swap 5 mod 0 = or ) a:filter



\ sum the remaining values

' n:+ 0 a:reduce

. cr bye

1a: 1.871 sec

1b: 1.595 sec

1c: 1.426 sec

1d: 1.080 sec

1e: 2.268 sec

A new 8th user struggled to come up with a solution to the Project Euler problem #1 , being unaware of the existence of counted loops in 8th. The solution this person gave (1a.8th) is:Not bad code (especially since "it works"), but there are a few issues one should note:As I said, none of these are terrible. But we can do quite a bit better. The code in samples/euler/1.8th is (1b.8th):This is much more compact, and uses the stack rather than a var. It can be improved by factoring (1c.8th):Perhaps it makes sense to use multiple tasks? The code becomes more complex (1d.8th):And what happens if we are quite lazy? (1e.8th):The timings are informative. I had to increase the upper limit significantly to get good timings, so rather than numbers below 1000, I timed how long it took to sum them below 10000000:I'm actually surprised that 1e didn't take a lot longer, since it's allocating an array with 10000000 numbers in it; but overall, the results were very much in line with what I expected. Less var access is good. More factorizing is (usually) good. Multiple tasks is good if the problem can be decomposed in parallel. And all in all, performance is not bad at all, even with "naive" code.