Лидеры
Популярный контент
Показан контент с высокой репутацией 06.03.2022 во всех областях
-
3 баллаLost User - Самый Простой Робот Зачем? Роботы OC сложны в сборке и программировании. Эта программа BIOS помогает использовать роботов как "пользователей" и многими другими способами. Установка Сборка Соберите робота в минимальной конфигурации: Корпус ЦПУ ОЗУ E2E-E Если вы играете в Enigmatica 2: Expert - Extended, в модпаке есть предопределенный рецепт EEPROM. Найдите его в JEI и создайте. У него будет цветное свечение. Если вы его создали, можете пропустить следующий шаг Запись программы на EEPROM. Запись программы на EEPROM Скачайте файл из интернета (требуется ), запустите из командной строки: wget https://raw.githubusercontent.com/Krutoy242/lostuser/main/lostuser.min.lua Чтобы записать на существующий EEPROM, запустите: flash -q lostuser.min.lua LostUser Вставка в робота Возьмите EEPROM из корпуса компьютера и вставьте его в робота. Использование Программируйте робота, переименовывая его. Переименуйте робота на или с помощью . Назовите вашего робота robot.use(3), поставьте его на землю, включите и смотрите, как он кликает блоки перед собой. Синтаксис Кратко Если вы не хотите изучать Lua и вам нужно, чтобы робот кликал правой/левой кнопкой мыши, вот несколько простых имен для робота и результат: robot.use(3) - Робот будет кликать правой кнопкой мыши по блоку перед собой. robot.swing(3) - Робот будет махать мечом или ломать блок перед собой. Операторы и выражения Выполнение Робот будет выполнять свое имя как код Lua в цикле while true. Код может быть выполнен в любом варианте - оператор или выражение, но все равно должен следовать правилам потока кода Lua. Возврат Если выражение возвращает одну или несколько функций, они будут выполнены рекурсивно. Обратите внимание, что все возвращаемые значения рассчитываются сначала, и только потом будут вызваны функции. Глобальные переменные Все компоненты доступны как глобальные переменные. Компоненты сортируются естественным образом и добавляются в глобальные переменные по первой большой букве. C => computer E => eeprom I => inventory_controller R => robot T => trading ... Дополнительные глобальные переменные: i - текущий индекс цикла, начиная с 0. sleep(seconds: number = 1) write(...) - ошибка с сериализованным выводом. api(shortName: string, obj?: table) - написать полное имя сокращения. Сокращение Поскольку имя робота или дрона может содержать только 64 символа, указатели должны быть сокращены. Таким образом, вместо написания полного имени указателя, вы можете его сократить. Например, вместо написания robot.use(3), вы можете написать r.u(3) или даже Ru3. Правила сокращения: Если ключ имеет точное не-nil совпадение, оно будет возвращено. Сокращение должно содержать первую букву, а затем, по желанию, любое количество оставшихся букв. Если несколько имен имеют одинаковую первую букву, будет выбрано самое короткое, алфавитно отсортированное имя. Большая первая буква с точкой . может использоваться без точки. Число в конце сокращения будет вызывать сокращение как функцию с этим числом в качестве первого аргумента. В то же время, если это таблица, а не функция, все ключи таблицы будут естественно отсортированы и возвращен N-й элемент. Смотрите больше в Числовом Словаре. Локальные переменные не могут быть сокращены. Lodash _ Специальная вспомогательная функция нижнего подчеркивания _. Индексация _ Использование _ с числами _123 Вернет новый список-массив с длиной числа. Если первая цифра 0, таблица будет с нулевым индексом. Использование _ со словами _abc Создает функцию, которая будет записывать результат в переменную abc. Функция возвращает переданное значение. Обратите внимание, что _abc функциональна. Вызов _ Использование _ на строке Загрузит код внутри этой строки и вернет его как функцию. Вызов этой функции всегда безопасен для ошибок — если внутри произойдет исключение, функция просто вернет nil. Использование _ на таблице или функции Преобразует их в специальную таблицу _{} или функцию _'' для использования с Функциональным Программированием. Функциональное Программирование Любая таблица или функция, которую вы можете получить из глобальной переменной, будет преобразована в специальную таблицу _{}. Эта таблица улучшена дополнительными метаметодами операторов, которые помогают с функциональным стилем программирования. Любая итерация или вызовы pairs() на этих преобразованных таблицах будут выводить элементы в естественно отсортированном порядке. Операторы ведут себя по-разному в зависимости от левой и правой стороны оператора. Обратите внимание, что когда обнаруживается строка, она загружается и преобразуется в функцию по принципу _'fnc'. Приоритет Приоритет операторов в Lua следует таблице ниже, от высшего к низшему приоритету: ^ унарные not # - ~ * / // % + - .. << >> & ~ | < > <= >= ~= == and or Map ^, +, или & ^, +, и & операторы делают то же самое. Их три, только для управления приоритетом. Примечание¹: ^ ассоциируется справа. Это означает, что сначала будет вычислена правая сторона. Примечание²: Вы также можете вызывать невызываемые таблицы. t(x) то же самое, что t^x. Невызываемые таблицы — это таблицы без метатаблицы __call. Пример (map t^f): _{1,2,3}'0' -- _{0,0,0} Левая сторона Правая сторона Результат Таблица Функция Классическая карта _{4,5,6}^f -- {f(4),f(5),f(6)} Таблица Выбор индексов _{4,5,6}^{3,1} -- {6,4} Число, Булево значение Добавление значения в КОНЕЦ таблицы _{1,[3]=3,a=6,[4]=4}^5 -- _{1,3=3,4=4,5=5,a=6} Функция Функция Композиция f^g -- (...)=>f(g(...)) Таблица Распаковка как аргументы f^{1,2,3} -- f(1,2,3) Число, Булево значение Простой вызов f^1 -- f(1) Число, Булево значение Таблица Получение по числовому или булевому индексу 2^_{4,5,6} -- 5 Функция Не реализовано Лямбда - / | Левая сторона Правая сторона Результат Таблица Функция Фильтр, оставляет только значения, являющиеся Истинными _{4,5,6,7}/'v%2' -- {5,7} Таблица Не реализовано Число, Булево значение Удаление индекса _3/2 -- {1=1,3=3} Функция Функция Обратная композиция f/g -- (...)=>g(f(...)) Таблица Простой вызов f/R -- f(R) Число, Булево значение Композиция f/1 -- (...)=>f(1,...) Число, Булево значение Таблица Получение по модулю i/t -- t[i % #t + 1] Функция Вращающаяся композиция 2/f -- (...)=>f(..., 2) Цикл ~ или * Левая сторона Правая сторона Результат Таблица Функция Не реализовано Таблица Не реализовано Число, Булево значение Не реализовано Функция Функция Пока истинно, делай f~g -- пока истинно(g(j++)) делай f(j) Таблица Не реализовано Число, Булево значение Цикл for f~n -- for j=1,TONUMBER(n) do f(j) end Число, Булево значение Таблица Не реализовано Функция То же, что и f~n, но без передачи индекса n~f -- for j=1,TONUMBER(n) do f() end Унарные операторы Унарный оператор Объект Результат ~ Функция Пока истинно, делай ~f -- повторять пока не истинно(f()) Таблица Сглаживание таблицы, используя числовые индексы. ~_{1,{2,3},{4,a=5,b={6,c=7}}} -- {1,2,3,4,5,{6,c=7}} - Функция Создать функцию, результат которой будет инвертирован. Если результат истинный, возвращает 0. Возвращает 1 в противном случае. -- id здесь функция, возвращающая свой первый аргумент (-id)(0) -- 1 (-id)(4) -- 0 (- -id)(4) -- 1 Таблица Обмен ключей и значений -_{'a','b','c'} -- {a=1,b=2,c=3} # Функция Создать функцию, которая будет оборачивать свой результат в таблицу. Полезно для функций, возвращающих несколько значений. -- Предположим, `f(n)` возвращает три значения - 2,3,n f&4 -- 2 #f&4 -- _{2,3,4} Истинные значения Знач ение считается "истинным", если оно не является "ложным". "Ложные" значения: false или nil '' (пустая строка) 0 (ноль) nan (не число, n ~= n) inf или -inf (результат 1/0 или -1/0) Макросы В программе есть несколько предопределенных макросов - символов, которые будут заменены везде на другой текст. ! => '()' ⓐ => ' и ' ⓞ => ' или ' ⓝ => ' не ' ⓡ => ' вернуть ' ⒯ => '(истина)' ⒡ => '(ложь)' Примеры Перемещение между двумя точками и выполнение их метки Имя дрона: P=i/Nf300ⓡDm^Pp,s/1~'Dg0>1',_(Pl) Nf300: Выполнить navigation.findWaypoints(300). i/Nf300: i - индекс выполнения скрипта. i / table - "Получение по индексу модуля" t[i % #t + 1]. P=i/Nf300: Записать в глобальную переменную P различные точки каждый цикл скрипта. ⓡ: будет заменено на вернуть Dm^Pp: вызов drone.move(table.unpack(P.position)). s/1~'Dg0>1' => пока drone.getOffset() > 1 делать sleep(1). _(Pl): Загрузить P.label как код Lua. Эта загруженная функция будет возвращена и выполнена. Метки точек. Первая просто всасывает снизу, вторая итерирует по 4 слотам и сбрасывает вниз. _'Dsk0'~4 Dsel-'Dd0'~4 Зигзаг + Использование вниз, полезно для ферм Имя робота: m,t=_'Rm3,Ru0',Rtn/(i2>1)ⓡ~m,t!,_'m!,t!'!ⓞt/m m,t=_'Rm3,Ru0',Rtn/(i2>1): определить две функции для движения и поворота _'Rm3,Ru0': определить функцию Rm3,Ru0, которая будет двигаться вперед и использовать инструмент вниз Rtn/(i2>1): это создает функцию, которая будет вызывать Rtn (robot.turn) с аргументом i2>1. i2 - сокращение для i%2+1 ~m: Заставляет робота двигаться вперед, пока он не сможет двигаться. t!: просто поворачивает _'m!,t!'!ⓞt/m: Двигаться и поворачиваться. Если движение не удалось, повернуться и двигаться снова. Торговый бот Имя робота: Rsel-'Rd0'~RiS0,IsF/0~Igz0,Tg0'~tr' Rsel-'Rd0'~RiS0: Выбрать каждый слот и сбросить вниз IsF/0~Igz0: Для каждого слота инвентаря снизу inventory_controller.getInventorySize(0) вызвать inventory_controller.suckFromSlot(0, k) Tg0'~tr': Торговать всеми товарами. Есть другой вариант имени робота, более продвинутый. Он будет забирать только предметы, которые действительно требуются для торговли. Эта программа жестко запрограммирована для работы с внутренним и внешним инвентарем размером 16: -- Торговать всем a=-~Tg0"_{g!}'n',~tr"ⓡ_16&R16-'Rd0'&IgI/0&'a[n]ⓐI8/0&k' -- Не продавать изумруды [id==388] a=-~Tg0'388^-g0ⓞ{g0.n,~tr}'ⓡ_16&R16-'Rd0'&IgI/0&'a[n]ⓐI8/0&k' Создатель рун Поместите ингредиенты в первые 6 слотов робота. Живой камень на 7-м, палочку на 8-м. Имя робота: _8/'Rsel^v,v==7ⓐ{s3,Rm1,Rd(3,1),Rm0}ⓞ{Ie!,Ru3,Ie!}' Rsel^v: Выбрать слот по очереди v==7ⓐ{s3,Rm1,Rd(3,1),Rm0}: если это 7-й слот с Живым камнем, подождать 3 секунды до завершения крафта, затем сбросить Камень сверху. Ie!,Ru3,Ie!: Для других слотов - просто кликнуть правой кнопкой мыши с предметом Ферма одиночных деревьев Этот робот предназначен для использования с саженцами Forestry, которые обычно не могут быть поставлены как блоки, но требуют клика правой кнопкой мыши для посадки. Кроме того, роботу нужен неразрушимый Широкий Топор из TCon с чертой Глобальный Путешественник. Кроме того, мой топор имеет черту Удобрение - клик правой кнопкой мыши для удобрения. Поставьте робота на контейнер с саженцами. Имя робота: #(1|#Rdt&3)<6ⓐRsw/3-s/1-Rsk/0-Ie-Ru/3-IeⓞRu3,s (1|#Rdt&3): Обнаружить блок перед собой, выбрать второе возвращаемое значение - описание блока #()<6: хитрость, чтобы определить, является ли блок твердым Rsw/3-s/1: Срубить все дерево, подождать 1 секунду Rsk/0-Ie-Ru/3-Ie: Всосать саженец снизу, затем посадить его. Обратите внимание, что Rsk получает одно значение от sleep возврата Ru3,s: Удобрить саженец Другие примеры Круговой шахтер. Используя Молот с частью из Алумита (черта Глобальный Путешественник). Поставьте Робота под землю, поместите стак Блоков Угля в выбранный слот робота. Робот начнет кружить вокруг, добывая все на своем пути. Gi,_'Rm3,Rsw3'~i*2,Rtn⒯ Робот для сортировки дропа мобов. Берет снизу, предметы, подлежащие повреждению, вверх, остальные - вперед. Rd|3%2^(IsF(0,i%Igz0+1)ⓐIgSII!.mDⓞ2) Открыватель кошек. Берет 16 предметов перед собой, кликает их правой кнопкой мыши, затем сбрасывает инвентарь вверх. Rsk/3&16ⓐIe!,~_'Ru0',_16/Rc|Rsel/'Rd1' Компрессионный бот. Берет спереди, крафтит 3x3, затем сбрасывает назад. -(_16-Rc&12)|'Rd3'&Rsel,IsF/3/'_11/8/4&Rc!/9/RtT'|i81,Cc Бот для неразложимых предметов. Берет предмет перед собой только если они неразложимы и кладет их наверх. Если не может сбросить предмет наверх, толкает вверх и ставит блок. (IgSI/3&_a^i1728ⓞ{}).mS^_{_'IsF/3&a,Rd1ⓞ{Pps1,Rsel9,Rp1,Rsel1}'} Дополнительно Ссылки Репозиторий с исходным кодом и readme Модпак, для которого был запрограммирован этот робот: Enigmatica 2: Expert - Extended Старое описание: LiMWFlH.mp4
-
2 баллаРеспект за соулс от мира опенкомпов! Вики очень достойная, но логику работы сложно осилить даже на примере \0ZZ, учитывая необходимость перма-скроллинга то по списку алиасов в сырце, то по списку операторов в самой вики. Да и без поиска тут не обойтись. Пожалей наши мыши! Интереса ради я решил вникнуть в первый пример: 1) Читаю команду \0, понимаю, что это useDown(), вопросов нет 2) Читаю команду Z, осознаю, что это алиас на %`~F'ta'N` ?M*'F?M`FN``RRMN`', приступаю к расшифровке 3) Читаю команду %, смекаю, это ещё один алиас на ?{<a>==nil}, отвечающий за проверку истинности результата выполнения некоего Lua-выражения. А какого? 4) Судорожно ищу, что такое <a>, и вроде бы даже нахожу нужную секцию: То есть, согласно вики, a - это программа, которая... что? Которая названа a? 5) Пытаюсь найти в сырцах некую программу с названием а, но тщетно 6) Допускаю, что, скорее всего, a - это переменная, которая пока еще не определена в текущем окружении. Вроде бы. То есть, наверное, выражение ?{<a>==nil} эквивалентно if a == nil. Или a - это все же программа? Ладно, хрен с ним 7) Возвращаюсь к пункту 2, читаю символ `, вновь обращаюсь к сырцам. В сырцах не нахожу. Видимо, оно в вики? Скроллю вики, нахожу искомое: Так, падаж-ж-жи! Интересно, зачем столько вариантов... для возможности использовать внутри строк другие кавычки, когда требуется? Если да, то это хорошо, хотя классический эскейпинг через \" был бы правильнее, т.к., например, я не смогу заюзать все 3 варианта кавычек в строке "hello `sunny`, you are 'so shiny' and "beautiful"". Или все же смогу? Энивей иду вперед 8) Натыкаюсь на символ ~, определяющий алиас на подпрограмму ~F'ta'. Судя по вики, у нас теперь определена некая подпрограмма F, выполняющая команды ta 9) Ищу, что такое t и a. Сырцы говорят, что t отвечает за robot.turn(clockwise). Вероятно, переменная а и отвечает за поворот по часовой стрелке? Вроде бы понятно... 10) Читаю новый неизвестный символ N. Хоспади, только не алиас... МАМОЧКИ, ЭТО ОН. Ищу в сырцах содержимое, нахожу логику инверсии перменной a -a{not <a>}... не-е-е, все, убейте меня. Софтина хорошая, идея клёвая, но нервная система у меня одна хд
-
2 баллаНашел баг. test( "true/false arguments", "a:true b:false c:c", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 'a', 'b', 'c' ) return f(true)(false)() end ) -- [Failed] true/false arguments -- Expected: a:true b:false c:c -- Got: a:true b:b c:c Тот самый случай, когда ты подумал "a and b or c" это настоящий условный оператор, а он подвел. Но я знаю как исправить, нужно просто заменить на "==nil"
-
1 баллПо стечению обстоятельств выкладываю немного не дописанный (разработка продолжается), но в рабочем состоянии магазинчик внутриигровых предметов. репозиторий: https://github.com/Zardar/pimmarket/ ссылка для загрузки: https://raw.githubusercontent.com/Zardar/pimmarket/pimmarket_0.8/loader.lua alternative dl from pastebin: market - https://pastebin.com/M5anF9JW (pastebin get M5anF9JW market.lua) server - https://pastebin.com/jGMM1vqD (pastebin get jGMM1vqD server.lua) Что подтверждено на практике: Работа сервера с четырьмя клиентами Что на данный момент реализовано: Взаимодействие с клиентом/сервером путём касания экрана. Игногрирование касаний экрана посторонними при игроке на PIM. Полное игнорирование касаний экрана без игрока на PIM. Авторегистрация владельца/цев через пим подключенный к серверу. Авторегистрация игроков через пим подключенный к клиенту. Поддержка ме-сети в качестве источника товаров. Поддержка указанных сундуков в качестве источника товаров, если не подключен ме-интерфейс. Из коробки это сундуки мод-пака GTImpact. Собственно сама продажа предметов. В качестве источника средств используется NPC money. Регистрация клиентов на терминале. +Автоматический запрос регистрации клиентом. Сохранение адресов клиентов сервером. Их загрузка из файла в случае перезапуска сервера. Сохранение списка владельцев. Сохранение списка посетителей магазина и их баланс. Автовключение клиентов после запуска сервера. Вам достаточно прописать на клиенте его название в автозагрузку для автоподнятия торговой сети если всё было выключено. Редактирование цен и названий отображаемых предметов владельцем. Переход в режим редактирования осуществляется кликанием по надписи owner в верхнем левом углу. Автосохранение базы предметов после редактирования. Автообновление количества доступных предметов после покупки и по нажатию кнопки 'отмена' (как бы странно это ни было). Что на данный момент не реализовано: Поиск предмета по названию. Пополнение счёта без осуществления покупки. В данный момент счёт пополняется остатками от операции покупки товара, а именно: если цена предмета неравна целому от операции цена/10. Не планировалось изначально. Будет добавлено для работы казино Возможность смены типа валюты через инвентарь игрока. Проверка на сервере кто коснулся экрана. Критический момент, если сервер стоит в доступном для посещения посторонними месте. Впрочем, функционал взаимодействия с сервером мал, и при отключенном от сервера пиме (а он нужен только для регистрации владельцев) опасность невелика, но есть. Можно отправить на сервер запрос регистрации клиента и зарегистрировать его, после чего имитировать покупки для пополнения баланса. Поддержка реквестов крафта купленных товаров Подключение сторонних программ. Предполагается подключить некоторые из приложений казино автора Кровяка: рулетка, больше меньше и ещё что-то. Сам не помню что :-) Возможно, будут ещё идеи. Что не доделано: Графическое меню магазина. Выполнено примерно на 90-95%. Впрочем, это область визуальной эстетики не влияющая на работоспособность в целом. Каковы системные требования? Для комфортной инсталляции рекомендуется экран тира 2 и выше. После установки для работы клиента и сервера достаточно корпуса компьютера второго тира. Но рекомендуется тир 3. Если предполагается огромная база пользователей/товаров, то скорее всего потребуется коробка тир 3 и соответствующие по тиру компоненты. Моя комплектация сервера и клиента. Используется исключительно для тестов работоспособности: Виды в меню клиента: Взгляд мельком на экран сервера:
-
1 баллЯ пишу свой интерпретатор на Lua для роботов. Мне потребовалось использовать лямбда-вычисления. Задача - написать функцию L, где L(f, n) выдавало бы функцию Ln(a1)(a2)(...)(an) которая при выполнении выдает f(a1, a2, ..., an). @ProgramCrafter подсказал написать так: local function L(f,n) if n<=1 then return f else return function(a) return L(function(...) return f(a,...) end, n-1) end end end Такая функция работает при значениях n>=1, но не работает с n=0 f = L(print, 2) f(1)(2) -- печатает: 1 2 f = L(print, 0) f() -- выдает функцию print Вопрос: Нужна функция L, которая принимает в параметр функцию f и дополнительно n аргументов - стандартных значений, которые так же будут показывать количество аргументов. local function L(f, ...) -- ??? end -- Функция для примера - просто выводит три своих параметра local function abc(a, b, c) return '"a:'..tostring(a).. ' b:'..tostring(b).. ' c:'..tostring(c)..'"' end local f = L(abc, 'a', 'b', nil) -- Создаем λ-функцию с тремя значениями по умолчанию -- Должно выводить: print( f(1)(2)(3) ) -- "a:1 b:2 c:3" print( f()()() ) -- "a:a b:b c:nil" print( f(nil, 2)() ) -- "a:a b:2 c:nil"
-
1 баллСтатью не читал. Лямбда-исчесления знаю ужасно. Знаю только что f(1)(2)(3) - это лямбда.
-
1 балл>lambda calculus Весь лк или только каррирование? http://lua-users.org/wiki/CurriedLua
-
1 баллЯ полностью удовлетворен! Спасибо за помощь! P.S. Уже третий час пишу документацию по своему новому языку....
-
1 баллДа, я поначалу думал заюзать pack/select, но в нашем случае это ломает кейс без таблицы дефолтных значений: f = L(function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end) f(1)(2)(3) Здесь невозможно определить, сколько всего аргументов принимает функция f(a, b, c), а затем выполнить её на этапе (3). Хотя, конечно, мы могли бы ограничиться условием, что таблица дефолтных значений требуется всегда, что позволило бы на основании ее размера судить о кол-ве аргументов функции f. Но это уже вопрос к @Krutoy Зато через pack можно решить проблему с nil в кач-ве последнего аргумента любого из замыканий в цепочке:
-
1 балл
-
1 баллВсё в Lua сделать можно, я даже статью про это писал. Там про table.pack в основном, но хочу вдобавок напомнить здесь про функцию select, которая умеет как число переданных аргументов возвратить, так и вытащить нужный: select('#', 2, 4, nil, 8, nil, nil, nil, nil) --> 8 select(2, 2, 4, nil, 8, nil, nil, nil, nil) --> 4 nil 8 nil nil nil Никакие nil ему не помеха.
-
1 балл@ECS Огонь, большое спасибо! Мне самому не хватало мозгов что бы это написать. Сейчас имплементирую в код и скоро опубликую прогу для робота. Функция правда выглядит громоздко для EEPROM и робота с одной Т1 платой, но ченить придумаю.
-
1 баллХе-хе, вот поэтому без внятного ТЗ результат ХЗ: не было ж ни слова про nil'овые дефолты. Вообще вариант у нас лишь один - всегда указывать размер таблицы defaults вручную, если в ней присутствует nil в конце, т.к. lua попросту не воспринимает его ни в случае вараргов, ни при инициализации таблицы напрямую: print(#{nil, "b", "c"}) -- 3 print(#{"a", nil, "c"}) -- 3 print(#{"a", "b", nil}) -- 2 print(#{[1] = "a", [2] = "b", [3] = nil}) -- 2 Поэтому только ручками, видимо: local function L(f, fArgsCount, defaults) fArgsCount = fArgsCount or 1 if fArgsCount <= 1 then return f end local fArgIndex = 1 local fArgs = {} local function appendNextArg() if fArgIndex > fArgsCount then return f(table.unpack(fArgs, 1, fArgsCount)) end return function(...) local fArgsParts = {...} if #fArgsParts == 0 then fArgs[fArgIndex] = defaults and defaults[fArgIndex] or nil fArgIndex = fArgIndex + 1 else for i = 1, #fArgsParts do fArgs[fArgIndex] = fArgsParts[i] or (defaults and defaults[fArgIndex] or nil) fArgIndex = fArgIndex + 1 end end return appendNextArg() end end return appendNextArg() end local function test(name, expectedResult, f) local result = f() print("[" .. (result == expectedResult and "Passed" or "Failed") .. "] " .. name .. ":") print("Expected: " .. tostring(expectedResult)) print("Got: " .. tostring(result)) print() end test( "test 1: no defaults, no result", nil, function() f = L(function() print('succes!') end) f() end ) test( "test 2: no defaults, every argument is passed directly", "a:1 b:2 c:3", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3 ) return f(1)(2)(3) end ) test( "test 3: no nils in defaults", "a:a b:e c:c", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3, {'a', 'b', 'c'} ) return f()('e')() end ) test( "test 4: nil at defaults middle", "a:a b:nil c:c", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3, {'a', nil, 'c'} ) return f()()() end ) test( "test 5: nil at defaults end", "a:1 b:b c:3", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3, {'a', 'b', nil} ) return f(1)()(3) end ) test( "test 6: multiple returns, nil at defaults end", "a:a b:2 c:nil", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3, {'a', 'b', nil} ) return f(nil, 2)() end ) Фичу мульти-ретурна я сделал, фигня вопрос, однако если какая-то функция из цепочки вернет результат с nil в конце - система сдохнет. Тут уж либо опять вручную указывать кол-во аргументов, либо забить болт: test( "test 7: multiple returns with nil at end", "a:a b:2 c:nil", function() f = L( function(a, b, c) return 'a:' .. tostring(a) .. ' b:' .. tostring(b) .. ' c:' .. tostring(c) end, 3, {'a', 'b', 'c'} ) return f(2, nil)() end )
-
1 баллСпасибо, это ближе к решению. Но эта функция неправильно работает, если дефолтные значения nil f = L(function(a, b, c) return 'a:'..tostring(a)..' b:'..tostring(b)..' c:'..tostring(c) end, 'a', nil, 'c') print(f()()()) -- Выводит "a:a b:c c:nil", хотя должно "a:a b:nil c:c" Если же список дефолтных значений кончается на nil, то вообще ошибка: f = L(print, 'a', nil, nil) print(f()()()) -- attempt to call a nil value Хотя возможно, в Lua вообще нельзя посчитать количество значений из ..., если они кончаются на nil. Еще, я расширю задачу в первом посте. Так как Lua умеет работать с множественным возвращением значений из функции, лямбда должна обрабатывать и это. local function L(f, ...) -- ??? end -- Функция для примера - просто выводит три своих параметра local function abc(a, b, c) return '"a:'..tostring(a).. ' b:'..tostring(b).. ' c:'..tostring(c)..'"' end local f = L(abc, 'a', 'b', nil) -- Создаем λ-функцию с тремя значениями по умолчанию -- Должно выводить: print( f(1)(2)(3) ) -- "a:1 b:2 c:3" print( f()()() ) -- "a:a b:b c:nil" print( f(nil, 2)() ) -- "a:a b:2 c:nil"
-
1 баллlocal function L(f, ...) local defaults = {...} if #defaults == 0 then return f end local defaultIndex = 1 local fArgs = {} local function appendNextArg() if defaultIndex > #defaults then return f(table.unpack(fArgs)) end return function(fArg) table.insert(fArgs, fArg or defaults[defaultIndex]) defaultIndex = defaultIndex + 1 return appendNextArg() end end return appendNextArg() end f = L(function(a, b, c) return a .. b .. c end, 'a', 'b', 'c') print(f()('e')()) -- Нужно что бы вывело "aec" f = L(function() print('succes!') end) f() -- Должно выводить "succes!" В общем, не уверен, что я правильно понял задачу, но ТЗ из второго примера результат соответствует
-
1 баллЕсли запустить этот пример, то f() не выдает ничего, хотя сказано обратное. Пруф: Поясни, пожалуйста, должна ли функция L по ТЗ выдавать функцию print, если n = 0, или же наоборот не должна
-
1 баллЕсли есть исходный код, то маловероятно что оно закрыто. У меня не хватает идей, как это сделать. Из разряда "у меня вот есть такая вот программа, но я вам не дам её"
-
0 баллов
-
0 балловЗа форумом я в последнее время слежу через RSS-читалку, и недавно мне начали попадаться какие-то настолько огромные стены безграмотного текста, что решил заглянуть, что тут творится. В общем, это были посты @rootmaster: с ошибками в словах, которые третьеклассник не допустит, желанием материться в каждом третьем посте, без форматирования, без точек, запятых, всё сплошняком, зато с излишними самоуверенностью и невежеством. Тут вот заверяется защита от замены биоса изнутри запущенной системы. За фичу эту много людей берётся, но постоянно делают всё не так от незнания. Напомню: достаточно просто подменить component.invoke именно в таблице, которую получает биос в окружении. И мне стало интересно: может, зря я осуждаю непризнанного гения. Вдруг хоть он смог понять и сделать всё по уму и красоте. Тем более, что сам код биоса не читабелен непосредственно, то есть вишней на торте даже до обфускации какой-то автор дошёл. Ещё и функционалы какие-то определил и тут же расширил. ...Ну да, если бы. И саспенса не получилось даже: были б ум да красота, я бы пост этот в принципе не писал. Код напичкан костылями. Было решено скопировать component в отдельную таблицу, в которой покрыть влоб бронёй прокси, отдаваемый методом component.proxy для компонента eeprom. Затем пришлось переопределить поле invoke в копии, чтобы он работал через component.proxy, а не внутренние механизмы machine.lua. И это всё работает на одной сопле в форме локальной переменной со ссылкой на эту прокси: без неё все изменения бы откатились при следующем же collectgarbage, потому что возвращаемые прокси лежат в эфемерной (__mode = "v") табличке-кэше. Хотя я наврал со словом "работает". Если хоть немного вдаться в работу machine.lua, сразу должно стать понятным, что "защита" элементарно обходится. Например, вот так. getmetatable(component.eeprom.getSize).__call({address = component.eeprom.address, name = "set"}, "lol") И без перепрошивки комп больше не запустится. Насчёт третьего пункта выше я даже не особо понял, как так вышло. То ли автор всё-таки под капотом смог разглядеть тонкости кэша проксей, то ли он просто от балды пытался код менять, пока не заработало, то ли досталось счастливым артефактом от прошлых версий проги. Неважно. Осуждаю по всем пунктам обвинения. А ведь стоило бы по-человечески написать, и лайкнул бы, и похвалил. И другие, думаю, сарказмом бы не поливали.
Эта таблица лидеров рассчитана в Москва/GMT+03:00
