Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 23 |
Nodes: | 6 (0 / 6) |
Uptime: | 52:40:59 |
Calls: | 583 |
Files: | 1,139 |
D/L today: |
179 files (27,921K bytes) |
Messages: | 111,617 |
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))
(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.