Вернуть определенный элемент в списке - LISP - PullRequest
0 голосов
/ 06 октября 2019

Я пытаюсь написать функцию с именем: get-element (координаты доски), которая принимает доску и пару координат, представляющих позицию доски в качестве входных данных. Первый элемент пары представляет номер столбца, а второй представляет номер строки (индексация начинается с 0). Функция возвращает содержимое этой позиции платы, которая может быть X, O или NIL. Используя следующее состояние тестовой платы.

    (defparameter *test-board*
        '((nil nil nil nil nil nil)
          (O   nil nil nil nil nil)
          (X   nil nil nil nil nil)
          (X   X   O   nil nil nil)
          (O   O   X   nil nil nil)
          (nil nil nil nil nil nil)
          (nil nil nil nil nil nil)))

Функция должна работать следующим образом:

(get-element *test-board* ‘(0 0))
> NIL

Кажется, я не могу понять процесс получения, такой как вывод. Пока что мой код выглядит следующим образом (но это серьезно!):

  (col(nth 0 coords))
  (row(nth 1 coords)))

Любая помощь с пониманием того, как извлечь определенные элементы из списка, будет высоко ценится!

Ответы [ 3 ]

2 голосов
/ 06 октября 2019

Я не буду давать вам точное решение, но я надеюсь, что будет полезно подготовить его самостоятельно.

Ваша структура данных состоит из списка, каждый элемент которого представляет собой строкудоска. Итак, у вас есть список с количеством элементов, равным количеству строк на доске.

Элементами такого списка являются сами списки: поэтому каждая строка представлена ​​списком, в котором каждый элемент представляет определенную ячейку доски (не столбец, а ячейку!). Итак, ваша структура данных представляет собой список списков.

Итак, можно спросить: что такое столбец доски в этом представлении? И ответ таков: нет фактической структуры данных, которую можно назвать столбцом на плате, просто столбец можно увидеть как: «все элементы в одной и той же позиции целочисленных списков».

Итак, если вы хотите извлечь конкретную ячейку из представления вашей доски, идентифицируемого парой координат (номер строки, номер столбца), вы должны «перевести» эту информацию в ваше конкретное представление структуры данных. , что выражается вместо этого в списке списков. Например, если вы хотите получить содержимое ячейки в координатах (3, 5), то есть в строке 3 и столбце 5, вы должны рассуждать следующим образом: я могу получить доступ непосредственно к строке 3, так как эточетвертый элемент «большого» списка, но не столбцу 5, поскольку ему ничего не соответствует.

Но если я смогу получить доступ к строке 3, например, с помощью (nth 3 board), то получуэто список, соответствующий ячейкам такой строки, поэтому нет необходимости получать столбец 5, я могу просто взять элемент 5 этого списка и получить содержимое ячейки с координатой (3, 5). Таким образом, достаточно получить номер 5 этого списка, например, с помощью (nth 5 (nth 3 board)) (то есть, поскольку (nth 3 board) возвращает список ячеек этой строки, вы выбираете элемент 5 из этого списка).

Надеюсь, это поможет понять, как решить вашу проблему.

0 голосов
/ 08 октября 2019

Эта функция будет численно выбирать из вложенного списка на любую глубину:

(defun nested-list-coord-select (nested-list coords)
  (loop for coord in coords
        with current = nested-list
        do (setf current (nth coord current))
        finally (return current)))

[1]> (nested-list-coord-select '((a a)) '(0 0))
A
[2]> (nested-list-coord-select '((a a)) '(0 1))
A
[3]> (nested-list-coord-select '((a b)) '(0 1))
B
[4]> (nested-list-coord-select '((a b (c d))) '(0 1))
B
[5]> (nested-list-coord-select '((a b (c d))) '(0 2))
(C D)
[6]> (nested-list-coord-select '((a b (c d))) '(0 2 0))
C
[7]> (nested-list-coord-select '((a b (c d))) '(0 2 1))
D
[8]> (nested-list-coord-select '((a b (c d))) '(0 2 1 3))

*** - NTH: D is not a list
[9]> (nested-list-coord-select nil nil)
NIL
[10]> (nested-list-coord-select 42 nil)
42

Если мы заменим nth на elt (не обращая внимания на обратные аргументы), то она станет более общей. У нас может быть вектор списков строк и тому подобное.

Примечание: ANSI Common Lisp имеет N-мерные массивы, вы знаете.

0 голосов
/ 07 октября 2019
(defun get-element (list-of-list coord)
  "Return value of field in list-of-list."
  (let ((row (nth (first coord) list-of-list)))
    (nth (second coord) row)))
(defparameter *test-board*
     '((nil nil nil nil nil nil)
       (O   nil nil nil nil nil)
       (X   nil nil nil nil nil)
       (X   X   O   nil nil nil)
       (O   O   X   nil nil nil)
       (nil nil nil nil nil nil)
       (nil nil nil nil nil nil)))

(get-element *test-board* '(0 0)) ;; NIL
(get-element *test-board* '(1 0)) ;; O
(get-element *test-board* '(4 2)) ;; X
...