| Deutsch English Français Italiano |
|
<87o76lcomw.fsf@nightsong.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Paul Rubin <no.email@nospam.invalid>
Newsgroups: comp.lang.lisp
Subject: Re: Euler 14.
Date: Thu, 25 Jul 2024 11:28:23 -0700
Organization: A noiseless patient Spider
Lines: 38
Message-ID: <87o76lcomw.fsf@nightsong.com>
References: <v34fp4$iunh$1@dont-email.me> <v7p00g$1b339$3@dont-email.me>
<87h6cf9711.fsf@nightsong.com>
MIME-Version: 1.0
Content-Type: text/plain
Injection-Date: Thu, 25 Jul 2024 20:28:24 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="a89df0e331107fdc444e94bb37ae2dd9";
logging-data="2528263"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+pvXPG737bt6q1LyGBfaC5"
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux)
Cancel-Lock: sha1:qUnRcHnl1aDP8wwihn2pBzZx/IY=
sha1:+JMB9qrp99OJMRL7YK5+ebh2+lA=
Bytes: 2287
Paul Rubin <no.email@nospam.invalid> writes:
> It is problem 14 of projecteuler.net .
Here is my solution, maybe not idiomatic CL since I don't write much of
that these days. It takes about 0.17 sec of user time on my laptop
using sbcl --script, or 1.1 sec with compiled clisp. It doesn't work
with interpreted clisp because the clisp interpreter has no TRO and so
the tail recursion overflows the stack. I could rewrite it iteratively
but nah. A similar C++ version with gcc -O3 takes about 0.03 sec. I
haven't experimented with changing the size of the memo table or
anything like that.
================================================================
(defun collatz (n)
(cond ((oddp n) (1+ (* 3 n)))
(t (floor n 2))))
(defvar memo (make-array 1000000 :initial-element nil))
(defun clen (n)
(cond ((= n 1) 1)
((<= n 0) 'crash)
((and (< n (length memo)) (aref memo n)) (aref memo n))
(t (let ((a (1+ (clen (collatz n)))))
(if (< n (length memo))
(setf (aref memo n) a))
a))))
(defun run (&optional (n 1) (mi 0) (ma 0))
(if (> n 1000000)
(list mi ma)
(let ((a (clen n))
(nn (1+ n)))
(if (> a ma)
(run nn n a)
(run nn mi ma)))))
(print (run))
(terpri)