patternMinor
Project Euler 1 (sum of multiples of 3 or 5 under 1000)
Viewed 0 times
underprojectmultipleseuler1000sum
Problem
I solved this a while ago. In the moment I solved it I was learning Scheme and, well, I still am. I'm not looking at the best solution (I searched for it and coded it already, in Python), what I want is to improve this code, maintaining the same (brute) approach, so I can learn some best practices and tips in Scheme. Maybe there are some suggestions on how I wrote the routines, for example.
#lang racket
(define (check x) (or (= (modulo x 3) 0)
(= (modulo x 5) 0)))
(define (count-check x) (if (check x)
x
0))
(define (sum-multiples-rec actual limit acc) (if (< actual limit)
(sum-multiples-rec (+ actual 1) limit (+ (count-check actual) acc))
acc))
(define (sum-multiples lower-limit upper-limit) (sum-multiples-rec lower-limit upper-limit 0))
(sum-multiples 0 1000)Solution
So, any time you want to write a "helper" recursive function, the standard way to write that is to use a named
Named
(I've taken the liberty of using
Here's a version that's even more Rackety, using
let. So here's how I might restructure your program (but keeping the same algorithm):(define (sum-multiples start end)
(let loop ((sum 0)
(i start))
(cond ((>= i end) sum)
((or (zero? (modulo i 3))
(zero? (modulo i 5)))
(loop (+ sum i) (add1 i)))
(else (loop sum (add1 i))))))Named
let is a macro, which in this case expands to the same expression as:(define (sum-multiples start end)
((letrec ((loop (lambda (sum i)
(cond ((>= i end) sum)
((or (zero? (modulo i 3))
(zero? (modulo i 5)))
(loop (+ sum i) (add1 i)))
(else (loop sum (add1 i)))))))
loop)
0 start))(I've taken the liberty of using
(add1 i) instead of (+ i 1) since you're using Racket.)Here's a version that's even more Rackety, using
for/sum to accumulate the sum rather than using a manual loop:(define (sum-multiples start end)
(for/sum ((i (range start end)))
(if (or (zero? (modulo i 3))
(zero? (modulo i 5)))
i 0)))Code Snippets
(define (sum-multiples start end)
(let loop ((sum 0)
(i start))
(cond ((>= i end) sum)
((or (zero? (modulo i 3))
(zero? (modulo i 5)))
(loop (+ sum i) (add1 i)))
(else (loop sum (add1 i))))))(define (sum-multiples start end)
((letrec ((loop (lambda (sum i)
(cond ((>= i end) sum)
((or (zero? (modulo i 3))
(zero? (modulo i 5)))
(loop (+ sum i) (add1 i)))
(else (loop sum (add1 i)))))))
loop)
0 start))(define (sum-multiples start end)
(for/sum ((i (range start end)))
(if (or (zero? (modulo i 3))
(zero? (modulo i 5)))
i 0)))Context
StackExchange Code Review Q#46379, answer score: 6
Revisions (0)
No revisions yet.