Нашли или выдавили из себя код, который нельзя назвать нормальным,
на который без улыбки не взглянешь?
Не торопитесь его удалять или рефакторить, — запостите его на
говнокод.ру, посмеёмся вместе!
;;; Returns a string and 'T' if the list is in a desc. or asc. order, and NIL otherwise
(defun ordered (list)
(let ((list-dec (copy-list list)))
(let ((list-inc (copy-list list)))
(let ((alist (sort list-inc #'<)))
(let ((dlist (sort list-dec #'>)))
(cond
((equal list dlist)
(format nil "~%The numbers in ~a are in a descending order. ~%T" list))
((equal list alist)
(format nil "~%The numbers in ~a are in an ascending order. ~%T" list))))))))
Задача была следующей: функция должна возвращать t (истина), если в списке все элементы либо в восходящем, либо в нисходящем порядкe, и соответсвенно nil (ложь), если нет. Думаю, вполне сгодится сюда :) http://www.lispforum.com/viewtopic.php?f=2&t=1275
Чушь какая-то. Половина let'ов не нужна, у cond'а нет умолчательной ветки, функция вместо того, чтобы возвращать T или NIL выводит какие-то письмена.
Это что, опаскаленного учат языку программирования?
UPD Вру, ни один let не нужен. И cond не нужен. И говнокод этот тут не нужен, ибо уныл.
Почему? Если не принимать во внимание недочеты реализации, то говнозадумка автора не так частво тут встречалась (я так вообще ни разу не видел). По-моему идея отсортировать список, а потом сравнить с исходником, вместо того, чтобы проверить исходный список вполне достойна этого сайта, вне зависимости от языка.
Идея-то плюс-минус нормальная, позволяет решить проблему за пару строчек тупого понятного кода. KISS во всей своей красе.
Уродство в имплементации: 4 уровня let'ов, cond без t-случая. Говно в том, что на неплохую задумку осуществили через задницу. Это не весело и красиво, это грустно и уродливо (и при этом не на PHP).
Это красивше, но в зависимости от реализации будут ограничения на длину списка. Т.е. По стандарту не сказано сколько именно максимально параметров может принимать функция, но, практически наверняка, если в списке будет ~1000 елементов, такой код не будет работать.
Похвалю Конфуция с lispforum'а и себя любимого заодно. Это решение основано на двух полезных фишках: apply и семантике функций < и >. Постижению дао юными дарованиями очень помогает.
Ну а длинные списки - это да, тут не отвертеться.
Подумал. Там сказано "ascending or descending order". Т.е. "в возрастающем или убывающем порядке". Там не сказано "в неубывающем или невозрастающем порядке".
Не забывайте, тут есть еще такой момент, что у вашего варианта есть худший и лучший случаи, худший, это когда: '(1 1 1 1 1 1 1 1 ... 2) то обе ветки (or ...) переберут почти весь список с самого начала 😉
Собственно вот, вариант конечно гораздо длиннее, но так же учитывает этот момент:
1. А вы как думаете? (я честно не знаю).
2. Потому что маловероятно, что именно эта ветка будет выбиратся чаще.
3. CL не гарантирует оптимизации рекурсии, зачем рисковать? 🙂
1. внутренний цикл рассчитывает определиться со знаком, в случае '(1 1) будет проблема (сначала проверил на `elisp', подтвердил `sbcl').
2. Пожалуй, да. Зато симпотичней.
3. CL (и стандарты) знаю плохо, но об этом в курсе, впрочем есть и `sbcl'... И вообще, схема же для лаб адекватнее.
Ну это как деление на ноль - я не знаю, что должно получится, вот и нет ответа 🙂 Вы можете сказать, расположены ли все элементы списка состоящего только из одинаковых элементов в восходящем или нисходящем порядке? Кстати, я вот подумал на счет моего предыдущего коментария по поводу пустого списка - это, в общем, та же ситуация, так что наверное лучше ошибку, чем как-нибудь ответ.
На чем писать я не выбирал, да и вообще, язык на котором это написано тут ни при чем, напишите то же самое на Си, тот же эффект будет.
ЗЫ. SBCL - Steel Bank Common Lisp - т.е. одна из реализаций CL (Common Lisp).
> я не знаю, что должно получится, вот и нет ответа 🙂
> (if ... '>= '<=)
> asc-or-desc
непоследовательно (не нужно asc или desc отдельно, нужно or), этот случай-таки имелся ввиду при написании? 😉
> SBCL - Steel Bank Common Lisp - т.е. одна из реализаций CL (Common Lisp)
спасибо, но `sbcl' и приводился как пример открытой реализации с "tail-call optimization"
Как вы можете утверждать, что суждение соответстует хотя бы одному из двух предположений, когда нет возможности установить, что оно наверняка соответствует либо первому, либо второму? Это, как по мне, классический случай нул-гипотезы (т.е., когда отрицание отрицания утверждения не делает утверждение истинным). 🙂
1. Используется немотонный порядок
2. Возвращаемый тип -- Bool
(конкретно в этом подходе; можно было бы возвращать 'eq | 'asc | 'desc, не знаю есть ли готовый тип)
'(1 1) - упорядочен и по неубыванию, и невозрастанию, имхо, пользующийся функцией ожидал бы t.
Кстати, меня тут по этому поводу просветили знающие люди: http://en.wikipedia.org/wiki/Vacuous_truth Из чего следует, что на вопрос "упорядочена ли последовательность из одинаковых чисел (в том числе и пустая последовательность) в восходящем порядке, или нисходящем порядке?" можно ответить утвердительно. Но мне это все равно не нравится 🙂
CL не более функциональный язык, чем JavaScript... И как бы странно было бы игнорировать лабы, если большинство кода, который пишется сегодня на любом из Лиспов, это академия тем или иным образом, а для IT / web / desktop программирования его очень редко используют...
Это что, опаскаленного учат языку программирования?
UPD Вру, ни один let не нужен. И cond не нужен. И говнокод этот тут не нужен, ибо уныл.
Уродство в имплементации: 4 уровня let'ов, cond без t-случая. Говно в том, что на неплохую задумку осуществили через задницу. Это не весело и красиво, это грустно и уродливо (и при этом не на PHP).
Ну а длинные списки - это да, тут не отвертеться.
Собственно вот, вариант конечно гораздо длиннее, но так же учитывает этот момент:
Нельзя ли просто рекурсивно вызвать `asc-or-desc' если car = cadr? И поцчему t в ядренях, а не под if.
зы... на хаскеле читабельнее (впрочем, полагаю, что и на схеме тоже).
2. Потому что маловероятно, что именно эта ветка будет выбиратся чаще.
3. CL не гарантирует оптимизации рекурсии, зачем рисковать? 🙂
2. Пожалуй, да. Зато симпотичней.
3. CL (и стандарты) знаю плохо, но об этом в курсе, впрочем есть и `sbcl'... И вообще, схема же для лаб адекватнее.
На чем писать я не выбирал, да и вообще, язык на котором это написано тут ни при чем, напишите то же самое на Си, тот же эффект будет.
ЗЫ. SBCL - Steel Bank Common Lisp - т.е. одна из реализаций CL (Common Lisp).
> (if ... '>= '<=)
> asc-or-desc
непоследовательно (не нужно asc или desc отдельно, нужно or), этот случай-таки имелся ввиду при написании? 😉
> SBCL - Steel Bank Common Lisp - т.е. одна из реализаций CL (Common Lisp)
спасибо, но `sbcl' и приводился как пример открытой реализации с "tail-call optimization"
2. Возвращаемый тип -- Bool
(конкретно в этом подходе; можно было бы возвращать 'eq | 'asc | 'desc, не знаю есть ли готовый тип)
'(1 1) - упорядочен и по неубыванию, и невозрастанию, имхо, пользующийся функцией ожидал бы t.
Все функциональные боги считают, что на лиспе лаб не бывает.