From Newsgroup: comp.lang.lisp
Wolfram Fenske wrote:
Jon Harrop writes:
Chris Russell wrote:
(defun pythagorean-triplet()
(let ((c2-b2 0) (a 0) (i 0))
(loop for c from 2 to 5000 do
(loop for b from 1 below c do
(progn
(setf c2-b2 (- (* c c) (* b b))
a (isqrt c2-b2))
(when (= c2-b2 (* a a))
(incf i)))))
(print i)))
I think this is the only Lisp posted so far that gives the same answer as the original program. As far as timings, I get:
OCaml: 0.341s
C: 0.384s
Lisp: 9.233s
For some reason ISQRT seems to be very slow. Replacing
(isqrt c2-b2)
with
(truncate (sqrt c2-b2))
brings down the runtime on my computer from 9.000s to 0.734s, while
still yielding the same result (11362, right?). Here it is in full:
--8<---------------cut here---------------start------------->8---
(defun pythagorean-triplet ()
(let ((c2-b2 0) (a 0) (i 0))
(loop for c from 2 to 5000 do
(loop for b from 1 below c do
(progn
(setf c2-b2 (- (* c c) (* b b))
;;a (isqrt c2-b2)
a (truncate (sqrt c2-b2)))
(when (= c2-b2 (* a a))
No need to truncate and square a. Just see if it is an integer.
(incf i)))))
(print i)))
--8<---------------cut here---------------end--------------->8---
As has been mentioned, this solution allocates a lot of memory,
ca. 100 MB using SBCL 1.0.5. If that could be eliminated, I assume
it'd be as fast as the C or OCaml versions. Unfortunately I don't
know enough about CL optimization to do this. None of the type
declarations I tried had any effect.
Gauche Scheme
(use srfi-42) ;; sum-ec
(define (pythagorean-triplet)
(print
(sum-ec (:range c 2 1000)
(:range b 1 c)
(:let c2-b2 (- (* c c) (* b b)))
(if (integer? (sqrt c2-b2)))
1)))
1756
Using "do".
(define (pythagorean-triplet)
(define (py? b c) (integer? (sqrt (- (* c c) (* b b)))))
(do ((c 2 (+ 1 c))
(i 0 (+ i (do ((b 1 (+ 1 b))
(i 0 (+ i (if (py? b c) 1 0))))
((= b c) i)))))
((> c 999) i)))
--
[T]he problem is that lispniks are as cultish as any other devout group and basically fall down frothing at the mouth if they see [heterodoxy].
--- Kenny Tilton
The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- Synchronet 3.21a-Linux NewsLink 1.2