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

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

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

Разбить список на подсписки длинны 1, 2, 3… Помогите написать задачу без рекурсии, не могу разобраться с ошибкой
Листинг программы
  1. //Эта функция должна выводить из списка в другой список заданное количество элементов либо пока начальный список не закончится. Напр., (f1 '(1 2 3 4) 2) -> (1 2)
  2. (defun f1 (x y)
  3. (setq buf nil)
  4. (loop
  5. (if (or (< y 0) (null (car x)))
  6. (return buf)
  7. (if (null buf)
  8. (setq buf car(x))
  9. (setq buf (append buf (list (car x))))))
  10. (- y 1)
  11. ))
  12. Ошибка: *** - SETQ: (X) is not a symbol
  13. //Удаляет у-элементов из основного списка
  14. (defun cdrf (x y)
  15. (setq buf x)
  16. (loop
  17. (if (> y 0)
  18. (setq buf (cdr x))
  19. (return buf))
  20. (- y 1)))
  21. //Основная функция, которая будет увеличивать y для передачи в f1, и создаст главный список с подсписками
  22. (defun f (x)
  23. (setq buf nil)
  24. (setq y 1)
  25. (loop
  26. (if (null (car x)) (return buf)
  27. (setq buf (append buf (list (f1 (car x) y))))
  28. (setq x (cdrf x y))
  29. (setq y (+ y 1))
  30. )))

Решение задачи: «Поделить список на подсписки длинны 1, 2, 3»

textual
Листинг программы
  1. (defun task (lst)
  2.   (let ((r nil) (acc nil) (n 1))
  3.      (dolist (x lst nil)
  4.        (push x acc)
  5.        (when (= n (length acc)) (push (reverse acc) r) (setq n (+ 1 n) acc nil)))
  6.      (when (> (length acc) 0) (push (reverse acc) r))
  7.      (reverse r)))
  8.        
  9.  
  10. ==> TASK
  11.  
  12. (task '(1 2 3 4 5 6 7 8 9 10 11 12))
  13.  
  14. ==> ((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

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы