How to shuffle list in lisp?
Asked Answered
P

2

6

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))
Penthouse answered 26/3, 2018 at 11:38 Comment(5)
There's nothing wrong with your code. (my_shuffle 1 2 3 4) returns (2 3 4 1). How are you calling it?Mesquite
n.b. Saying that there was "an error" is rarely useful unless you say what the error was. Always include the exact error message, and how you triggered it.Mesquite
@phils: I call it by (my_shuffle (list 1 2 3 4)). It seems I'm passing incorrect argument. As you say (my_shuffle 1 2 3 4) returns (2 3 4 1) and this is what I want.Penthouse
You better call a function with four parameters then with four arguments, not only one list.Abase
Calling my_shuffle([1,2,3,4]) in Python doesn't work either. None of them takes one list parameter, but both takes 4 arguments and return a list with those in a different order than called.Portraitist
K
10

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)
Kt answered 27/3, 2018 at 6:42 Comment(0)
M
3
(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.

Mcginty answered 26/3, 2018 at 19:8 Comment(2)
I would suggest that nth is particularly worth pointing out here.Mesquite
thx for mentioning it sir, I forgot about it so easily. I added itMcginty

© 2022 - 2024 — McMap. All rights reserved.