Task

The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below n.

Show output for n = 1000.

This is is the same as Project Euler problem 1.

Extra credit: do this efficiently for n = 1e20 or higher.




/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 40
 
runSample(arg)
return
 
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method summing(maxLimit = 1000) public static
  mult = 0
  loop mv = 0 while mv < maxLimit
    if mv // 3 = 0 | mv // 5 = 0 then
      mult = mult + mv
    end mv
  return mult
 
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- translation of Raku
method sum_mults(first, limit) public static
  last = limit - 1
  last = last - last // first
  sum = (last / first) * (first + last) % 2
  return sum
 
method sum35(maxLimit) public static
  return sum_mults(3, maxLimit) + sum_mults(5, maxLimit) - sum_mults(15, maxLimit)
 
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
 
  offset = 30
  incr = 10
 
  say 'Limit'.right(offset) || '|' || 'Sum'
  say '-'.copies(offset)    || '+' || '-'.copies(60)
  timing = System.nanoTime
  sum = summing()
  timing = System.nanoTime - timing
  say 1000.format.right(offset)'|'sum
  say 'Elapsed time:' Rexx(timing * 1e-9).format(4, 6)'s'
  say
 
  say 'Limit'.right(offset) || '|' || 'Sum'
  say '-'.copies(offset)    || '+' || '-'.copies(60)
  tmax = 1e+6
  timing = System.nanoTime
  mm = 1
  loop while mm <= tmax
    say mm.right(offset)'|'summing(mm)
    mm = mm * incr
    end
  timing = System.nanoTime - timing
  say 'Elapsed time:' Rexx(timing * 1e-9).format(4, 6)'s'
  say
 
  say 'Limit'.right(offset) || '|' || 'Sum'
  say '-'.copies(offset)    || '+' || '-'.copies(60)
  timing = System.nanoTime
  sum = sum35(1000)
  timing = System.nanoTime - timing
  say 1000.format.right(offset)'|'sum
  say 'Elapsed time:' Rexx(timing * 1e-9).format(4, 6)'s'
  say
 
  say 'Limit'.right(offset) || '|' || 'Sum'
  say '-'.copies(offset)    || '+' || '-'.copies(60)
  tmax = 1e+27
  timing = System.nanoTime
  mm = 1
  loop while mm <= tmax
    say mm.right(offset)'|'sum35(mm)
    mm = mm * incr
    end
  timing = System.nanoTime - timing
  say 'Elapsed time:' Rexx(timing * 1e-9).format(4, 6)'s'
  say
  return
 