find the position of an atom in list - lisp

I have this board with atom T and I wanna get is position in list and sub-list
(defun board ()
"position of T: i=0 e j=9"
'(
;; 0 1 2 3 4 5 6 7 8 9
(96 25 54 89 21 8 36 14 41 T) ;; 0
(78 47 56 23 5 NIL 13 12 26 60) ;; 1
(0 27 17 83 34 93 74 52 45 80) ;; 2
(69 9 77 95 55 39 91 73 57 30) ;; 3
(24 15 22 86 1 11 68 79 76 72) ;; 4
(81 48 32 2 64 16 50 37 29 71) ;; 5
(99 51 6 18 53 28 7 63 10 88) ;; 6
(59 42 46 85 90 75 87 43 20 31) ;; 7
(3 61 58 44 65 82 19 4 35 62) ;; 8
(33 70 84 40 66 38 92 67 98 97);; 9
)
)
Function to get line and cell from board
(defun line (x board)
(nth x board))
(defun cell-board (x y board)
(nth y (line x board)))
(defun column (index board)
(cond ((not (numberp index)) nil)
((< index 0) nil)
(t (mapcar #'(lambda (line &aux (n-column (nth index line))) n-column) board))))
Function that receives the board and returns the position (i j) where the "T" is. If "T" is not on the board, NIL should be returned.
(defun find-T-position (board)
)
you can teste and see the result here https://ideone.com/GQIePI
(print "position : " (find-T-position (board)))
the result correct should be
(0 9)

The board function tries to call a literal list as-if it was a function. The quote is misplaced.
The find-t-position function has no body.
If you add more code and an actual question you will have better feedback.
Hint: either T is in current row (car board), or you need to search the board (cdr board); test often to spot errors.

(defun find-t (rows)
(let* ((col nil)
(row (position-if (lambda (r) (setf col (position t r))) rows)))
(values row col)))
Some tests:
[1]> (find-t nil)
NIL ;
NIL
[2]> (find-t '(()))
NIL ;
NIL
[3]> (find-t '((0)))
NIL ;
NIL
[4]> (find-t '((t)))
0 ;
0
[5]> (find-t '((0 t)))
0 ;
1
[6]> (find-t '((0 t 0)))
0 ;
1
[7]> (find-t '((0 0 t)))
0 ;
2
[8]> (find-t '((0 0 0)))
NIL ;
NIL
[9]> (find-t '((0 0 0)
(t 0 0)))
1 ;
0
[10]> (find-t '((0 0 0)
(t 0 t)))
1 ;
0
[11]> (find-t '((0 0 0)
(0 0 t)))
1 ;
2
[12]> (find-t '((0 0 t)
(0 0 t)))
0 ;
2

I find the answer in this question Lisp position of nested list element with children and it´s work perfectly
(defun my-position (elm tree &optional (start 0))
"find the generalized position of elm inside tree.
Parameters: elm - element to be found
tree - a list of atoms and lists in which to search the element
start - the tentative position"
(cond ((null tree) nil) ; element not present => nil
((atom (first tree)) ; if the first element is an atom, then
(if (eql elm (first tree)) ; if equal to element, found
(list start) ; return position start
;; otherwise, recur on rest of list incrementing the tentative position
(my-position elm (rest tree) (1+ start))))
;; otherwise, the first element is a list,
;; try to find it inside, with a recursive call
(t (let ((pos (my-position elm (first tree) 0)))
(if pos ; if not nil the element has been found
(cons start pos) ; return the current position followed by the position inside the list
; otherwise recur on rest of list incrementing the tentative position
(my-position elm (rest tree) (1+ start)))))))
and my function find-t-position just call the function my-position
with element 'T and the board and return the position of element 'T in
list
(defun find-T-position (board)
(my-position ('T board))
you can see the correct result https://ideone.com/DOIOoB

Related

How to convert a list of numbers to separated strings using Lisp?

Given the following code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Copyright (C) 2014 Wojciech Siewierski ;;
;; ;;
;; This program is free software: you can redistribute it and/or modify ;;
;; it under the terms of the GNU General Public License as published by ;;
;; the Free Software Foundation, either version 3 of the License, or ;;
;; (at your option) any later version. ;;
;; ;;
;; This program is distributed in the hope that it will be useful, ;;
;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;
;; GNU General Public License for more details. ;;
;; ;;
;; You should have received a copy of the GNU General Public License ;;
;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar *output*)
(defvar *indent*)
(defun format-tag (symbol &optional arg)
(cond
((equal arg 'begin)
(format nil "~{~a~}<~(~a~)" *indent* symbol))
((equal arg 'end)
(format nil "~{~a~}<~(/~a~)>~%" *indent* symbol))
(t
(format nil "~{~a~}~a~%" *indent* symbol))))
(defun sexp-to-xml--inside-tag (sexp)
(if sexp
(if (listp (car sexp))
(progn
(sexp-to-xml--new-tag (car sexp))
(sexp-to-xml--inside-tag (cdr sexp)))
(progn
(push (format-tag
(string (car sexp)))
*output*)
(sexp-to-xml--inside-tag (cdr sexp))))))
(defun sexp-to-xml--attrs (plist)
(when plist
(push (format nil " ~(~a~)=~s"
(car plist)
(cadr plist))
*output*)
(sexp-to-xml--attrs (cddr plist))))
(defun sexp-to-xml--new-tag (sexp)
(if (listp (car sexp))
(progn
(push (format-tag (caar sexp) 'begin)
*output*)
(sexp-to-xml--attrs (cdar sexp)))
(push (format-tag (car sexp) 'begin)
*output*))
(unless (cdr sexp)
(push (format nil " /")
*output*))
(push (format nil ">~%")
*output*)
(let ((*indent* (cons " " *indent*)))
(sexp-to-xml--inside-tag (cdr sexp)))
(when (cdr sexp)
(push (format-tag (if (listp (car sexp))
(caar sexp)
(car sexp))
'end)
*output*)))
(defun sexp-to-xml-unquoted (&rest sexps)
(apply #'concatenate 'string
(apply #'concatenate 'list
(loop for sexp in sexps collecting
(let ((*output* nil)
(*indent* nil))
(reverse (sexp-to-xml--new-tag sexp)))))))
(defmacro sexp-to-xml (&rest sexps)
`(format *standard-output* "~a"
(sexp-to-xml-unquoted ,#(loop for sexp in sexps collecting
`(quote ,sexp)))))
(defun file-get-contents (filename)
(with-open-file (stream filename)
(let ((contents (make-string (file-length stream))))
(read-sequence contents stream)
contents)))
(defun file-get-lines (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil)
while line
collect line)))
(defun list-to-string (lst)
(format nil "~{~A~}" lst))
(defun test1()
(let((input (file-get-contents "sample2.sexp")))
(format t (sexp-to-xml-unquoted (read-from-string "(head (title \"my-site\"))")))
)
)
(defun test2()
(let((input (file-get-lines "sample2.sexp")))
(loop for sexp in input do (print (write-to-string sexp)))
)
)
(defun test3()
(let((input (file-get-lines "sample2.sexp")))
(format t (list-to-string input))
)
)
(defun :str->lst (str / i lst)
(repeat (setq i (strlen str))
(setq lst (cons (substr str (1+ (setq i (1- i))) 1) lst))))
(defun print-elements-recursively (list)
(when list ; do-again-test
(print (car list)) ; body
(print-elements-recursively ; recursive call
(cdr list)))) ; next-step-expression
(defun tokenize( str )(read-from-string (concatenate 'string "(" str
")")))
(defun test4()
(let((input (file-get-contents "sample2.sexp")))
(print-elements-recursively (tokenize input) )
)
)
(defun test5()
(let((input (file-get-contents "sample2.sexp")))
(print (sexp-to-xml-unquoted (tokenize input)))
)
)
(defun test6()
(let((input (file-get-contents "sample2.sexp")))
(loop for sexp in (tokenize input) do (
with-input-from-string (s (write-to-string sexp) )
(print ( sexp-to-xml-unquoted (read s)) )
)
)
)
)
(defun test7()
(let((input (file-get-contents "sample2.sexp")))
(loop for sexp in (tokenize input) do (
print sexp
)
)
)
)
(defun test8()
(let((input (file-get-contents "sample2.sexp")))
(format t (sexp-to-xml-unquoted (read-from-string input)))
)
)
I want to serialize into an xml file, specifically this sample file:
(supertux-tiles
(tilegroup
(name (_ "Snow"))
(tiles
7 8 9 202
13 14 15 204
10 11 12 206
16 17 18 205
30 31 114 113
21 22 19 203
20 23 207 208
3044 3045 3046 3047
3048 3049 3050 3051
3052 3053 3054 3055
3056 3057 3058 3059
2134 115 116 214
2135 117 118 1539
3249 3250 3251 3252
3253 3254 3255 3256
3261 3262 3263 3264
3265 3266 3267 3268
2121 2122 2123 0
2126 2127 2128 0
2131 2132 2133 0
2124 2125 0 0
2129 2130 0 0
2909 2910 2913 2914
2911 2912 2915 2916
1834 0 0 1835
2917 2918 2921 2922
2919 2920 2923 2924
0 1826 1827 0
1829 1830 1831 1832
1833 1834 1835 1836
3139 3140 3141 3142
3143 3144 3145 3146
0 3147 3148 0
3149 0 0 3150
3151 3152 3153 3154
3155 3156 3157 3158
0 1835 1834 0
1837 1838 1843 1844
1839 1840 1845 1846
1841 1842 1847 1848
0 0 1849 1850
2925 2926 2929 2930
0 2928 2931 0
0 0 2937 2940
2933 2935 2938 2941
2934 2936 2939 2942
2050 2051 2060 2061
2055 2056 2065 2066
2052 2053 2054 0
2057 2058 2059 0
2062 2063 2064 0
0 2067 2068 2069
0 2072 2073 2074
2075 2079 2076 2070
2077 2073 2078 2071
2178 3038 3039 3040
2406 3041 3042 3043
2155 2156 2157 2163
2158 2159 2154 2164
2160 2161 2162 2165
2166 2167 2168 2169
2170 2171 2172 2173
2174 2175 2176 2177
2384 2385 2386 2949
2387 2388 2389 2950
2390 2391 2392 2951
2393 2394 2395 2952
2953 2954 2955 2956
2957 2962 2398 2396
2958 2961 2399 2397
2959 2960 2997 2998
0 0 2963 2969
2975 2979 2964 2970
2976 2980 2965 2971
2977 2981 2966 2972
2978 2982 2967 2973
0 0 2968 2974
0 2986 2990 0
2983 2987 2991 2994
2984 2988 2992 2995
2985 2989 2993 2996
33 32 34 1741
35 37 39 1740
38 36 43 1739
40 41 42 1815
119 121 120 1816
)
)
)
But using test8 it gives an error:
7 is not a string designator.
Which led me to write a file like so:
(supertux-tiles
(tilegroup
(name (_ "Snow"))
(tiles
"7"
)
)
)
Which then compiles fine and the xml is generated upon, but I don't know how to convert all the integers into their string representation, reading from the list. I tried parsing the string and using the write-to-string method but I think I'm missing something.
Any help will be grated.
Thanks!
-- EDIT --
Changing string with princ-to-string as coredump suggested fixes the parsing evaluation of raw numbers within the string, however, when attempting to evaluate symbols such as t this is what it happens:
no dispatch function defined for #\T
using as an example the following
(tile
; dupe of tile 70, this one will be removed.
(id 63)
(deprecated #t)
(images
"tilesets/background/backgroundtile1.png"
)
)
It looks, though, that evaluating to a variable outside Lisp will be kept by only checking for the "t" xml tag.
This got solved.
A quick search on google lead to the following repository (https://github.com/Vifon/sexp-to-xml/blob/master/sexp-to-xml.lisp); the linked code is enough to reproduce the error. Note that when I run it from inside Emacs/Slime, the debugger shows the backtrace:
0: (STRING 7)
1: (SEXP-TO-XML--INSIDE-TAG (7 8 9 202 13 14 ...))
2: (SEXP-TO-XML--NEW-TAG (TILES 7 8 9 202 13 ...))
3: (SEXP-TO-XML--INSIDE-TAG ((TILES 7 8 9 202 13 ...)))
4: (SEXP-TO-XML--INSIDE-TAG ((NAME (_ "Snow")) (TILES 7 8 9 202 13 ...)))
5: (SEXP-TO-XML--NEW-TAG (TILEGROUP (NAME (_ "Snow")) (TILES 7 8 9 202 13 ...)))
6: (SEXP-TO-XML--INSIDE-TAG ((TILEGROUP (NAME #) (TILES 7 8 9 202 13 ...))))
7: (SEXP-TO-XML--NEW-TAG (SUPERTUX-TILES (TILEGROUP (NAME #) (TILES 7 8 9 202 13 ...))))
8: (SEXP-TO-XML-UNQUOTED (SUPERTUX-TILES (TILEGROUP (NAME #) (TILES 7 8 9 202 13 ...))))
Pressing v on various stack frames listed above, I can locate the places where the code currently is halted across the call stack.
I did not load a lisp file, but just evaluated the different forms in the current Emacs buffer, so there is no source file associated with functions. Yet, the AST form is stored for debugging purposes and the debugger can pinpoint where code execution currently is, wrapped in a fake (#:***HERE*** ...) form:
(SB-INT:NAMED-LAMBDA SEXP-TO-XML--INSIDE-TAG
(SEXP)
(BLOCK SEXP-TO-XML--INSIDE-TAG
(IF SEXP
(IF (LISTP (CAR SEXP))
(PROGN
(SEXP-TO-XML--NEW-TAG (CAR SEXP))
(SEXP-TO-XML--INSIDE-TAG (CDR SEXP)))
(PROGN
(PUSH (FORMAT-TAG (#:***HERE*** (STRING (CAR SEXP)))) *OUTPUT*)
(SEXP-TO-XML--INSIDE-TAG (CDR SEXP)))))))
Calling string on arbitrary values won't work, you need to replace that by princ-to-string in sexp-to-xml--inside-tag. Then it works as expected.

Best way to implement rook moves and possible moves in Lisp

I have board [8,8] and I'm trying to implement the horizontal movement and vertical movement based on the movements up, down, left and right, movements of a rook on a chessboard and I am having difficulty in how to move piece to square with the number of square to move.
(defun board ()
'((64 35 74 26 21 57 12 28)
(43 15 47 53 24 56 42 29)
(51 41 71 31 17 45 55 30)
(67 66 22 T 54 75 32 38)
(13 11 16 23 25 27 33 20)
(34 36 37 44 46 52 61 48)
(10 49 59 69 68 70 50 40)
(62 63 65 72 73 76 77 58)))
The Rook moves horizontally and vertically any number of squares, forwards or backwards. In the diagram the Rook can move to any of the highlighted squares.
Function to check if the coordinates are valid
(defun position-valid (x y)
(and (>= x 0) (>= y 0) (< x 8) (< y 8)))
Function that will move the tower according to the coordinates (x, y)
(defun move-piece (x y dx dy board)
(let ((new-board (copy-tree board))
(new-x (+ x dx))
(new-y (+ y dy))
(piece (nth x (nth y board))))
(setf (nth x (nth y new-board)) nil
(nth new-x (nth new-y new-board)) piece)
new-board))
Function that moves the piece down
(defun DOWN (x y board)
(cond
((equal (position-valid (+ x 1) (+ y 0)) 'T)
(move-piece x y 1 0 board))
(T NIL)))
Function that moves the piece to up
(defun UP (x y board)
(cond
((equal (position-valid (- x 1) (+ y 0)) 'T)
(move-piece x y -1 0 board))
(T NIL)))
Function that moves the piece to the left
(defun LEFT (x y board)
(cond
((equal (position-valid (+ x 0) (- y 1)) 'T)
(move-piece x y 0 -1 board))
(T NIL)))
Function that moves the piece to the right
(defun RIGHT (x y board)
(cond
((equal (position-valid (+ x 0) (+ y 1)) 'T)
(move-piece x y 0 1 board))
(T NIL)))
now the goal is to implement the vertical and horizontal movements based on the movements mentioned above so that the piece is moved and in this case, I think that we still need to implement the possible moves based on the type of movement and how many squares to move
I implemented this list of operators for horizontal and vertical movement but it is not working
Function that moves the Tower horizontally
(defun HORIZONTAL (x y n mov board) ;;n is number of square to move
(cond
((and (equal (position-valid (+ x 0) (- y 1)) 'T) ;;left
(equal (position-valid (+ x 0) (+ y 1)) 'T));;right
(cond
((equal mov 'LEFT) (LEFT x y board))
((equal mov 'RIGHT) (RIGTH x y board))
(T (HORIZONTAL x y (1- n) mov board))))
(T NIL)))
Function that makes the Tower move in the vertical direction,
(defun VERTICAL(x y n mov board) ;;n is number of square to move
(cond
((and (equal (position-valid (- x 1) (+ y 0)) 'T) ;;up
(equal (position-valid (+ x 1) (+ y 0)) 'T));;down
(cond
((equal mov 'DOWN) (DOWN x y board))
((equal mov 'UP) (UP x y board))
(T (VERTICAL x y (1- n) mov board))))
(T NIL)))
and how to get the possible moves of the tower on the board based on the type of moves
Anny suggestion?
It seems to me that you are building too many functions which are unnecessary. What I would do is to have a MOVE function, based on move-piece, which would do both horizontal and vertical displacement. Since you have the parameter mov, which can be UP, DOWN, LEFT or RIGHT, the horizontal and vertical movements are already implicit, so there is no need to have a separate function for each direction.
So this is what I would do:
(setq board
'((64 35 74 26 21 57 12 28)
(43 15 47 53 24 56 42 29)
(51 41 71 31 17 45 55 30)
(67 66 22 T 54 75 32 38)
(13 11 16 23 25 27 33 20)
(34 36 37 44 46 52 61 48)
(10 49 59 69 68 70 50 40)
(62 63 65 72 73 76 77 58)))
(defun position-valid (x y)
(and (>= x 0) (>= y 0) (< x 8) (< y 8)) )
(defun move-piece (x y dx dy board)
(let ((new-board (copy-tree board))
(new-x (+ x dx))
(new-y (+ y dy))
(piece (nth x (nth y board))) )
(when (position-valid new-x new-y)
(setf (nth x (nth y new-board)) nil
(nth new-x (nth new-y new-board)) piece ))
new-board))
(defun MOVE (x y n mov board) ;; n is number of squares to move
(case mov
(UP (move-piece x y 0 (- n) board))
(DOWN (move-piece x y 0 n board))
(LEFT (move-piece x y (- n) 0 board))
(RIGHT (move-piece x y n 0 board))
(otherwise NIL) ))
And then, if you want to get a list of all possible moves:
(defun valid-moves (x y board)
(let (result)
(dolist (mov '(up down left right) result)
(dotimes (n 7)
(when (move x y n mov board)
(push (list n mov) result) )))))

How to create a list of lists in lisp?

I am trying to run code in common lisp, but it keeps giving me the following error:
*** - SYSTEM::%EXPAND-FORM: (SETF (NTH X NUMS) 0) should be a lambda
expression
What am I doing wrong? I am pretty new to lisp, and here is my code:
(defun answer-ynq()
(setq nums '(13 15 19 33))
(setq numsstuff '())
(loop for x from 1 to 4
do (progn(
(setf (nth x nums) 0)
(append numstuff nums)
)))
(print numstuff)
)
(answer-ynq)
Also, is this the right way to create a list out of lists? I need numsstuff to be a list of lists in this way, where if I give in a list of objects (13 15 19 33), I get an output that is the following list of lists:
((0 15 19 33) (13 0 19 33) (13 15 0 33) (13 15 19 0))
Thank you so much!
CL-USER > (loop for i below 4
collect (loop for e in '(13 15 19 33)
for j from 0
when (= i j) collect 0 else collect e))
((0 15 19 33) (13 0 19 33) (13 15 0 33) (13 15 19 0))

How to print a list as matrix in Common Lisp

I am working in Common Lisp, trying to make Windows game minesweeper.
I have a list (1 1 1 2 2 2 3 3 3) and want to print that like matrix
(1 1 1
2 2 2
3 3 3)
How to do that?
Edit
I am at the beginning of
(format t "Input width:")
(setf width (read))
(format t "Input height:")
(setf height (read))
(format t "How many mines:")
(setf brMina (read))
(defun matrica (i j)
(cond ((= 0 i) '())
(t (append (vrsta j) (matrica (1- i) j) ))))
(setf minefield (matrica width height))
(defun stampaj ()
(format t "~%~a" minefield ))
Another example, using the pretty-printer for fun:
(defun print-list-as-matrix
(list elements-per-row
&optional (cell-width (1+ (truncate (log (apply #'max list) 10)))))
(let ((*print-right-margin* (* elements-per-row (1+ cell-width)))
(*print-miser-width* nil)
(*print-pretty* t)
(format-string (format nil "~~<~~#{~~~ad~~^ ~~}~~#:>~%" cell-width)))
(format t format-string list)))
Works like this:
CL-USER> (print-list-as-matrix (loop for i from 1 to 9 collect i) 3)
1 2 3
4 5 6
7 8 9
NIL
CL-USER> (print-list-as-matrix (loop for i from 1 to 25 collect i) 5)
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
NIL
CL-USER> (print-list-as-matrix (loop for i from 1 to 16 collect i) 2)
1 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
Like this:
(defun print-list-as-grid (list rows cols)
(assert (= (length list) (* rows cols))
(loop for row from 0 below rows do
(loop for col from 0 below cols do
(princ (car list))
(princ #\space)
(setf list (cdr list)))
(princ #\newline)))
* (print-list-as-grid '(a b c d e f g h i) 3 3)
A B C
D E F
G H I
NIL

How do I insert a lenghthier list in my buffer with elisp?

If I do C-u M-: (to insert the result of a lisp statement into the buffer) and I then do something like:
(progn (setq x 0 l '()) (while(< x 30) (push (random 99) l) (incf x 1)) (nreverse l))
I get:
(89 29 27 23 56 88 37 11 33 20 98 95 ...)
With trailing ellipsis. What's a way around this? Something like buffer-insert across the resulting list.
try
(setq eval-expression-print-length nil)
in .emacs
M-:(insert (pp (loop repeat 30 collect (random 99))))
May need (require 'cl) first.