Красивая формула Бине для чисел Фибоначчи содержит иррациональность - квадратный корень из пяти, что делает ее непригодной для точного вычисления больших чисел Фибоначчи. Это кажется вполне очевидным. Предлагаю способ, как избавиться от зловредного корня и сделать формулу Бине пригодной для точных вычислений.
Пользователь
Мемоизация в Лиспе
В заметке подробно рассматривается суть понятия "мемоизация" и разбирается работоспособная версия мемоизации произвольных функций Лиспа. Предполагается, что читатель знаком с Лиспом. Тем не менее, "тонкие места" разбираются достаточно подробно.
Задача о m максимумах
Старая-старая школьно-студенческая задача... Дан массив целых чисел. Требуется найти m его максимальных (или минимальных) элементов. Когда я задаю эту задачу учащимся, то почти в каждой группе находятся "умельцы", решающие ее с помощью сортировки. В самом деле, это ведь так просто: сортируем массив по убыванию (вручную или подходящей библиотечной функцией) и просто берем m первых элементов. Конечно, иначе как алгоритмическим варварством такой подход не назовешь - найти m максимумов достаточно просто за один проход массива; сортировка существенно сложнее. И однажды я решил исследовать сей вопрос вычислительными экспериментами. Результаты этих экспериментов я и предлагаю вашему вниманию. Не исключено, что кому-то результаты помогут и в практической работе.
Без сортировки задача может быть решена, например, так. Создаем рабочий массив длины m и заполняем его начальными значениями. В общем случае можно в качестве такого значения выбрать минимальное значение int/integer для соответствующей среды программирования. А если известна нижняя граница значений исходного массива, то можно взять любое число, меньшее этой границы.
Итак рабочий массив заполнен одинаковыми значениями. Теперь берем элемент за элементом исходного массива и вставляем его в нужное место рабочего массива. При этом длину рабочего массива сохраняем равной m. Если очередной элемент меньше последнего значения рабочего массива, то он просто пропускается. Этот процесс имеет вычислительную сложность O(n*m).
Цена естественности или как обогнать QuickSort
Частичное применение и «каррирование» функций в Лиспе
В этой небольшой заметке мы рассмотрим, как можно реализовать в Лиспе такой, весьма популярный ныне программный механизм, как частичное применение функций. При этом я буду использовать свою реализацию Homelisp (это чистый интерпретатор Лиспа с некоторыми дополнительными возможностями).
Вероятно, использование частичного применения в Common Lisp будет не очень простым (в связи с тем, что для вызова вычисляемого функционального объекта нужно использовать funcall/apply); в Scheme дело должно обстоять проще. В ближайшее время я планирую опубликовать новую версию HomeLisp, в котором для вызова вычисляемого функционального объекта не требуется funcall/apply. В тех случаях, когда поведение кода отличается, я буду это подчёркивать.
Частичное применение — это строгая математическая операция. Но мы рассмотрим ее «на пальцах», без обращения к лямбда-исчислению и комбинаторной логике.
Вычисляем определитель матрицы на Хаскелле
Немного теории
Как известно, определитель квадратной матрицы n*n — это сумма n! слагаемых, каждое из которых есть произведение, содержащее ровно по одному элементу матрицы из каждого столбца и ровно по одному из каждой строки. Знак очередного произведения:
определяется чётностью подстановки:
Функциональные интерфейсы… в VBA
Брюс Мак-Кинни “Крепкий орешек Visual Basic”
Введение
Постоянный интерес к подходам функционального программирования в настоящее время приводит к тому, что традиционные языки программирования активно обзаводятся функциональными средствами. И, хотя чистые функциональные языки остаются пока не слишком популярными, функциональные возможности прочно обосновались в таких языках, как С++, Java, JavaScript, Python и др. Язык VBA уже многие годы пользуется заслуженной популярностью у довольно многочисленной аудитории пользователей Microsoft Office, однако этот язык практически не содержит функциональных средств.
Давайте попытаемся заполнить этого пробел – предлагаю законченную (хотя, возможно, и не безупречную) реализацию функциональных интерфейсов, выполненную средствами VBA. Реализация может служить основой для последующих доработок и улучшений.
Пишем простой транслятор на Лиспе — III
Ошибки, Ошибки, Ошибки…
Хорошая программа должна быть защищена от ошибок пользователя. Это совершенно бесспорно. Ошибки нужно обрабатывать, а еще лучше – предупреждать (профилактика всегда лучше лечения!). Высший пилотаж – так выстроить диалог с пользователем, чтобы последний просто не мог совершить ошибку.
Пишем простой транслятор на Лиспе — II
Реализуем оператор присвоения
А теперь научим транслятор обрабатывать оператор присвоения. И здесь перед нами встает классическая задача – обеспечить вычисление алгебраической формулы, заданной в привычной для нас со школьных лет записи. Если бы мы делали интерпретатор, то нам бы понадобилось вычислять значение формулы. В нашем же случае вычислять (во время выполнения) будет ядро Лиспа. А нам нужно всего лишь преобразовать формулу из привычной нам записи в лисповскую.
Привычная нам запись называется “инфиксной нотацией” (знак операции располагается между операндами). В Лиспе знак операции располагается перед операндами (такая запись называется “префиксной нотацией”). Таким образом, наша задача состоит в преобразовании инфиксной формы в префиксную.
Решать эту задачу можно разными путями…
Пишем простой транслятор на Лиспе — I
Давайте попробуем написать на Лиспе… транслятор простого императивного языка. Нет-нет, я не ошибся – именно транслятор. Транслировать он будет в Лисп-код. А дальше этот код может быть выполнен Лисп-системой.
Здесь бесценную услугу нам окажет то обстоятельство, что в Лиспе нет барьера между кодом и данными (это редкое свойство некоторых языков программирования называется “гомоиконность”). Но и изобразительные возможности Лиспа тоже сыграют не последнюю роль.
В качестве реализации я буду использовать HomeLisp. Желающие смогут адаптировать этот проект под Common Lisp. Скажу сразу – применительно к рассматриваемой задаче существенная разница между Common Lisp и HomeLisp состоит только в обработке строк и файлов.
Скачать портабельную версию HomeLisp можно по ссылке. На этом же сайте расположена и документация. Желающие могут копировать код из статьи и сразу проверять работоспособность.
Предлагаемая вашему вниманию тема послужила основой для моей мастерской на знаменитой Новосибирской ЛШЮП-2018. С результатами мастерской можно ознакомиться здесь. А далее я излагаю свой подход. Предполагаю, что читатель знаком с языком Лисп.
Приступаем
Начнем с “простого императивного языка”, который мы будем транслировать в Лисп.
Язык будет обрабатывать только числовые данные. Код на этом языке состоит из функций (процедур, возвращающих значения). Среди этих функций одна должна называться main. Именно с этой функции начинается выполнение кода. Хотя зачем так себя связывать? Пишем функции на императивном языке, они транслируются в Лисп и могут использоваться вместе с лисповскими функциями. Но не будем забегать вперед...
HomeLisp два года спустя
Что же произошло за эти два года с проектом?
Information
- Rating
- Does not participate
- Location
- Россия
- Date of birth
- Registered
- Activity