Поделить список на подсписки длинны 1, 2, 3 - Lisp

Узнай цену своей работы

Формулировка задачи:

Разбить список на подсписки длинны 1, 2, 3… Помогите написать задачу без рекурсии, не могу разобраться с ошибкой
//Эта функция должна выводить из списка в другой список  заданное количество элементов либо пока начальный список не закончится. Напр., (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»

textual
Листинг программы
(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 реверсируется и возвращается как результат.

  1. (task '(1 2 3 4 5 6 7 8 9 10 11 12))
  2. ((1) (2 3) (4 5 6) (7 8 9 10) (11 12))

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

9   голосов , оценка 4.111 из 5
Похожие ответы