如何在Lisp中随机播放列表?

Kei*_*awa 4 elisp common-lisp

这是一个非常简单的程序,它只将输入作为列表改组返回。我用python编写了这个程序。现在,我想将此程序转换为Lisp代码。但我做不到 如何用Lisp写下该程序?

def my_shuffle(a, b, c, d):
    return [b, c, d, a]
Run Code Online (Sandbox Code Playgroud)

我尝试了以下代码,但发生错误。

(defun my_shuffle (a b c d) (list b c d a))
Run Code Online (Sandbox Code Playgroud)

anq*_*egi 5

您在这里需要指出几件事。首先,您提供的代码是正确的,但会随机排列一个列表,然后以相同的顺序显示您通过的四个算法的新列表。首先,将一个序列改组为:

生成有限序列的随机排列

在Wikipedia中,您可以找到几种算法:

https://zh.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

同样在rosseta代码中,有一个knuth shuffle的实现:

(defun nshuffle (sequence)
  (loop for i from (length sequence) downto 2
        do (rotatef (elt sequence (random i))
                    (elt sequence (1- i))))
  sequence)
Run Code Online (Sandbox Code Playgroud)

然后,如果您在repl中应用它:

CL-USER> (nshuffle (list 1 2 3 4))
(3 1 4 2)
CL-USER> (nshuffle (list 1 2 3 4))
(3 1 2 4)
Run Code Online (Sandbox Code Playgroud)

注意同一列表上有两个不同的结果!!!(同样是可能发生的,因为是随机顺序)

在python中,有一些构建算法:

https://docs.python.org/3/library/random.html#random.shuffle

也在lisp公共库Alexandria中:

CL-USER> (ql:quickload :alexandria)
To load "alexandria":
  Load 1 ASDF system:
    alexandria
; Loading "alexandria"

(:ALEXANDRIA)
CL-USER> (alexandria:shuffle (list 1 2 3 4))
(3 2 4 1)
Run Code Online (Sandbox Code Playgroud)


Sub*_*wal 2

(defun my_shuffle (a b c d) (list b c d a))
Run Code Online (Sandbox Code Playgroud)

上面的代码定义了一个函数,它将接受4 个项目并返回这 4 个项目的重新排列列表。它可以接受 4 个列表、4 个原子、4 个数字、4 个任何东西的输入,但它不能分隔单个列表中存在的子列表。

你能做的是:

(defun my_shuffle (myList) 
(list (second myList) (third myList) (fourth myList) (first myList)))
Run Code Online (Sandbox Code Playgroud)

或者

(defun my_shuffle (myList)
(list (cadr myList) (caddr myList) (cadddr myList) (car myList)))
Run Code Online (Sandbox Code Playgroud)

或者

(defun my_shuffle (myList)
(list (nth 1 myList) (nth 2 myList) (nth 3 myList) (nth 1 myList)))
Run Code Online (Sandbox Code Playgroud)


car返回列表的第一个元素 cdr返回列表的尾部(列表后面的列表的一部分car) 我使用 car 和 cdr 的组合来提取列表的不同元素。在你的教科书中找到它。

first, second, third,fourth相对容易使用并且与car, cadr,caddr和 做同样的事情cadddr

(nth x list)返回列表的第 (x+1) 个项目,从零开始计数。因此,(nth 3 (list abcd)) => d (nth 0 (list abcd)) => a 等等。