Search code examples
lispcommon-lisplispworks

find the position of an atom in list


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)

enter image description here


Solution

  • 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