[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
## Re: guile style

**From**: |
Tim Van den Langenbergh |

**Subject**: |
Re: guile style |

**Date**: |
Sat, 19 Jun 2021 12:25:13 +0200 |

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