Большая задачка - Lisp
Формулировка задачи:
Большая задача.
Есть список натуральных чисел С, в котором есть указатель POS. Для списка есть две операции:
-R, удаляет элемент с индексом pos+1, изменяет позицию на pos+ element
-X, вставляет после элемента для которого дана позиция этот же елемент-1, изменяет позицию на pos+element
Изначально pos указывает на первый элемент С (если такой существует) Выполнить н-количество операций на С. В случае если элемент на позиции четный выполнить операцию R, если нечетный - Х. Указатель pos передвигается циклично по списку.
Ввод
- н (количество операций) + знак пробела (kod ASCII 32),
- элементы списка С, разделенные пробелом и завершенные знаком EOF.
Вывод:
Все числа списка циклично начиная от pos
В случае пустого списка вывести -1
Длина С [0,10^7]. Н <= 10^7. Количество передвижений Pos [0,10^9]
Пример
Ввод:
3 1 2 3
Вывод:
0 0 1 3
Операции:
Н=1: С: 1 2 3
POS->1
Операция: X, элемент=1
С: 1 0 2 3
POS->0
Н=2: С: 1 0 2 3
POS->0
Операция: R, элемент=2
С: 1 0 3
POS->1
Н=3: С: 1 0 3
POS->1
Операция: X, c=1
С: 1 0 0 3
POS->0
Вот то, что уже сделано
Не знаю как сделать цикличный проход по спискам. И вообще что-то не так получается((
Вот, что получается, не знаю почему pos перескакивает на 4(
(defun get-integer (&optional (stream *standard-input*)) "GET INTEGER FROM STREAM" (declare (optimize (speed 3) (safety 0) (space 0) (debug 0))) (let ((digit (read-char stream nil)) (number 0)) (declare (type fixnum number)) (if digit (loop (setf number (the fixnum (+ (the fixnum (* 10 number)) (the fixnum (- (char-code digit) (char-code #\0))))) digit (read-char stream nil)) (unless (and digit (digit-char-p digit)) (return (values number digit)))) (values nil nil)))) (defun get-int-list () "GET LIST OF INTEGERS FROM *STANDART-INPUT*" (let ((elem nil)) (loop (multiple-value-bind (n c) (get-integer) (cond ((null n) (return)) ((null c) (push n elem) (return)) (t (push n elem))))) (nreverse elem))) (defun del-by-pos (pos lst) "DELETE ELEMENT ON CERTAIN POSITION" (loop :for x :in lst :for i :from 0 :unless (= i pos) :collect x)) (defun insert-by-pos (pos lst el) "INSERT ELEMENT TO CERTAIN POSITION" (let ((fst (subseq lst 0 pos)) (scnd (subseq lst pos))) (push el scnd) (concatenate 'list fst scnd))) (defun X (pos lst) "FOR ODD element INSERT (- ELEMENT 1) AFTER GIVEN POSITION AND INCREMENT POSITION ON ELEMENT" (let ((el (nth pos lst))) (values (insert-by-pos (+ pos 1) lst (- el 1)) (+ pos el)))) (defun R (pos lst) "FOR EVEN element DELETE ELEMENT AFTER GIVEN POSITION AND INCREMENT POSITION ON ELEMENT" (let ((el (nth pos lst))) (values (del-by-pos (+ pos 1) lst) (+ pos el)))) (defun get-result (iter lst pos) "Get result?" (dotimes (i iter) (cond ((evenp pos) (format t "R ~s ~s ---> " lst pos) (multiple-value-setq (lst pos) (R pos lst)) (format t "R ~s ~s ~%" lst pos)) ((oddp pos) (format t "R ~s ~s ---> " lst pos) (multiple-value-setq (lst pos) (R pos lst)) (format t "R ~s ~s ~%" lst pos)))) lst) * (GET-RESULT 3 `(1 2 3) 0) R (1 2 3) 0 ---> R (1 3) 1 R (1 3) 1 ---> R (1 3) 4 R (1 3) 4 ---> debugger invoked on a SIMPLE-TYPE-ERROR in thread #<THREAD "main thread" RUNNING {1002AFBD43}>: Argument Y is not a NUMBER: NIL Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT] Exit debugger, returning to top level. (SB-KERNEL:TWO-ARG-+ 4 NIL) 0] 0 *
Забыл добавить лимиты
По времени O(tn), По памяти O(n),где n начальная длина С, t количество повторений R и X.
Решение задачи: «Большая задачка»
textual
Листинг программы
(defun add-el (lst val) (let ((el (make-element :value val))) (cond ((null lst) (setf (element-next el) el)) (t (setf (element-prev el) (element-prev lst)) (setf (element-prev lst) el) (setf (element-next el) lst))) (setf lst el) lst))
Объяснение кода листинга программы
В данном коде реализована функция add-el, которая добавляет новый элемент в список. Список представлен в виде связного списка, состоящего из элементов, каждый из которых содержит два поля: значение и ссылки на предыдущий и следующий элементы.
- Создается новый элемент с заданным значением с помощью функции make-element.
- Если список пуст, то новый элемент становится первым в списке.
- Если список не пуст, то в текущем элементе списка (который является последним) устанавливается ссылка на новый элемент.
- Новый элемент устанавливается в качестве последнего элемента списка.
- Возвращается новый список.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д