On Saturday, 19 June 2021 02:55:34 CEST jerry wrote: > I am fairly new to guile and scheme. People tell me that I should use a > functional style. > > I have 3 solutions for project euler problem #1. The first is > functional, the second is imperative and the third is written in "Little > Schemer" style. > > I was hoping other guile users would comment on preferences or the > "correct way". Sorry in advance for any wrapping problems that may occur. > > #!/usr/local/bin/guile -s > !# > (use-modules (srfi srfi-1) (jpd stdio)) ;; for folds > (define N 1000) > > (define ans > (fold + 0 > (filter > (lambda (x) (or (= 0 (modulo x 3)) (= 0 (modulo x 5)))) > (iota N)))) > (print ans) > > (define ans 0) > (for i N > (if (or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (set! ans (+ ans i)))) > (print ans) > > (define ans > (let loop ((i 1) (ans 0)) > (cond > ((>= i N) ans) > ((or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (loop (1+ i) (+ ans i))) > (else (loop (1+ i) ans)) )))
I'm not 100% sure about how Guile does it, but I know that some Scheme implementations do some boxing for set! operations, which will make the second variation poorly optimised. Personally I would use combine the first and third answers by doing the divisible-by check during the fold, like this: (use-modules (srfi srfi-1)) (define (divisible-by? divident divisor) ~~(zero? (modulo divident divisor))) (define N 1000) (define ans ~~(fold (lambda (i res) ~~~~~~~~~~(if (or (divisible-by? i 3) ~~~~~~~~~~~~~~~~~~(divisible-by? i 5)) ~~~~~~~~~~~~(+ i res) ~~~~~~~~~~~~res)) ~~~~~~~~0 ~~~~~~~~(iota N))) Vale, -Tim