0

如果我的输入是一个列表列表,那么我想输出一个包含输入元素的列表,以便它们像一副扑克牌一样被洗牌。

例如,如果输入是'((1 2 3) (4 5)),那么我希望输出显示为'(1 4 2 5 3)。

我的想法是首先从列表中的第一个列表中删除一个元素,然后将该列表的列表移动到列表的后面。这样,可以附加列表的下一个列表的第一个元素。

到目前为止,这是我的代码:

(define (shuffle ls)
   (if (null? ls) '()
       (cond ((null? car (ls)) (append (cdr (ls)) (list (cdr(car(ls)))))))
             (else (car (car (ls)))
                   (append (cdr (ls)) (list (cdr (car (ls))))
                   (shuffle (cdr (ls)))))))
4

2 回答 2

1

[这里的所有代码片段都需要先加载SRFI 1。 ]

您似乎想要的是压缩列表:

> (zip '(1 2 3) '(4 5))
((1 4) (2 5))

但是,如您所见,当它到达最短列表的末尾时,它会停止。也许您可以编写一个自定义 zip,它会在所有元素用完后停止:

(define (my-zip l1 l2)
  (cond ((and (null? l1) (null? l2)) '())
        ((null? l1) (cons (car l2) (my-zip l1 (cdr l2))))
        ((null? l2) (cons (car l1) (my-zip (cdr l1) l2)))
        (else (cons* (car l1) (car l2) (my-zip (cdr l1) (cdr l2))))))

让我们试试吧!

> (my-zip '(1 2 3) '(4 5))
(1 4 2 5 3)
> (my-zip '(1 2 3) '(4 5 6 7))
(1 4 2 5 3 6 7)
于 2012-09-13T20:33:10.537 回答
0

这也可以...我使用鸡肉方案,所以我必须从 srfi-1“导入”过滤器。

(use srfi-1)
(define *deck* '((1 2 3 4) (5 6 7) (9 10 11 12)))

(define nullcar? 
  (lambda (x) 
    (if (not (null? x)) 
      (null? (car x)))))

(define nullcdr? 
  (lambda (x) 
    (if (not (null? x)) 
      (null? (cdr x)))))

(define notnulls 
  (lambda (x) 
    (filter (lambda (e) 
              (not (null? e))) 
            x)))

(define firsts 
  (lambda (l) 
    (if (not (null? l)) 
      (map (lambda (x) 
             (if (not (null? x)) 
               (car x) 
               '())) 
            l))))

(define shuf 
  (lambda (d) 
    (notnulls 
      (append (firsts d) 
              (if (not (nullcar? d)) 
                (if (not (nullcdr? d))  
                  (shuf (map cdr (notnulls d))) 
                  '()) 
               '())))))

干杯!

于 2012-09-14T00:15:40.257 回答