Поделить список на подсписки длинны 1, 2, 3 - Lisp
Формулировка задачи:
//Эта функция должна выводить из списка в другой список заданное количество элементов либо пока начальный список не закончится. Напр., (f1 '(1 2 3 4) 2) -> (1 2)
(defun f1 (x y)
(setq buf nil)
(loop
(if (or (< y 0) (null (car x)))
(return buf)
(if (null buf)
(setq buf car(x))
(setq buf (append buf (list (car x))))))
(- y 1)
))
Ошибка: *** - SETQ: (X) is not a symbol
//Удаляет у-элементов из основного списка
(defun cdrf (x y)
(setq buf x)
(loop
(if (> y 0)
(setq buf (cdr x))
(return buf))
(- y 1)))
//Основная функция, которая будет увеличивать y для передачи в f1, и создаст главный список с подсписками
(defun f (x)
(setq buf nil)
(setq y 1)
(loop
(if (null (car x)) (return buf)
(setq buf (append buf (list (f1 (car x) y))))
(setq x (cdrf x y))
(setq y (+ y 1))
)))Решение задачи: «Поделить список на подсписки длинны 1, 2, 3»
(defun task (lst) (let ((r nil) (acc nil) (n 1)) (dolist (x lst nil) (push x acc) (when (= n (length acc)) (push (reverse acc) r) (setq n (+ 1 n) acc nil))) (when (> (length acc) 0) (push (reverse acc) r)) (reverse r))) ==> TASK (task '(1 2 3 4 5 6 7 8 9 10 11 12)) ==> ((1) (2 3) (4 5 6) (7 8 9 10) (11 12))
Объяснение кода листинга программы
В коде определена функция task, которая принимает в качестве аргумента список lst. Внутри функции используется let для создания трёх переменных: r, acc и n.
Первая переменная r инициализируется как nil, она будет хранить результат.
Вторая переменная acc также инициализируется как nil, она будет использоваться для накопления элементов списка, которые будут добавляться в обратном порядке.
Третья переменная n инициализируется значением 1, это счётчик количества элементов в acc.
Далее следует цикл dolist, который перебирает элементы списка lst. На каждой итерации элемент добавляется в acc, а затем проверяется, равен ли n длине acc. Если это так, то происходит реверс acc и его добавление в r. Затем n увеличивается на 1 и acc сбрасывается в nil.
После завершения цикла, если длина acc больше 0, то происходит реверс acc и его добавление в r.
В конце функции r реверсируется и возвращается как результат.
(task '(1 2 3 4 5 6 7 8 9 10 11 12))((1) (2 3) (4 5 6) (7 8 9 10) (11 12))