Kei Minagawa
Kei Minagawa

Reputation: 4521

How to shuffle list in lisp?

It's very simple program which just return the input as a list shuffled. I wrote this program in python. Now I want to convert this program to lisp code. but I couldn't. How do I write down this program in lisp?

def my_shuffle(a, b, c, d):
    return [b, c, d, a]

I tried the following code but an error occur.

(defun my_shuffle (a b c d) (list b c d a))

Upvotes: 6

Views: 3181

Answers (2)

anquegi
anquegi

Reputation: 11522

Thee are several things here that I think that need to be pointing out. First the code that you presented is correct but do shuffle a list, present a new list of four algorithms that you pass, allways with the same order. First of all shuffle a sequence is:

generating a random permutation of a finite sequence

From wikipedia you can find several algorithms for that:

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

Also in the rosseta code there is an implementation of the knuth shuffle:

(defun nshuffle (sequence)
  (loop for i from (length sequence) downto 2
        do (rotatef (elt sequence (random i))
                    (elt sequence (1- i))))
  sequence)

Then if you apply this in the 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)

Note Two different results on the same list!!! (also the same can happen, because is a random order)

In python there are build algorithms for that:

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

also in the Common lisp library 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)

Upvotes: 10

Subham Burnwal
Subham Burnwal

Reputation: 369

(defun my_shuffle (a b c d) (list b c d a))

The above code defines a function which will take 4 items and return a rearranged list of those 4 items. It can take input of 4 lists, 4 atoms, 4 numbers, 4 anything, but it cannot separate sublists present inside a single list.

What you can do is:

(defun my_shuffle (myList) 
(list (second myList) (third myList) (fourth myList) (first myList)))

or

(defun my_shuffle (myList)
(list (cadr myList) (caddr myList) (cadddr myList) (car myList)))

or

(defun my_shuffle (myList)
(list (nth 1 myList) (nth 2 myList) (nth 3 myList) (nth 1 myList)))


car returns the first element of a list cdr returns the tail of a list (part of the list following car of the list) I have used combinations of car and cdr to extract the different elements of the list. Find that in your textbook.

first, second, third, fourth are relatively easy to use and do the same thing as car, cadr, caddr and cadddr

(nth x list) returns the (x+1)th item of the list, counting from zero. So, (nth 3 (list a b c d)) => d (nth 0 (list a b c d)) => a and so on.

Upvotes: 3

Related Questions