0

I have this function to create a list with initial element from the other question list with initial-element are start from 99 to 0 in Lisp

(defun newList (&optional(n 100))
  (loop for i from (- n 1) downto 0 collect i))

(defun board (newList &optional(n 10))
  (cond
   ((null newList) nil)
   (t (cons (subseq newList 0 n) (board (subseq newList n) n)))))

(defun show-board (board)
    (format T "~%")
    (mapcar (lambda (x) (format T " ~A ~%" x)) board)
    (format nil "")
)

(show-board (board (newList)))

(99 98 97 96 95 94 93 92 91 90) 
(89 88 87 86 85 84 83 82 81 80) 
(79 78 77 76 75 74 73 72 71 70) 
(69 68 67 66 65 64 63 62 61 60) 
(59 58 57 56 55 54 53 52 51 50) 
(49 48 47 46 45 44 43 42 41 40) 
(39 38 37 36 35 34 33 32 31 30) 
(29 28 27 26 25 24 23 22 21 20) 
(19 18 17 16 15 14 13 12 11 10) 
(9 8 7 6 5 4 3 2 1 0) 

see the result here https://ideone.com/Paorct and with this function to remove duplicate number

(defun remove-duplicate (pred l)
  (cond ((null l) NIL) 
        ((funcall pred (car l)) (remove-duplicate pred (cdr l)))
        (T (cons (car l) (remove-duplicate pred (cdr l))))))

I wanna implement a function that receives a the list and will randomly change its numbers. Make a recursive function and use the

nth

function, the random function, and the

remove-duplicate

function where the function must remove the number from the list equal to the one found randomly.

The stop condition is for the list to be empty;

should use the

let

statement to locally store the number found at a random position using the following statement:

(nth (random (length l)) l)

Using the

remove-duplicate

function you should remove from the list that is being passed as an argument in the recursive function, the number that was found randomly and that is stored locally. I have this but it´s not work and I tried to understand the algorithm

my doubt is here, how to implement the function to shuffle list without duplicate number

(defun shuffle-list (l)
   ;; iterate 99 times
   (dotimes (i (- (length l) 1))
    ;; store random number to n
    (let ((n (nth (random (length l)) l)))
         ;; print value of n
         (format t "~A ~%" n)
         (cond 
             ((null l) nil)
             ;; I have this but it´s not show the new list
             (t (remove-duplicate #'(lambda (x) (= x n)) l))))))

the result for example should be

 (94 25 54 89 21 8 36 14 41 96) 
 (78 47 56 23 5 49 13 12 26 60)  
 (0 27 17 83 34 93 74 52 45 80)  
 (69 9 77 95 55 39 91 73 57 30) 
 (24 15 22 86 1 11 68 79 76 72)  
 (81 48 32 2 64 16 50 37 29 71)  
 (99 51 6 18 53 28 7 63 10 88)  
 (59 42 46 85 90 75 87 43 20 31)  
 (3 61 58 44 65 82 19 4 35 62)
 (33 70 84 40 66 38 92 67 98 97)
Renata P Souza
  • 255
  • 3
  • 20
  • The question is a bit unclear, but I think salvageable. I think you mean that `let`, `nth`, `random`, and `remove-duplicates` can be assumed as given (look them up in the Common Lisp Hyperspec!), and that you are expected to implement a simple shuffle of a list without duplicates with them. – Svante Nov 25 '19 at 01:00
  • thanks and you right, the question was missing put the function `generate-board` but I updated the project and the goal is implement a recursive function to shuffle a list without duplicates removing by `remove-duplicate` function – Renata P Souza Nov 25 '19 at 03:42
  • in fact is `Common Lisp Hyperspec` – Renata P Souza Nov 25 '19 at 03:58

2 Answers2

1

There is a built-in function remove-duplicates whose name ends with an "s".

remove-duplicates takes a :from-end keyword argument, with a boolean value, to control which of the duplicate values is kept: the first or the last that occurs in a list.

Please read in Practical Common Lisp about let and about if/cond. It's a great book!

zut
  • 806
  • 4
  • 12
  • Thanks @zut, after reading about **let**, I learned that it serves to assign the result of an operation to a local variable like `(let ((n (nth (random (length list)) list)))` and now is about **if/cond** that missing, and about `remove-duplicates`, I need to use the **remove-duplicate** the function I mention in question, that receive the predicate and list, I update the code, if you wanna see the result [check result](https://ideone.com/cFNGbU) – Renata P Souza Nov 29 '19 at 19:17
1

That remove-duplicate definition takes a predicate and removes elements for which the predicate is true. It behaves the same as the builtin remove-if.

So you have to create a predicate function that compares a list item to the n saved in (let ((n (nth (random (length list)) list))). Learn about variables, lambda, and closures.

zut
  • 806
  • 4
  • 12
  • yes I understand, I made this `(dotimes (i (- (length list) 1))...` to iterate and store 99 number and the use of function remove duplicate but it´s not create a new list `(t (remove-duplicate #'(lambda (x) (list n) (cons n x)) list))))))`, if you wanna [see the result](https://ideone.com/WM786d) – Renata P Souza Dec 01 '19 at 18:02
  • I change to this `(remove-duplicate #'(lambda (x) (= x n) (cons n x) list)` and don´t show nothing , I think it´s need more thing but I dont have idea – Renata P Souza Dec 01 '19 at 18:33
  • use this example `(remove-if #'(lambda (x) (= x 10)) '(11 10 9 5 15 10 6 0))` it will remove all number 10 and I update the code to `(remove-duplicate #'(lambda (x) (= x n)) list)` and I think its missing the part that create new list, I try `(list n) (cons n x)` but it´s not work – Renata P Souza Dec 01 '19 at 18:46
  • This might be what you are looking for, close to what you have: `(cons n (remove-duplicate #'(lambda (x) (= x n)) list))` and don't forget to store it it: `(setf list (cons ..))` – zut Dec 01 '19 at 22:22
  • the method is recursive, so i implemented this `(shuffle-list (setf list (cons n list)))` and it doesn't work and when you see the result, the list grows in size and I need the right answer to close this – Renata P Souza Dec 02 '19 at 00:59
  • to stop condition, I try `(defparameter *fn* (let ((count 0)) #'(lambda () (setf count (1+ count)))))` and in condition `((= (funcall *fn*) (length list)) NIL)` but in test finish at 199 but should be 100 and I try this `(t (shuffle-list (setf list (cons n (remove-duplicate #'(lambda (x) (= x n)) list))))`, it is working, I think, but it should return a new random and not repeated list, and it returns nothing – – Renata P Souza Dec 02 '19 at 01:44
  • I find here `((= (funcall *fn*) (length list)) NIL)` when it´s stop condition return `NIL` and I change to the list `((= (funcall *fn*) (length list)) list)` ad it's work – Renata P Souza Dec 02 '19 at 17:20