Перейти к содержимому

eu_tomat

Модераторы
  • Публикации

    2 666
  • Зарегистрирован

  • Посещение

  • Победитель дней

    331

Все публикации пользователя eu_tomat

  1. Лайки этим постам: И далее подробнее с этого места: К чёрту трёхмерные графики. Они тут нам вообще не нужны. Для начала вспоминаем, что производная — это скорость роста функции в каждой её точке. Попробую пояснить её применение на этой задаче. Объем цилиндра зависит от его радиуса и высоты. И площадь тоже зависит от радиуса и высоты, но по другой формуле. Нам нужно минизировать площать при заданном объеме. Или наоборот, но это совсем не принципиально, т.к все формулы обратимы. Я считаю, что формулы имеют более простой вид при выводе площади из объема. Попробуйте сделать наоборот, и мой выбор станет понятным. Сначала выведем формулу зависимости площади от радиуса или высоты при постоянном объёме. На каком-то участке функции будет наблюдаться уменьшение площади, а на каком-то её увеличение. То есть, функция сначала будет падать, а затем, пройдя точку минимума, начнёт подниматься. В точке минимума функции её производная обратитится в ноль. Соответственно, приравняв к нулю производную, мы сможем найти точку, в которой площадь минимальна. В формулах это будет выглядеть таким образом: Формула объёма цилиндра, формула зависимости высоты от объема и радиуса: Площадь цилиндра, подставлена высота из предыдущей формулы: Объём цилиндра принимаем за константу, а площадь дифференцируем по радиусу и приравниваем производную к нулю: Это зависимость объема от радиуса при условии, что поверхность цилиндра минимальна. Подставляем в изначальную формулу объема и получаем соотношение высоты и радиуса: При этом соотношении площадь цилиндра минимальна при заданном объеме. Справедливо и обратное: при заданной площади объём цилиндра максимален. Задача для случая бесконечно тонкой стенки цилиндра решена. Аналогичным образом можно задать толщину стенки произвольного размера. В этом случае используем постоянный полезный объём, и ищем минимум для объёма, к которому добавляется толщина стенок. Я упоролся и таки вывел формулы и для этого случая тоже. Результат совпал с предыдущим, но формулы получились многократно сложнее. Поэтому публиковать я их не буду. Алгоритм их получения тот же самый, с той лишь разницей, что придётся написать больше символов, и будет больше шансов допустить ошибку. Тут помогут только аккуратность и терпение.
  2. Прекрасное сравнение. Работа над любым проектом рано или поздно приостанавливается, а иногда приходится возвращаться к старому коду через полгода-год. И если бы не удобное оформление кода и комментарии, мне иногда было бы проще переписать код заново, чем разбираться в уже написанном. Через полгода для меня собственный код выглядит чужим. Но удобный для меня стиль, а также комментарии всякий раз экономят моё время. Очень рекомендую.
  3. Нота Ля первой октавы: local computer=require"computer" computer.beep(440,1)
  4. Почему же никто не сможет? Настойчивый критик обычно открывает ссылку в меню форума: Сервисы > Lua > Форматтер Lua, вставляет код, клацает на «Beautify» и критикует в своё удовольствие. Кто же остановит настойчивого критика? Менее настойчивые, конечно же, просто игнорируют темы с плохо оформленным кодом. Имеют право.
  5. Любопытный подход. И в чём же польза непонятного кода?
  6. Не обязательно делать код красивым. Сделай его хотя бы понятным. Если, конечно, хочешь, чтобы кто-то читал его.
  7. Отступы, как и другие правила форматирования кода, не влияют на его работоспособность, но сильно влияют на его чтение. Любое оформление кода: отступы, разделение кода на строки, дополнительные пробелы, комментарии – должно подчёркивать мысль программиста. Отступы, например, помогают при беглом осмотре понять блочную структуру кода, что в какой оператор вложено. Попробую разобрать имеющийся код: Взяв в руки карандаш, я линиями отмечаю начало и конец каждого блока кода. Правильные отступы помогли бы обойтись и без карандаша, но это не наш случай. Цвет карандаша использую любой, тут главное, чтобы соседние линии не сливались. * Первым я вижу ключевое слово function, отмечаю точкой начало оператора и ожидаю его завершения ключевым словом end. * Но дальше встречаю оператор for, начало которого я токже отмечаю точкой и снова просматриваю код в ожидании end. * следующие после for две команды оформлены с отступами, но потом отступ уменьшается, что создаёт иллюзию того, что эти команды в цикл не вложены, что не соответствует действительности. Но продолжаем искать end, завершающий for. * Дальше встречается ключевое слово if, содержащиеся с нём команды, правильно оформленные отступом, а также закрывающее ключеове слово end. Тут сразу можно нарисовать линию, выделяющую этот блок команд. * Дальше снова встречается if, закрываемый end. Отступ для команд выбран верный, а отступ для end следует уменьшить. * потом встречается end. Смотрим, какая последняя точка ещё не превратилась в линию и видим, что этот end закрывает for. Да, он находится на одной линии с ним, так и должно быть. Но он находится и на одной линии с предыдущим if, и создаётся иллюзия, что закрывается именно if. Такие отступы дезориентируют и мешают поиску ошибок в коде. * дальше отступы правильные, и хорошо видно, что end закрывает function. Как привести отступы в порядок? Первые символы строк кода должны постоянно образовывать фигуры, напоминающие закрывающую квадратную скобку: При таком расположении ключевые слова, открывающие и закрывающие оператор, всегда начинаются на одном уровне, а вложенные команды располагаются уровнем ниже. Такое оформление помогает быстро понять, что куда вложено.
  8. Судя по коду, программа рабочая. Советы по улучшению кода интересуют? Если да, то рекомендую начать с приведения в порядок отступов. Правильные отступы сильно облегчают обнаружение шероховатостей кода.
  9. Вопрос ещё как актуален, он регулярно всплывает. И ознакомиться с таким решением очень полезно. Наилучший ответ.
  10. Выбрасываем костыль: function onChatMessage(...) for n,arg in ipairs({...}) do print(arg) end end
  11. О, печаль. Подход рабочий, но прелесть системы в возможности использовать уже готовые библиотеки. Решение не для всех. Не скачивал свежую версию OpenComputers, но если имеющиеся у меня файлы не устарели, то должно помочь удаление из файла /lib/event.lua следующих строк: local interrupting = current_time - lastInterrupt > 1 and keyboard.isControlDown() and keyboard.isKeyDown(keyboard.keys.c) if interrupting then lastInterrupt = current_time if keyboard.isAltDown() then error("interrupted", 0) end event.push("interrupted", current_time) end А можно вырезать только эту часть: if keyboard.isAltDown() then error("interrupted", 0) end Зависит от того, какая часть имеющейся логики останова программы должна быть урезана.
  12. Поиск по форуму приводит к следующему решению: http://computercraft.ru/topic/1870-kak-predotvratit-prinuditelnyi-ostanov-prog/
  13. Да. Во-первых, все случаи предусмотреть невозможно. Во-вторых, чтобы вызывать меньше подозрений, программа изначально должна занимать минимум памяти. Поэтому нужны всего четыре базовые команды: 1) безопасно выполнить принятый код и отослать результат на пульт; 2) добавить принятый код как постоянную команду с назначенным номером; 3) удалить команду с определенным номером или сразу все для очистки памяти; 4) безопасно выполнить команду с определенным номером (что отчасти реализовано) и отослать результат выполнения на пульт. А можно вообще обойтись только первым пунктом. Помнится, форумчане даже соревновались в написании наикомпактнейшего загрузчика кода: http://computercraft.ru/topic/833-bios-net-dlia-tcentralizovannogo-upravleniia-setiu-kont/ Он, конечно, не в фоне работал, но тут важен принцип функционирования.
  14. Мои впечатления от кода: Отступы расставлены как попало, что затрудняет чтение кода и поиск ошибок. Функции drop(), dropUp() и dropDown() вряд ли работают так как это было задумано: local function drop() for i = 1, size do robot.drop() robot.select(i) end robot.select(i) robot.drop() robot.select(1) endБессмысленно пищать динамиком о недостатке энергии при удаленном управлении: if energy <= 1500 then computer.beep() endНужно сообщать эту информацию на планшет, а уже он сможет издавать звук или сигнализировать о проблеме иным путём. Не ясно, что делает эта одиноко стоящая конструкция: math.floor(energy) Длинная конструкция типа этой: if code == 17 then robot.forward() elseif code == 30 then robot.turnLeft() elseif code == 32 then robot.turnRight() ... перемещается в таблицу примерно таким образом: local cmd = { [17] = robot.forward, [32] = robot.turnRight, ... } ... if cmd[code] then cmd[code]() end
  15. Для робота важно не то, будет ли сам хозяин грузить чанк с приватом, или же иной игрок, а то, прописал ли хозяин робот в свой приват.
  16. eu_tomat

    OpenArmors

    Ну, хорошо. Критики рассказали о том, что останется невостребованным. Но есть и уникальная особенность брони: Броня, полностью автоматизирующая действия игрока программным путём, разрешит долгий спор между магами и программистами. С этой бронёй не будет важным, сможет ли робот быть магом, или нет, т.к. всю магическую рутину можно будет выполнить от лица персонажа. Пробежать по нужным нодам, восстановить заряд палочки, не истощая ноды, теперь не будет проблемой. Изучить тумометром всякие новые предметы тоже можно автоматически. Синтезировать сложные аспекты из простых при исследованиях, сложить оптимальную комбинацию из аспектов, да и вообще исследовать весь таумономикон можно будет автоматически. Запуск наполнения на алтаре тоже можно будет автоматизировать. Теперь хорошо экипированный АФКашник может отбиться от случайных атак слабых игроков, вовремя съесть нужную еду или выпить зелье. И пусть игрок не будет ограничен выбором, надеть ли ему нашу программируемую броню или другую броню из любимого им мода. Пусть всё-таки это будет подобие нанитов. То есть, броня сама по себе, а возможности автопилота сами по себе. Что должен уметь автопилот? В первую очередь он должен "видеть" всё, что видит игрок: различать блоки, игроков, мобов, знать свои координаты и положение в пространстве, читать любые характеристики предметов в инвентаре и различать элементы интерфейсов. Также автопилот должен обеспечить полную возможность управления персонажем: перемещаться, переключать режимы брони и оружия, перемещать предметы в инвентарях, крафтить на обычном столике, зачаровывать вещи на столе зачарований и наковальне, переименовывать их, ставить блоки и ломать их, бить мобов, пользоваться зельями и т.д. Короче, нужна возможность полной автоматизации любых действий игрока. Такой мод будет уникальным и интересным. Новые механики для программирования тоже будут обеспечены. Это вам не робот с пёрышком, легко пролетающий над пропастью, не сбиваясь с курса. Тут надо будет следить за дорогой, "смотреть" под ноги, подкладывать блоки в пустоты, расставлять факела и быть готовым защищаться в отличие от робота, которому мобы не несут угрозы. Голосую "за" в надежде на то, что броня будет воплощать именно эти идеи.
  17. Во флудилке ей самое место. Тут, наверное, ошибка. Я не слышал о существовании таких длинных SSD в обозримом нами секторе Вселенной. Даже расстояние от Солнца до Венеры немного меньше. К тому же более важным показателем для SSD является не его длина, а объём. А объём измеряется в метрах кубических.
  18. Сложно подтвердить инфу, которая легко опровергается. Всякий источник информации может оказаться полезным, но не всякую информацию стоит принимать на веру. Исключение составляют только случаи, когда в данный момент проверка информации не представляется возможной, а источник уже имеет хорошую репутацию. Это как с теориями физики, о которых здесь на форуме даже как-то спорили: теории, конечно, не идеальные, но лучших в данный момент всё равно нет. При такой логике любую операцию можно повторять 35 раз. Ну, а что, моментально же выполняется. Но лишним таки будет. Наш форум читают неопытные программисты, которым этот код может показаться нормой. Это не норма, и вот, почему. Любая локальная переменная доступна исключитлельно в области своей видимости. Соответственно, локальная переменная psk доступна только в предалах блока do ... end, внутри которого она была объявлена, а по окончанию его работы занимаемаемая ею память становится доступной для освобождения сборщиком мусора. Но и на этом этапе содержимое переменной не будет удалено. Оно будет затёрто лишь при инициализации новых переменных, если они, конечно, будут созданы на этом участке памяти. Операция psk = nil тоже не удаляет строку, а лишь указывает, что теперь значение переменной пустое, а ранее занятая переменной память может быть освобождена сборщиком мусора. И даже psk = string.random(psk:len()) не перезаписывает пароль в ОЗУ, а лишь создаёт новую строку, и присваивает ссылку на неё переменной psk, а сама же строка остаётся в неизименном виде до тех пор, пока до неё не доберётся сборщик мусора. Но и он, как говорилось выше, переменную не очищает. Что мы имеем в итоге? 35 раз создаётся новая строка, а ссылка не неё присваивается переменной psk, каждый раз затирая предыдущую ссылку (не строку!). Потом ссылка (не строка!) очищается при выполнении psk = nil. А по окончании выполнения блока do ... end теряется доступ к самой переменной psk. Значение имеет только последнее действие: доступ к переменной потерян. Сам ключ и 35 экземпляров случайных строк продолжают висеть в памяти. Со временем сборщик мусора освободит память из-под этих переменных, а их значения так и останутся в памяти, пока на их месте не будут созданы и инициализированы новые переменные. Конечно, интенсивное создание случайных строк ускорит использование сборщика мусора и в конечном итоге даже перезапись того участка памяти, где когда-то был ключ. Но возникают два вопроса. Почему 35 итераций достаточно для гарантированного удаления ключа? И какая в этом польза, если доступ к ключу внутри Lua всё равно уже потерян, а другого доступа в OpenComputers нет и не предвидится?
  19. Странно. Если и монитор и видеокарта третьего уровня, то такая ошибка при смене разрешения не должна возникать, и её появление не должно зависеть от используемой OS.
  20. Нужна конкретика. Иначе нечего обсуждать и улучшать.
  21. Первый (в порядке появления, а не по важности) совет: освоить шестнадцатеричную запись цветов. Записиь вида robot.setLightColor(0xFF8080) сегодня понятна не только программистам, но и многим дизайнерам. Даже они, далёкие от тонкостей систем счисления, оценили удобство такой записи. В результате промежуточная функция colorRGB() становится ненужной, а запись выглядит компактнее. Впрочем, для кого-то запись из трёх десятичных чисел более понятна, и потому имеет право на существование. Следующий участок кода можно и записать короче, и сделать более понятным, и даже поднять его быстродействие: local powerSteps = #cl local e = tonumber(pc.maxEnergy()) local pStep = math.floor((e / powerSteps)) local function currentPowerStep() e = pc.energy() local result = powerSteps local process = true for i = 1, powerSteps-1 do if (e < (pStep*i)) and process then result = i break end end return result endЗдесь используется цикл и проверка условия внутри него. В зависимости от текущего состояния робота выполняется соответствующее количество итераций. Но это вычисление можно всегда выполнить за одну итерацию. local idx = math.ceil(computer.energy() / computer.maxEnergy() * #colors) robot.setLightColor(colors[ idx>0 and idx or 1 ]) Такой код записывается короче, выглядит проще, а работает быстрее. И памяти меньше требует.
  22. @@HeroBrine1st, можешь пояснить назначение этого хитрого участка кода? print("Перезапись ключа в ОЗУ 35 раз") for i = 1, 35 do psk = string.random(psk:len()) end print("Удаление ключа из ОЗУ") psk = nilНасколько я знаю, достаточно последней строчки, если речь идёт об OpenComputers, а в контексте языков, приближенных к машинным, достаточно лишь один раз переписать находящийся в RAM ключ. Или есть иная информация?
  23. Да. Во-первых, сервер можно использовать вместо компьютера. Во-вторых, для непосредственного управления реактором или получения данных о его работе можно использовать промежуточный сервер или компьютер, передавая данные между ним и основным компьютером по сети.
  24. Как работает реактор, я не знаю. Прокомментирую только вывод этой масштабной ASCII-картинки. Я бы предпочёл избавиться от кучи gpu.set, чтобы снизить шансы на ошибку в номерах строк: -- вывод многострочного текста на gpu local com = require "component" local gpu = com.gpu local text = [[ string111 string222 string333 string4 string5 ]] local row=0 for txt in text:gmatch( "([^\n]+)" ) do row = row + 1 gpu.set( 1, row, txt ) end -- альтернативный вариант кода: text:gsub( "([^\n]+)", function( txt ) row = row + 1 gpu.set( 1, row, txt ) end)
  25. Мы не ищем смыслы. Мы их создаём. И если человек говорит о какой-то стратегии, значит, у него есть цель, и он знает смысл. Вот, его-то мы и пытаемся понять.
×
×
  • Создать...