fork download
  1. ;; For loops for integer ranges and lists. (1.01)
  2.  
  3. (use-modules (srfi srfi-1))
  4.  
  5. (define-syntax for
  6. (syntax-rules (in .. .= by)
  7. ;; Integer range exclusive by step.
  8. ((for index in start .. end by step body ...)
  9. (let* ((count (max (ceiling-quotient (- end start) step) 0))
  10. (final (+ start (* count step))))
  11. (do ((index start (+ index step)))
  12. ((= index final))
  13. body ...)))
  14. ;; Integer range inclusive by step.
  15. ((for index in start .= end by step body ...)
  16. (for index in start .. ((if (negative? step) - +) end 1) by step
  17. body ...))
  18. ;; Integer range exclusive default step.
  19. ((for index in start .. end body ...)
  20. (for index in start .. end by 1
  21. body ...))
  22. ;; Integer range inclusive default step.
  23. ((for index in start .= end body ...)
  24. (for index in start .= end by 1
  25. body ...))
  26. ;; Iterate over a list.
  27. ((for item in list body ...)
  28. (for-each (lambda (item)
  29. body ...)
  30. list))))
  31.  
  32. ;; Main.
  33.  
  34. (define (print-range start end step)
  35. (for i in start .. end by step
  36. (format #t "~A " i))
  37. (newline)
  38. (for i in start .= end by step
  39. (format #t "~A " i))
  40. (newline)
  41. (let ((n (max (ceiling-quotient (- end start) step) 0)))
  42. (for i in (iota n start step)
  43. (format #t "~A " i)))
  44. (newline))
  45.  
  46. (print-range 1 5 1)
  47. (print-range 1 11 2)
  48. (print-range -11 -1 2)
  49. (print-range 5 1 -1)
  50. (print-range 11 1 -2)
  51. (print-range -1 -11 -2)
  52.  
  53. ;; Nested default step.
  54.  
  55. (define (pythagorean-triples n)
  56. (define (primitive-pythagorean-triple? x y z)
  57. (and (< x y z)
  58. (= (+ (* x x) (* y y)) (* z z))
  59. (= (gcd x y z) 1)))
  60. (let ((result '()))
  61. (for x in 1 .= n
  62. (for y in (+ x 1) .= n
  63. (for z in (+ y 1) .= n
  64. (when (primitive-pythagorean-triple? x y z)
  65. (set! result (cons (list x y z) result))))))
  66. (sort result (lambda (x y) (< (third x) (third y))))))
  67.  
  68. (display (pythagorean-triples 37))
  69. (newline)
Success #stdin #stdout 0.04s 12200KB
stdin
Standard input is empty
stdout
1 2 3 4 
1 2 3 4 5 
1 2 3 4 
1 3 5 7 9 
1 3 5 7 9 11 
1 3 5 7 9 
-11 -9 -7 -5 -3 
-11 -9 -7 -5 -3 -1 
-11 -9 -7 -5 -3 
5 4 3 2 
5 4 3 2 1 
5 4 3 2 
11 9 7 5 3 
11 9 7 5 3 1 
11 9 7 5 3 
-1 -3 -5 -7 -9 
-1 -3 -5 -7 -9 -11 
-1 -3 -5 -7 -9 
((3 4 5) (5 12 13) (8 15 17) (7 24 25) (20 21 29) (12 35 37))