Поделить список на подсписки длинны 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))
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д