Лисп печатает две строки вместо одной - PullRequest
1 голос
/ 05 июля 2019

Это мой код:


(defun count-toys (sorted budget spent num-bought)
    (cond ((> spent budget) (- num-bought 1))
          ((count-toys (cdr sorted) 
                       budget 
                       (+ spent (car sorted)) 
                       (+ num-bought 1)))))

(defun maxToys (numToys budget prices)
  (setq sorted (sort prices #'<))
  (count-toys sorted budget 0 0))

(print (maxToys numToys budget prices))

В последней строке есть оператор print, который печатает решение, возвращаемое функцией count-toys. Однако перед печатью решения lisp также печатает пустую строку.


3

Как мне избавиться от пустой строки?

Ответы [ 2 ]

3 голосов
/ 05 июля 2019

Мой код на вашем коде:

(defvar *prices* '(45 87 897 565 8 57 875 59))
(defvar *budget* 1000)

(defun count-toys (sorted budget spent num-bought)
  (if (not (and sorted (>= budget (+ spent (car sorted)))))
      num-bought
      (count-toys (cdr sorted) budget (+ spent (car sorted))
          (1+ num-bought))))

(defun max-toys (budget prices)
  (let ((sorted (sort (copy-list prices) #'<)))
    (count-toys sorted budget 0 0)))

(prin1 (max-toys *budget* *prices*))

Пример вывода:

USER> (prin1 (max-toys 100 '(5)))
1
1
USER> (prin1 (max-toys 100 '(101)))
0
0
USER> (prin1 (max-toys 100 '(70 20)))
2
2
USER> (prin1 (max-toys 100 '(70 10 20)))
3
3
USER> (prin1 (max-toys 100 '(70 10 21)))
2
2
USER> (sort *prices* #'<)
(45 57 59 87 565 875 897)
USER> (prin1 (max-toys *budget* *prices*))
5
5

Нет необходимости в переменной numToys (она не используется). Я написал max-toys вместо maxToys: это больше "Lispy" (но я не догматичный в этом вопросе ...) И (опять же, как сказал Райнер) использование prin1 вместо print позволяет избежать лишних пробелов строка перед выводом.

1 голос
/ 05 июля 2019

Вот LOOP версия:

(defun spend-greedily (prices budget)
  (loop
     for spent = 0 then next-spent
     for count from 0
     for price in prices
     for next-spent = (+ spent price)
     while (< next-spent budget)
     finally (return
               (values count spent))))

Обратите внимание, что итерация останавливается, когда в prices нет элемента price или когда следующие расходы превысят бюджет. Я также возвращаю общую сумму, потраченную в дополнение к количеству.

(assert (equalp
         (loop
            for budget in '(3 10 20 28 29 100)
            collect (list budget
                          (multiple-value-list
                           (spend-greedily '(5 10 13 20) budget))))
         '((3 (0 0))
           (10 (1 5))
           (20 (2 15))
           (28 (2 15))
           (29 (3 28))
           (100 (4 48)))))

Если вы сортируете последовательность, обратите внимание:

  • SORT является деструктивным, и может повторно использовать исходное хранилище последовательностей любым удобным для него способом. Копировать или нет оригинальную последовательность (copy-seq (или copy-list)) - вопрос владение ; в случае сомнений или с буквальными данными вы должны отсортировать копию.

  • Но , вы не должны больше использовать исходную последовательность, вы должны использовать возвращаемое значение из sort. Это имеет смысл, если вы рассматриваете список как цепочку понятий, которым sort разрешено связывать другим способом. Тогда ваш первый список, который является главой оригинальной цепочки выражений, может фактически оказаться в середине отсортированного списка. Или структура цепочки может быть сохранена, но CAR каждого списка изменяется. Фактические побочные эффекты, которые происходят с последовательностью, однако, не определены.

  • Подумайте об использовании STABLE-SORT для управления тем, что происходит с парой предметов, равных w.r.t. Ваша функция сравнения: пары (x, y) , так что ни x , ни y для пользовательского <</em>. Это не важно в вашем случае, так как равные числа неразличимы, но с некоторыми объектами вы можете получить произвольный порядок для элементов, которые полагаются на детали реализации, а не на свойства объекта.

...