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)
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!
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.
Related
Function that takes a positive number and creates a list of all numbers between 0 (included) and the number passed as an argument (excluded). By default, it's 100
(defun list-numbers (&optional (n 100))
(mapcar #'abs (make-list n :initial-element (- n 1))))
if you want to see the result https://ideone.com/Jbz5u3
(99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
99 99 99 99 99 99 99 99)
but my goal is create a simple list that initial-element are started with values from 99 to 0
(99 98 97 96 95 94 93 92 91 90 89 88 87 86....
9 8 7 6 5 4 3 2 1 0)
CL-USER 160 > (loop for i from 99 downto 0 collect i)
(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)
or
CL-USER 167 > (do* ((i 0 (+ i 1))
(result (list i) (cons i result)))
((= i 99) result))
(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)
I am very confused about what the function "do-something" does. Maybe I can replace it with another name.
(defun do-something (m &optional n)
(let* ((count (if (null n) 20 n))
(bound (* count m)))
(loop for i from 0 below m
do (princ "[ ")
(loop for j from (+ (- bound) i) to (+ bound i) by m
do (princ j)
(princ " "))
(princ "]\n"))))
You can try it on emacs by cut'n'paste to buffer and run C-x C-e (eval-last-sexp)
(do-something 10 10)
[ -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 ]
[ -99 -89 -79 -69 -59 -49 -39 -29 -19 -9 1 11 21 31 41 51 61 71 81 91 101 ]
[ -98 -88 -78 -68 -58 -48 -38 -28 -18 -8 2 12 22 32 42 52 62 72 82 92 102 ]
[ -97 -87 -77 -67 -57 -47 -37 -27 -17 -7 3 13 23 33 43 53 63 73 83 93 103 ]
[ -96 -86 -76 -66 -56 -46 -36 -26 -16 -6 4 14 24 34 44 54 64 74 84 94 104 ]
[ -95 -85 -75 -65 -55 -45 -35 -25 -15 -5 5 15 25 35 45 55 65 75 85 95 105 ]
[ -94 -84 -74 -64 -54 -44 -34 -24 -14 -4 6 16 26 36 46 56 66 76 86 96 106 ]
[ -93 -83 -73 -63 -53 -43 -33 -23 -13 -3 7 17 27 37 47 57 67 77 87 97 107 ]
[ -92 -82 -72 -62 -52 -42 -32 -22 -12 -2 8 18 28 38 48 58 68 78 88 98 108 ]
[ -91 -81 -71 -61 -51 -41 -31 -21 -11 -1 9 19 29 39 49 59 69 79 89 99 109 ]
As you see, it prints 2 dimensional array with some form.
I know my answer is dead wrong, I would like to know how I would be able to reach the answer. What did I do wrong?
X = (setf X '(88 ((11 21 31 41)) (90 91 92 93)))
I have to write LISP expression which evaluates to the list:
(11 (11 21 31 41) (88 90 91 92 93))
My Answer:
(list (caadr X) (cdddr X))
These should get you going:
CL-USER> (cadr X)
((11 21 31 41))
CL-USER> (caadr X)
(11 21 31 41)
CL-USER> (caaadr X)
11
CL-USER> (cons (caaadr X) (cadr X))
(11 (11 21 31 41))
CL-USER> (caddr X)
(90 91 92 93)
CL-USER> (car X)
88
CL-USER> (cons (car X) (caddr X))
(88 90 91 92 93)
(Experimenting in the REPL is a very effective way of finding things out.)
The following b variable seems to have a last character corresponding to a line break but it is not the classical '\n' character. This is very embarrassing for print using this variable:
K>> b
b =
toto_titi
K>> fprintf('This strange variable (%s) is very strange !!!\n', b);
This strange variable (toto_titi
) is very strange !!!
Indeed, the needed print would be:
This strange variable (toto_titi) is very strange !!!
Below, few observed facts with this variable:
K>> class(b)
ans =
char
K>> [b 'end']
ans =
toto_titi
end
K>> b(end)
ans =
K>> regexp(b,'_', 'split')
ans =
'toto' 'titi…'
I confess that I do not exactely understand for the three dots in 'titi…' but I suppose that here is a part of the explanation !!!
A quick and dirty method will be to remove the last invisible character that cause the line break but if in other application the last caharacter in the b variable is a "real" character we will lost this last character (ex. toto_tit in place of toto_titi).
A MATLAB equivalent of the python strip() exist ?
What is this invisible character in the b variable ?
EDIT 1:
A good idea, from rahnema1, is to determine what is the ASCII code for this invisible character:
K>> double(b)
ans =
116 111 116 111 95 116 105 116 105 13
K>> for i = 1 : 60
str = [num2str(i) ' ' char(i) ' '...
num2str(i+32) ' ' char(i+32) ' '...
num2str(i+64) ' ' char(i+64)];
disp(str)
end
1 33 ! 65 A
2 34 " 66 B
3 35 # 67 C
4 36 $ 68 D
5 37 % 69 E
6 38 & 70 F
7 39 ' 71 G
8 40 ( 72 H
9 41 ) 73 I
10
42 * 74 J
11 43 + 75 K
12 44 , 76 L
13
45 - 77 M
14 46 . 78 N
15 47 / 79 O
16 48 0 80 P
17 49 1 81 Q
18 50 2 82 R
19 51 3 83 S
20 52 4 84 T
21 53 5 85 U
22 54 6 86 V
23 55 7 87 W
24 56 8 88 X
25 57 9 89 Y
26 58 : 90 Z
27 59 ; 91 [
28 60 < 92 \
29 61 = 93 ]
30 62 > 94 ^
31 63 ? 95 _
32 64 # 96 `
33 ! 65 A 97 a
34 " 66 B 98 b
35 # 67 C 99 c
36 $ 68 D 100 d
37 % 69 E 101 e
38 & 70 F 102 f
39 ' 71 G 103 g
40 ( 72 H 104 h
41 ) 73 I 105 i
42 * 74 J 106 j
43 + 75 K 107 k
44 , 76 L 108 l
45 - 77 M 109 m
46 . 78 N 110 n
47 / 79 O 111 o
48 0 80 P 112 p
49 1 81 Q 113 q
50 2 82 R 114 r
51 3 83 S 115 s
52 4 84 T 116 t
53 5 85 U 117 u
54 6 86 V 118 v
55 7 87 W 119 w
56 8 88 X 120 x
57 9 89 Y 121 y
58 : 90 Z 122 z
59 ; 91 [ 123 {
60 < 92 \ 124 |
EDIT 2:
Works around the idea of rahnema1 and excaza:
. If we know the ASCII code (by using strrep):
K>> fprintf('This strange variable (%s) is very stange !!!\n', strrep(b,char(13),''));
This strange variable (toto_titi) is very stange !!!
. For remove leading and trailing whitespace (by using strtrim):
fprintf('This strange variable (%s) is very stange !!!\n', strtrim(b));
This strange variable (toto_titi) is very stange !!!
mat =
147 155 139 104 84 139
136 134 99 73 60 144
98 82 60 54 47 118
86 59 46 48 38 90
88 66 50 44 35 67
88 75 53 40 43 48
p = mat(3,3)
q = mat(2,5)
V = [1:60]
all i want is to check if there exist a path between pixel p and q using vector V, for example given matrix above there exist a paths: path1: (3,3) , (3,4) , (3,5) , (2,5) path2: (3,3) , (4,3) , (4,4) , (4,5) , (3,5) , (2,5) and many other paths, Note: pixel value in each path's coordinate should be in 'V' and obviously p and q should also be in 'V'. that's what i am trying to achieve in MATLAB
Code i've written so far:
mat =
147 155 139 104 84 139
136 134 99 73 60 144
98 82 60 54 47 118
86 59 46 48 38 90
88 66 50 44 35 67
88 75 53 40 43 48
p = mat(3,3)
q = mat(2,5)
V = [1:60]
% need to check N4 connectivity through pixel value p to q
cc = bwconncomp(mat,4)
for i=1:cc.NumObjects
pix = cc.PixelIdxList{i}
if any(ismember(pix(:), p)) && any(ismember(pix(:), q)) && any(ismember(V(:), p)) && any(ismember(V(:), q))
display('found N4 connectivity')
end
Actual Question: is this correct way to do the required task or am i doing it wrong?