common-lisp - 将列表理解转换为 Common Lisp 循环

标签 common-lisp collatz

我最近开始学习 lisp。像许多其他人一样,我正在尝试解决 Project Euler 问题,但是我有点卡在 Problem 14 上。 : 最长的 Collat​​z 序列。

这是我到目前为止:

(defun collatz (x)
  (if (evenp x) 
      (/ x 2)
      (+ (* x 3) 1)))

(defun collatz-sequence (x)
  (let ((count 1))
    (loop
     (setq x (collatz x))
       (incf count)
       (when (= x 1)
     (return count)))))

(defun result ()
  (loop for i from 1 to 1000000 maximize (collatz-sequence i)))

这将正确打印最长序列 (525),但不会打印生成最长序列的数字。

我想要的是
result = maximum  [ (collatz-sequence n, n) | n <- [1..999999]]

如果可能,翻译成 Common Lisp。

最佳答案

在宏的帮助下并使用 iterate库,它允许您扩展其 loop -like 宏,你可以做如下的事情:

(defun collatz (x)
  (if (evenp x) (floor x 2) (1+ (* x 3))))

(defun collatz-path (x)
  (1+ (iter:iter (iter:counting (setq x (collatz x))) (iter:until (= x 1)))))

(defmacro maximizing-for (maximized-expression into (cause result))
  (assert (eq 'into into) (into) "~S must be a symbol" into)
  `(progn
     (iter:with ,result = 0)
     (iter:reducing ,maximized-expression by
      (lambda (so-far candidate)
        (if (> candidate so-far)
            (progn (setf ,result i) candidate) so-far)) into ,cause)))

(defun euler-14 ()
  (iter:iter
    (iter:for i from 1000000 downto 1)
    (maximizing-for (collatz-path i) into (path result))
    (iter:finally (return (values result path)))))

(在不要求一般性的情况下提出。:))

关于common-lisp - 将列表理解转换为 Common Lisp 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16251608/

相关文章:

python - 将某种类型的 0 添加到局部变量时,Numba 抖动会改变结果

lisp - 申请#' or not to apply #'

list - 如何在 Common Lisp 中从现有列表中设置某些内容

loops - 在 Lisp 中附加到 "loop-collect"的结果

c - main 函数不调用 collat​​zSequencer 函数

python反Collat​​z猜想

list - 在 Lisp 中,如何将给定元素添加到给定列表中的每个列表中?

package - 全局声明特殊空间时违反了对包 COMMON-LISP 的锁定

python - R 中的 Collat​​z 猜想

java - 用java解决3n+1