|
84 / 83 / 8
Регистрация: 31.03.2015
Сообщений: 447
|
|
Clojure Найти наибольшую последовательность чисел в списке26.10.2015, 20:31. Показов 6346. Ответов 84
Метки нет (Все метки)
Нужно найти в списке самую длинную убывающую или растущую последовательность чисел
Например Вводим список 8 4 2 3 2 Получаем две последовательности 8 4 2 и 3 2, нам нужен 8 4 2 так как он длиннее.
0
|
|
| 26.10.2015, 20:31 | |
|
Ответы с готовыми решениями:
84
В одномерном массиве найти наибольшую последовательность из отрицательных чисел и вывести ее В одномерном масстве найти наибольшую последовательность из отрицаельных чисел и перенести ее в конец массива Вводится последовательность из N целых чисел. Найти наибольшую по значению четную цифру в каждом числе. |
|
84 / 83 / 8
Регистрация: 31.03.2015
Сообщений: 447
|
|
| 27.10.2015, 02:01 [ТС] | |
|
0
|
|
| 27.10.2015, 02:08 | ||||||
|
Да, и в при проверке на null? надо конечно выбрать из текущего результата и аккумулятора
Vaderkos, это хорошо, что не знаете - будете хоть немного думать сами.
0
|
||||||
|
84 / 83 / 8
Регистрация: 31.03.2015
Сообщений: 447
|
|||||||||||
| 27.10.2015, 02:52 [ТС] | |||||||||||
|
Почему цикл останавливается после первого второго раза?
Добавлено через 5 минут По-моему заработало?
Не пошло, опять( Добавлено через 7 минут Помоему, я все-таки нашел ошибку ![]()
0
|
|||||||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|||||||||||||||||||||
| 27.10.2015, 03:58 | |||||||||||||||||||||
|
Vaderkos, по-моему, всё правильно. Замечательно! Можете быть довольны собой, задача решена.
![]() Вот вам бонус. Во-первых, функцию резко можно сделать гораздо более универсальной. Дело в том, что сравнение с помощью >= можно не хардкодить, а задавать в качестве аргумента функции. Даже в си можно передавать аргументом ссылку на функцию, а в лиспе функции вообще граждане первого класса, можно обращаться с ними как с любыми другими объектами. Получа ется код такой:
В-четвёртых ― самое главное ― я добавил аргумент test ― функцию сравнения. Эта функция вызывается вместо <=. Здесь приходится писать funcall ― коряво с точки зрения функционального программирования. Почему мы не можем написать (test el (first temp))? Потому что символ на первом месте списка должен быть именем функции. А test ― имя переменной. В Common Lisp имена функций и переменных существуют независимо друг от друга (например, я назвал аргумент функции list, что никак не затеняет функцию list). Funcall используется, чтобы вытащить функцию из переменной test. К двум пространствам имён надо привыкнуть. Теперь вы можете писать, например,
Чтобы получить по имени функцию саму функцию, используется специальный оператор function. Так, < ― имя функции «меньше», (function <) ― сама функция «меньше». Сокращённо то же самое записывается #'<. Таким образом, в функцию find-longest передаются сами функции. Ту же функцию можно применять, например, к спискам символов, сравнивая их с помощью char< или подобных функций, и ещё много к чему. Не так сложно было бы добавить опциональный аргумент key, как у некоторых стандартных функций, тогда функций стала бы ещё более универсальной (например, можно было бы рассматривать списки строк и находить наибольшие подсписки с возрастающей длиной). Мораль: возможность передавать в функцию функциональные аргументы может многократно увеличивать её полезность. Таким образом, ваша обёртка может быть такая:
Такая функция достаточно эффективно работает и с длинными списками. Но за два прохода. Если у вас огромные совокупности данных, то, может быть, имело бы смысл не собирать их в список, а рассматривать их по одному, навроде генератора. Тогда мы не можем позволить себе два прохода, и нужны функции чуть посложнее. Если интересует, могу рассказать.
1
|
|||||||||||||||||||||
| 27.10.2015, 04:00 | ||||||
|
Без реверсов. Все-таки динамическая типизация в данном примере сильно усложняет написание кода - конструировать и разбирать пары-тройки, реализованные через списки, и элементами которых также могут быть списки, достаточно нудно, и главное - компилятор всегда все воспринимает как должное, даже если ты ошибся, и не подскажет.
1
|
||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
||||||
| 27.10.2015, 04:07 | ||||||
|
Не очень элегантно смотрится дублирование кода проверки. В принципе, можно создать для него локальную функцию. Я помещу её объявление внутрь объявлений переменных, чтобы она имела к ним доступ:
Добавлено через 5 минут А, забыл ещё. Алгоритм-то для непустых списков, так что надо изначально сделать проверку на пустоту и для пустого вернуть (values nil 0).
2
|
||||||
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
||||||
| 27.10.2015, 08:51 | ||||||
|
как вариант:
2
|
||||||
|
84 / 83 / 8
Регистрация: 31.03.2015
Сообщений: 447
|
|
| 27.10.2015, 12:16 [ТС] | |
|
helter, Еще вопрос, допустим по убыванию нашли список равный найденному списку по возрастанию, по заданию нам нужно вернуть тот список который стоит раньше, нужно ввести переменную счетчик для такого случая?
Добавлено через 17 минут Не список а последовательность Добавлено через 1 час 24 минуты helter, да я хотел на ходу считать поэтому я и считывать и решать пытался одновременно в самом начале так как чисел от 0 до 10в7 а ращмер каждого от 0до 10 в 9. Даже сейчас я из-за этого получаю ошибку в части тестов.
0
|
|
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
||||||||||||||||||||||||||||
| 27.10.2015, 15:50 | ||||||||||||||||||||||||||||
Ну да, можно ещё одну переменную. Надо будет добавить её в let и внутрь update-longest. Вот чем хорошо, когда код не дублируется: изменения вносятся только в одном месте. И можно возвращать позицию третьим значением.Добавлено через 1 час 47 минут Чтобы работать с последовательными числами, мы используем замыкания. Замыкание ― это функция вместе с какими-то внешними данными. Сначала ― простейший пример. Убедитесь, что он понятен.
Здесь внутренний let возвращает функцию (лямбду), которую мы связываем с переменной c. Эта лямбда имеет доступ к переменной i. Когда мы вызываем лямбду, она увеличивает i на 1 и возвращает увеличенное значение. Так что когда внизу мы вызываем эту лямбду 3 раза, она печатает сначала 1 (при этом становится i = 1), потом ― 2, потом ― 3. То есть лямбда помнит переменную i, в контексте которой она определялась. При этом сама переменная i уже не видна за пределами внутреннего let-а. Вот я попробую её использовать:
Предположим, вам понравились счётчики, и вы хотите их много-много в своей программе. Тогда вам нужна функция, создающая счётчики. Это значит, нужна лямбда над летом над лямбдой. ![]()
Конечно, замыкать можно любые лексические переменные, а не только созданные с помощью let. Например, лексическими переменными являются формальные параметры в теле defun-а. Можно модифицировать make-counter, задавая начальное значение:
3
|
||||||||||||||||||||||||||||
| 27.10.2015, 19:56 | |||||||||||
|
Не по теме:
Код
0
|
|||||||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
||||||||||||||||
| 27.10.2015, 20:01 | ||||||||||||||||
|
Теперь мы попробуем применить замыкания к нашей задаче.
Идея ― иметь функцию, которой «скармливаются» последовательные элементы последовательности, и которая внутри запоминает информацию о длиннейших монотоных подпоследовательностям. Раньше у нас «скармливанием» занимался dolist внутри функции. Теперь механизм итерирования выносится из функции. То есть я хочу иметь что-то такое:
Чтобы переделать код find-longest в код longfinder, по сути надо «вынести за лямбду» все переменные, кроме el, и вернуть лямбду, зависящую от el. Я сделаю небольшие модификации алгоритма. Во-первых, замыкание никак не знает, последний элемент ему передали или нет. Либо вводить способ оповещения, что аргумент последний, либо делать апдейт длиннейшего списка на каждой итерации. Я выбираю второе: проигрывается несколько присваиваний, что, думаю, некритично; зато просто. Во-вторых, я буду первый элемент обрабатывать по тем же правилам, как и остальные. Для этого я temp изначально выставляю в nil, и в цикле делаю проверку, пустой он или нет. Опять же, не думаю, что эта проверка критично отзовётся на производительности. В качестве значений замыкание каждый раз будет возвращать перевёрнутую длиннейшую монотонную последовательность, её длину и позицию начала. В примере выше я каждый раз присваиваю возвращаемые значения переменным longest, long-len и long-pos (не тем, которые в функции), и возвращаю последнее присвоенное значение. Код longfinder:
Вывод: по функциональности longfinder эквивалентна find-longest ― это универсальная функция, принимающая различные тестовые функции. Разница в интерфейсе: find-longest работает только по списку, longfinder возвращает замыкания, принимающие значения последовательности одно за другим. find-longest ― простенькая функция, аналог которой можно было бы написать на многих языках (хотя функциональный аргумент делает её очень гибкой). longfinder ― более интересная и более лиспоспецифичная. Common Lisp не функционален по мелочам, но важные идеи из функционального программирования он содержит. Замыкания ― одна из них.
4
|
||||||||||||||||
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
|||||||||||||||||||||
| 28.10.2015, 09:34 | |||||||||||||||||||||
на одном *w*:
2
|
|||||||||||||||||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|||||||||||
| 28.10.2015, 12:56 | |||||||||||
|
_sg, не могу повторить ваших результатов. Тот же самый, в принципе, код:
2
|
|||||||||||
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
||||||
| 28.10.2015, 13:13 | ||||||
|
helter, мистика.
Добавлено через 8 минут
2
|
||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
| 28.10.2015, 13:14 | |
|
По-моему, мистика — что у вас нехвостовая рекурсия глубины 10^6 в принципе заработала на CLISPе. Это ещё удивительнее, чем что она за два прохода обогнала однопроходный алгоритм с циклом.
Я хотел уточнить: на момент замера времени у вас функции были скомпилированные?
0
|
|
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
||||||
| 28.10.2015, 13:23 | ||||||
SBCL Добавлено через 4 минуты Да, скомпилированые. Возможно, СLISP тормозит вызов helter из REPL. Добавлено через 1 минуту а SBCL компилирует из REPL.
2
|
||||||
|
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
|
|
| 28.10.2015, 13:27 | |
|
SBCL в принципе компилирует всё, у него других опций нет. В общем случае, если функция helter скомпилирована, она должна возвращать скомпилированные замыкания, так что проблем от REPLа не должно быть.
0
|
|
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
||||||
| 28.10.2015, 13:52 | ||||||
|
или max-length-seq работает некорректно?
Добавлено через 23 минуты у меня max-length-seq в обеих реализациях отрабатывает за 3 с., helter в CLISP -30 c., в SBCL - 0,4 c., возможно CLISP тормозит в отличие от SBCL вызов из REPL конструкции:
0
|
||||||
|
Супер-модератор
|
||||||
| 29.10.2015, 11:47 | ||||||
|
До кучи:
2
|
||||||
|
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
|
||||||||||||||||
| 29.10.2015, 18:09 | ||||||||||||||||
helter, на одном *w*:
Catstail, (range 1 n) > (loop for m from 1 to n collect m) ?
2
|
||||||||||||||||
| 29.10.2015, 18:09 | |
|
Найти наибольшую неубывающую последовательность
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . .
Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
|
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг.
Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует.
В процессе разработки. . .
|
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
|
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации:
1. Вернуть возможность использования знаков | 1 l I;. . .
|
|
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С.
Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
|
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию?
Фраза «Любая достаточно развитая технология неотличима от магии». . .
|
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль?
Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
|
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология.
«Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
|