Scheme 计划中的约瑟夫

Scheme 计划中的约瑟夫,scheme,josephus,Scheme,Josephus,约瑟夫斯问题的这一实现有哪些不足之处?对于那些不熟悉约瑟夫斯问题的人来说,目标是从循环链接列表中删除每三个条目,直到只剩下一个条目。在本例中,我删除了每个“mth”值 (定义(joseph lst) (let((m(+1(随机长度lstЮЮ))) (定义(joseph-h i xlst mlst) (cond)(通过创建一个列表并从中删除元素(“杀死”人),您对算法的理解过于字面化。一个更简单的解决方案是使用算术运算对问题进行建模,下面是一个可能的实现,它改编自我自己的: 例如,要查看在杀死每三

约瑟夫斯问题的这一实现有哪些不足之处?对于那些不熟悉约瑟夫斯问题的人来说,目标是从循环链接列表中删除每三个条目,直到只剩下一个条目。在本例中,我删除了每个“mth”值

(定义(joseph lst)
(let((m(+1(随机长度lstЮЮ)))
(定义(joseph-h i xlst mlst)

(cond)(通过创建一个列表并从中删除元素(“杀死”人),您对算法的理解过于字面化。一个更简单的解决方案是使用算术运算对问题进行建模,下面是一个可能的实现,它改编自我自己的:

例如,要查看在杀死每三个人后列表中幸存的位置(1 2 3 4 5 6 7)
,请执行以下操作:

(joseph 7 3)
=> 4
Wikipedia提供了一个有趣的关于这个问题可能的解决方案,我的解决方案在将其转换为尾部递归后,对所示的简单python函数进行了调整。

我在中给出了三个解决方案。最字面的版本以m为单位从n个项目的列表中删除,将列表表示为循环列表:

(define (cycle xs)
  (set-cdr! (last-pair xs) xs) xs)

(define (josephus3 n m)
  (let loop ((k (- m 1)) (alive (cycle (range 0 n))) (dead '()))
    (cond ((= (car alive) (cadr alive))
            (reverse (cons (car alive) dead)))
          ((= k 1)
            (let ((dead (cons (cadr alive) dead)))
              (set-cdr! alive (cddr alive))
              (loop (- m 1) (cdr alive) dead)))
这是通过从
活动
列表中实际删除被杀死的元素并将它们放置在
列表中来执行删除操作的。
范围
函数来自my;它返回从0到
n-1的整数:

(define (range first past . step)
  (let* ((xs '()) (f first) (p past)
         (s (cond ((pair? step) (car step))
                  ((< f p) 1) (else -1)))
         (le? (if (< 0 s) <= >=)))
    (do ((x f (+ x s))) ((le? p x) (reverse xs))
      (set! xs (cons x xs)))))
(定义(范围第一步)
(让*((xs’())(f先)(p过去)
(秒)(成对台阶)(轿厢台阶))
((
最初的约瑟夫斯问题在3步中杀死了41人,剩下31人作为幸存者,从1开始计算:

(约瑟夫斯3413) (2 5 8 11 14 17 20 23 26 29 32 35 38 0 4 9 13 18 22 27 31 36 4061219253339716283710412133430)


您可能还喜欢上的其他两个版本。

Darn,这个解决方案简单多了。很酷,我来看看。
(define (cycle xs)
  (set-cdr! (last-pair xs) xs) xs)

(define (josephus3 n m)
  (let loop ((k (- m 1)) (alive (cycle (range 0 n))) (dead '()))
    (cond ((= (car alive) (cadr alive))
            (reverse (cons (car alive) dead)))
          ((= k 1)
            (let ((dead (cons (cadr alive) dead)))
              (set-cdr! alive (cddr alive))
              (loop (- m 1) (cdr alive) dead)))
(define (range first past . step)
  (let* ((xs '()) (f first) (p past)
         (s (cond ((pair? step) (car step))
                  ((< f p) 1) (else -1)))
         (le? (if (< 0 s) <= >=)))
    (do ((x f (+ x s))) ((le? p x) (reverse xs))
      (set! xs (cons x xs)))))