Большая задачка - 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 Вот то, что уже сделано Не знаю как сделать цикличный проход по спискам. И вообще что-то не так получается((
(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
 
*
Вот, что получается, не знаю почему pos перескакивает на 4(
Забыл добавить лимиты По времени 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, которая добавляет новый элемент в список. Список представлен в виде связного списка, состоящего из элементов, каждый из которых содержит два поля: значение и ссылки на предыдущий и следующий элементы.

  1. Создается новый элемент с заданным значением с помощью функции make-element.
  2. Если список пуст, то новый элемент становится первым в списке.
  3. Если список не пуст, то в текущем элементе списка (который является последним) устанавливается ссылка на новый элемент.
  4. Новый элемент устанавливается в качестве последнего элемента списка.
  5. Возвращается новый список.

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


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

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

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