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

Лидеры


Популярный контент

Показан контент с высокой репутацией 23.04.2020 в Сообщения

  1. 6 баллов
    Ничего не понятно, но очень интересно. Принятие решения сводится к оценке вероятности попадания плотности в нужный диапазон. Сканирование очень затратно по времени. Если будем сканировать и усреднять, то для уточнения понадобится линейное увеличение количества сканирований на каждый блок. Можно поступить проще. Берем минимальную и максимальную плотность для руды и камня, сравниваем их. Видим, что на расстоянии в 12 блоков имеется пересечение плотностей, при максимально возможном уровне шума. Следовательно, до 12 блока можно легко обнаруживать и добывать руду. Нам нужен камень? Вряд-ли. Пока идем до руды, его и так не мало набирается, следовательно, надо исключить попадание возможных плотностей камня в список целей добычи. Путем нехитрых манипуляций, выводим формулу получения максимального шума из расстояния. N = R * 0.0606 Для этого не придется делать тысячи сканов всех блоков, ведь в конфиге написано, что зависимость линейная, да и в коде можно глянуть. Чтобы отнять максимум плотности камня от минимума плотности руды, можно заюзать функцию math.max, в результате имеем возможность с вероятностью примерно в 99.99% не перепутать камень с рудой на любом расстоянии. Получаем уровень шума: N = math.sqrt(x^2 + y^2 + z^2) * 0.0606 Вычисляем минимально возможную плотность для текущего расстояния: math.max(3 - N, 1.5 + N) Если полученное число меньше результата сканирования, то все норм, этот блок точно плотнее камня и за ним можно ехать. Для примера я взял предельный случай, который возникает довольно редко. Можно поиграться с параметрами, например уменьшить коэффициент шума при оценке. Или на расстоянии больше 25 блоков устанавливать минимальную плотность на 3.
  2. 4 балла
    Привет, это моя первая программа для робота. Автоферма пшеницы. local args = {...} local io = require("io") local robot = require("robot") local comp = require("computer") local filesystem = require("filesystem") local r_forward = robot.forward local arg1 = args[1] local arg2 = args[2] function robot.forward() repeat os.sleep(0) until r_forward() return true end if (arg1 == "size") then if (arg2 == nil) then return print("Не указан размер") end local farmsize = io.open("/home/farm.cfg", "w") farmsize:write(arg2) farmsize:flush() farmsize:close() return print("Позиция установлена") end if (filesystem.exists("/home/farm.cfg") == false) then return print("Файл конфигурации не создан! пожалуйста используйте аргумент size *Размер поля*") end local farmsize = io.open("/home/farm.cfg") local size = farmsize:read() farmsize:close() function farm() robot.forward() for y = 1, size do -- собрать 1 линию robot.swingDown() robot.useDown() robot.placeDown() for x = 1, (size - 1) do robot.forward() robot.swingDown() robot.useDown() robot.placeDown() end -- поворот if y % 2 == 1 then robot.turnLeft() robot.forward() robot.turnLeft() else robot.turnRight() robot.forward() robot.turnRight() end end if(size%2 == 0) then robot.turnLeft() robot.turnLeft() robot.turnLeft() -- возвращение на базу for y = 1, (size - 1) do robot.forward() end robot.turnRight() robot.turnLeft() robot.forward() robot.turnRight() robot.forward() robot.turnAround() else for y = 1, (size - 1) do robot.forward() end robot.turnLeft() for y = 1, (size) do robot.forward() end robot.turnRight() robot.forward() robot.turnAround() end end function dropitem() robot.turnAround() for c = 2, 16 do robot.select(c) if robot.count() > 0 then robot.drop() else robot.select(1) break end end robot.turnAround() end if arg1 == "primary" then farm() if robot.count(2) == 64 then dropitem() end end local primary = nil while true do -- таймер(1час) for i = 1, 10 do os.sleep(370) print((10 * i) .. '%') end farm() if robot.count(2) == 64 then dropitem() end end Пару слов об аргументах *name*.lua primary(принудительный запуск сбора) *name*.lua size *size*(установка размера фермы) Также о настройке 1.Ферма должна быть одинаковая по размерам. т.е. 15x15 или 9x9 и т.д. 2.Робот должен быть установлен следующим образом(см.ниже) 3.(по желанию) дать роботу мотыгу чтобы он сам вспахал землю(в принципе просто можно задать ему размеры и дать семена и он сам вспашет землю и посадит семена) Просьба не судить строго так как это моя первая программа и вообще первая программа на языке LUA Жду адекватной критики и предложений. Спасибо за помощь игроку Asummonster
  3. 2 балла
    Зато могут появиться другие)
  4. 1 балл
    - Я умею читать чужие мысли! - А я умею читать чужие регулярные выражения! - Ты победил Люди, которые программируют приложения, связанные с обменом по сети rednet или сохранением на диск, часто сталкиваются с необходимостью преобразования массива данных различных типов в строку и последующим его восстановлением. Под массивом я подразумеваю не отдельно взятую таблицу, а несколько переменных, которые нужно упаковать в одну строку. Самый простой но не самый лучший способ решить эту задачу - поместить все необходимые данные в таблицу и воспользоваться функциями serialize, unserialize из библиотеки textutilse. О недостатках такого способа я уже когда-то говорил и сегодня повторяться не буду. А расскажу о том, как эту проблему решаю я. Предположим нам необходимо упаковать в одну строку значения нескольких переменных (x, y, z). Причем строка должна содержать не только значения переменных, но и информацию о том, что это за переменные. Думаю с упаковкой ни у кого больших проблем не возникнет. Сделать это можно, к примеру, так: s='x='..x..' y='..y..' z='..z В результате мы получим строку, которая содержит имена наших переменных и их значения, отделенные от имен знаками равенства. 'x=10 y=11 z=12' Вроде просто. Но как из этой строки извлечь заложенную в нее информацию, а именно имена и значения? Конечно, можно написать большой и сложный алгоритм посимвольного разбора строки. К счастью, вся скучная работа уже сделана за нас и поставленную задачу мы можем выполнить буквально в одно действие. Я говорю о функциях match и gmatch из библиотеки string. Назначение этих функций - поиск шаблона в строке. К примеру, в строке s, которую я привел выше, я хочу найти подстроку 'y=11'. Для этого я вызываю функцию s:match('y=11') которая и вернет мне искомую подстроку, если она там есть. Параметр 'y=11' будем называть шаблоном. Если шаблон в строке не найден, функция вернет nil. Правда здорово?
  5. 1 балл
    Провел эксперимент, в котором нашел зависимость погрешности геосканера от расстояния между самим сканером и сканируемым блоком. Результаты Максимальная погрешность NMax строго пропорциональна расстоянию R, которую можно вычислить по формуле NMax = R/16.5 (более точный вариант: NMax = R*0.0606 - товарищи посмотрели в код и подсказали). При любом расположении сканируемого блока в зоне видимости сканера 65*65*64 (сканер находится в центре) расстояние можно вычислить по формуле: R = x^2 + y^2 + (z - 33)^2, где x и y - координаты сканируемого столба относительно сканера, а z - номер элемента в таблице, которую возвращает сканер. Применение Знание максимальной погрешности NMax для данного R позволяет нам рассчитать максимальное расстояние, на котором данным методом возможно первым же сканированием гарантированно отличить два блока с твердостями P1 и P2. Для этого требуется вычислить максимально допустимый шум N, при котором полученные со сканера значения точно не будут пересекаться. Получаем неравенство: P1 + N < P2 - N, имеем: N < (P2 - P1)/2. В итоге R = (P2 - P1)/(2*0.0606). Пример применения Допустим, мы хотим робота, добывающего нам алмазы. Для ускорения процесса средствами геосканера отличаем алмазную руду от камня, чтобы не тратить слишком много времени на его выкапывание. Дополнительное время могут занимать и лишние перемещения робота, а значит робот должен не путать руду с камнем и сканировать как можно большую площадь вокруг себя, следовательно подходящей фигурой для области сканирования будет цилиндр. Чтобы узнать его радиус и высоту, нужно узнать радиус описанной вокруг него сферы. Воспользуемся описанным выше методом: R = (3 - 1,5)/(2*0.0606) = 12.376 Алмазы генерируются до 16 высоты, а бедрок - до 5. Если руда не заспавнилась на 3 высоте, ниже копать скорее всего нечего. Отсюда высота цилиндра H = 16 - 3 = 13 блоков. Тогда максимальное расстояние до края цилиндра по вертикали h = (H - 1)/2. За теоремой Пифагора найдем радиус цилиндра r = (R^2 - h^2)^(1/2). Тогда за той же теоремой получаем, что r^2 = x^2 + y^2, где x и y - максимальные координаты сканирования относительно геосканера. Так мы узнаем, до каких x и y мы можем со 100% точностью отличить алмазную руду от камня. Сам эксперимент 1. Создавался кубоид 65*65*64 из обсидиана, так как это максимальная зона сканирования для геосканера. 2. Запихнул робота с геосканером в центр по горизонтали, на 33-ий блок по счету снизу по вертикали (можно было создать 33*33*33 и запихнуть робота в угол, но тогда надо будет определять, в какую сторону сканировать). 3. Загрузил в него с помощью дискеты программу, имеющую функцию "scan", которая многогратно сканирует один и тот же блок в определенных координатах, возвращает среднюю, минимальную и максимальную погрешность. local component = require "component" local io = require "io" local geolyzer = component.geolyzer local path = "/home/geoScanData.txt" local accuracy = 10 local hardness = geolyzer.analyze(3).hardness local radius = 32 local average, min, max = {}, {}, {} local function compareData (scanData, sum, min, max) local lMin, lMax = min, max if scanData < min then lMin = scanData end if scanData > max then lMax = scanData end return sum + scanData, lMin, lMax end local function scan(x, y, zMin, zMax, hardness, accuracy) local sum, min, max = 0, 2, 0 for i = 1, accuracy do local scanData = geolyzer.scan(x, y) for j = zMin, zMax do sum, min, max = compareData(math.abs(scanData[j]-hardness), sum, min, max) end end return sum/(accuracy*(zMax-zMin+1)), min, max end local function DGN(k, radius, x, y, z, hardness, accuracy) for i = 1, radius do average[i+k], min[i+k], max[i+k] = scan(i*x, i*y, 33-i*z, 33-i*z, hardness, accuracy) print(average[i+k].."\n"..min[i+k].."\n"..max[i+k].."\n"..i.."/"..radius.."/"..x+y+z.."\n") end end DGN(0, radius, 1, 0, 0, hardness, accuracy) DGN(radius, radius, 1, 1, 0, hardness, accuracy) DGN(radius*2, radius, 1, 1, 1, hardness, accuracy) print("Done!") file = io.open(path, "w") local len = #average for i = 1, len do file:write(average[i].."\n") end file:write("\n") for i = 1, len do file:write(min[i].."\n") end file:write("\n") for i = 1, len do file:write(max[i].."\n") end file:write("\n") io.close() Три вызова функции "DGN" вызывают функцию "scan" по порядку для каждого блока по определенной линии от робота до края кубоида. На изображении ниже робот находится в углу, а сканируемые блоки для первого, второго и третьего вызова окрашены в цвета, соответствующие окраскам номеров вызовов. Это сделано для того, чтобы проверить, можно ли вычислять расстояние до блока описанными выше формулами, влияет ли отклонение по нескольким осям на результат. В первом вызове проверяются блоки отдаленные только по одной оси, во втором - по двум, в третьем - по трем. Потом программа сохраняет все результаты в файл, после чего я ввожу данные в excel: GeolyzerNoise.xlsx. Первый график показывает зависимость максимальной погрешности от расстояния для 500 сканирований каждого блока. Таким образом расстояние до блока можно вычислять по указанной ранее формулой, результат не зависит от количества осей, по которым блок смещен относительно сканера. Отсюда я и получил константу 1/16.5 Второй график показывает то же самое для средних значений. Еще на нем видно, что даже 30 сканирований дают очень низкую точность, по этому вычислять твердость средним арифметическом невыгодно по затратам времени и энергии. Третий график показывает, что средняя арифметическая погрешность приблизительно в два раза меньше максимальной. Сам не знаю что с этим делать.
  6. 1 балл
    Вместо вступления: Я не считаю C-подобный синтаксис лучше синтаксиса lua и не буду заставлять вас переписывать все ваши программы на TypeScript! Я просто хочу поделится с вами альтернативой и рассказать про ее преимущества и недостатки. # Что такое TypeScript? TypeScript — язык программирования, представленный Microsoft в 2012 году и позиционируемый как средство разработки веб-приложений. Он создан для расширения JavaScript и он компилируется в JavaScript, но также существует инструмент для преобразования TypeScript кода в Lua. Вам может показаться, что этот транслятор крайне ограничен, но, поверьте мне, его возможности впечатляют. # Почему его стоит попробовать? Я сначала продемонстрирую некоторые возможности TypeScript графически, а потом подробно расскажу про установку и настройку необходимых инструментов. Я покажу вам далеко не все возможности TypeScript, а только самые основные и интересные. Из-за большого размера контент каждого раздела будет скрыт под спойлер. 1. Статический анализ 2. Автодополнение 3. ООП 4. Стандартная библиотека и возможности языка # Как это работает? Конечно же все не так просто. Компилятор просто так не узнает типы методов и полей объектов, с которыми мы будем работать. Для того, чтобы описать наше окружение необходимо написать так называемые файлы декларации или тайпинги. Хочу сразу вас обрадовать - это не ваша задача. Существует репозиторий с такими декларациями, в котором, на данный момент, существуют типы для большинства API и компонентов OpenOS и библиотеки GUI. От вас требуется только установить все необходимые инструменты и правильно их настроить. # Установка Редактор кода Вы можете использовать любой редактор кода с поддержкой TypeScript. Я рекомендую VSCode, который поддерживает его из коробки. NodeJS Он необходим нам для установки необходимых пакетов (он поставляется с пакетным менеджером npm) и для запуска транспилера. Вы можете скачать последнюю стабильную версию с официального сайта. Использование плагина для VSCode (рекомендуется): Создание проекта вручную: Для компиляции используйте команду npm run build. Сгенерированные lua файлы появятся в папке dist. # Особенности работы транспилера В этой секции я подробно раскажу про недостатки этого подхода, возможные проблемы и способы их решения. 1. Параметр self 2. Множественные значения 3. Индексы # Ссылки Официальный сайт и документация TypeScript (англ) Серия русских статей по TypeScript Документация TypeScriptToLua (англ) Тайпинги
  7. 1 балл
    Но лично я в подобных случаях не заморачиваюсь с пустыми захватами, а использую функцию gmatch. Она возвращает функцию-итератор, которая при каждом очередном вызове ищет следующее совпадение шаблона в строке. Функция возвращает функцию! Звучит ужасно, но выглядит всё не так страшно, если применить ее в операторе for in s='x=10 y=11 z=12' -- исходная строка t={} -- таблица, в которой будем хранить результат for key, val in s:gmatch('(%w+)=(%d+)') do t[key]=tonumber(val) -- помещаем результат в таблицу end for key, val in pairs(t) do print(key,'=',val) endОператор for in выполнится столько раз, сколько раз будет найден шаблон '(%w+)=(%d+)' в исходной строке. Причем переменные key и val всякий раз будут принимать очередные захваченные значения - имя и значение переменной.Думаю, теперь мы готовы к тому, что бы написать собственные аналоги функций serialize и unserialize.
  8. 1 балл
    Вернемся к строке s='x=10 y=11 z=12', с которой мы начинали знакомство с шаблонами. Мы видели, что извлечь из нее значения переменных можно так: x,y,z=s:match('x=(%d+)%s*y=(%d+)%s*z=(%d+)')или так: x=s:match('x=(%d+)') y=s:match('y=(%d+)') z=s:match('z=(%d+)')Но как быть, если количество, содержащихся в строке переменных очень большое, скажем, несколько тысяч? Неужели их все придется прописывать вручную? Нельзя ли это как то автоматизировать? Последний пример из предыдущего поста подсказывает, что можно. Мы ведь можем захватывать не только значения, но и имена переменных. А полученные значения размещать в таблице где имя переменной будет именем элемента таблицы. Для простоты будем считать, что имена могут состоять из букв или цифр, а значения только из цифр. Пропишем шаблон для поиска одной переменной и заключим его в цикл для поиска остальных. s='x=10 y=11 z=12' -- исходная строка t={} -- таблица, в которой будем хранить результат for i=1,3 do key, val=s:match('(%w+)=(%d+)') -- извлекаем имя и значение t[key]=tonumber(val) -- помещаем результат в таблицу end for key, val in pairs(t) do -- выводим результат print(key,'=',val) endПриведенный пример кода загружает из исходной строки имена и значения переменной в таблицу t. Однако, если мы попытаемся этот код выполнить, то увидим, что в результате таблица t будет содержать только одно значение x=10. Произошло так потому, что функция match всегда начинает поиск совпадений с начала строки. Всегда, если ей не указать с какого места нужно начинать поиск. Оказывается match имеет еще один необязательный параметр, указывающий с какой позиции строки следует начинать поиск. Его можно узнать вставив в шаблон пустой захват (). Такой захват вернет позицию символа в строке, следующего за найденной подстрокой. s='x=10 y=11 z=12' -- исходная строка t={} -- таблица, в которой будем хранить результат n=1 -- начинаем поиск с начала строки for i=1,3 do key, val, n=s:match('(%w+)=(%d+)()',n) -- извлекаем имя и значение -- пустой захват ставим в конце шаблона, чтобы от вернул позицию символа, следующего за найденной подстрокой t[key]=tonumber(val) -- помещаем результат в таблицу end for key, val in pairs(t) do print(key,'=',val) endПосле внесенных изменений код должен работать более корректно.
  9. 1 балл
    Уточню перечень спецсимволов, используемых в шаблонах . (точка) - заменяет любой символ. %a --- все буквы. %c --- все управляющие символы. (Символы с кодом от 0 до 31, которые не имеют графического представления) %d --- все цифры. %l --- все строчные буквы. %p --- все знаки препинания. %s --- все пробелы (символы с кодом 9, 10, 12, 13, 32). %u --- все заглавные буквы. %w --- все алфавитно-цифровые символы (буквы и цифры). %x --- все шестнадцатеричные цифры (цифры и буквы a-f, A-F). %z --- символ с кодом 0. Использование заглавной буквы в качестве спецсимвола меняет смысл на противоположный. Например %A - все символы кроме букв, %S - все печатные символы Так же хочу добавить еще два спецсимвола ^ и $. Если шаблон начинается с символа ^ или заканчивается символом $, то искаться такой шаблон будет соответственно в начале или в конце исходной строки. Несколько примеров использования шаблонов: '[%+%-]?%d+' - ищет целое число в десятичном формате '0x%x+' - число в шестнадцатеричном формате s= s:match('^%s*(.*)%s*$') - удаляет из строки начальные и конечные пробелы key, val = s:match('([%a_][%w_]*)%s*=%s*(%S+)') - разбирает конструкцию типа key = val, причем имя key должно содержать буквы, цифры или символ подчеркивания и начинаться с буквы или подчеркивания, а val может содержать любые символы кроме пробела.
  10. 1 балл
    Шаблоны, которые я рассматривал до сих пор, возвращали строку, требующую дополнительной обработки. В самом деле, если функция match вернула строку 'y=11', то из этой строки необходимо выделить символы, соответствующие значению переменной. Например, вызвать функцию match еще раз. А нельзя ли обойтись одним вызовом? Оказывается можно. Делается это при помощи структуры, называемой захват (capture). Захват оформляется в виде группы символов, заключенных в круглые скобки. Если шаблон содержит захват, то он возвращает не всю совпавшую подстроку, а только захваченное значение, т.е. символы, соответствующие символам захвата. Пример: s:match('y=(%d+)') вернет строку не 'y=11', а '11' Обращаю внимание, match всегда возвращает строку, даже если вы ищите число. Так что от преобразования типа tonumber никуда не деться. Захватов в шаблоне может быть несколько. В этом случае match возвращает столько значений сколько захватов присутствует в шаблоне. Это позволяет искать сразу несколько значений в строке за один раз. Например: s='x=10 y=11 z=12' x,y,z=s:match('x=(%d+)%s*y=(%d+)%s*z=(%d+)') Тут нужно быть внимательным. Во-первых, не забываем про разделители, если они есть (в примере разделителями являются символы пробел - %s). Во-вторых, следует помнить, что шаблон стреляет только тогда, когда совпал целиком. Т.е. если из трех захватов, приведенных в примере, найдены два, а третий не найден, результатом работы функции будет nil и все три переменные x,y,z будут не определены. Поэтому, если вы не уверены, что в исходной строке присутствуют все искомые значения, воспользуйтесь тремя разными поисками. Или же функцией gmatch, о которой я расскажу чуть позже.
  11. 1 балл
    Символы и спецсимволы в шаблоне можно объединять в наборы (сеты). Для этого несколько символов заключаются в квадратные скобки. Набор замещает собой один из символов, входящих в его состав. Например, вот такой набор [%d%p] замещает цифру или знак препинания. А такой [_%w] - букву, цифру или символ подчеркивания. Порядок символов, в котором они идут в наборе значения не имеет. Теперь мы можем найти в строке значение переменной y даже если оно будет отрицательным или сопровождаться знаком + s:match('y=[%+%-]?%d+') Знаки % перед + и - говорят о том, что это не спецсимволы, а обычные + и - Знак ? после набора указывает на то, что + или - могут отсутствовать. А вот такой шаблон s:match('y=[%+%-%d]%d*%.?%d*') позволит найти число в формате с десятичной точкой. Если набор начинается с символа ^ , то такой набор интерпретируется как "всё кроме указанных символов".
  12. 1 балл
    Вы наверняка подумали, а зачем искать в строке значение переменной y, если для поиска нужно знать значение этой переменной? Как быть если значение y заранее не известно? Чаще всего так и происходит. Тогда в шаблон вместо цифр необходимо подставить специальные символы. В нашем случае это %d. s:match('y=%d%d') Спецсимволы в шаблоне заменяют собой другие символы. Спецсимволов припоминаю несколько: %a - заменяют все буквы %d - все цифры %w - буквы и цифры %p - знаки препинания %s - пробел .(точка) - любой символ %. - символ "точка" Спецсимволов чуть больше, но остальные не столь актуальны. Надеюсь, понятно, что функция s:match('y=%d%d') будет искать в строке s подстроку состоящую из символов 'y=' и еще каких то двух цифр. Именно эту подстроку она и вернет. Если найдет. А вдруг мы не знаем из скольки символов состоит значение переменной y. В этом случае на помощь приходят модификаторы. Модификаторы это такие спецсимволы, которые изменяют количество символа за которым стоят в шаблоне. Вот такие я знаю модификаторы: + - соответствует одному или более повторений символа; * - соответствует нулю или более повторений; - - соответствует нулю или более повторений. В отличии от модификатора * возвращает строку минимально возможной длины, но так, что бы она соответствовала шаблону; ? - соответствует нулю или одному символу. Если мы знаем, что значение переменной y состоит из какого то количества цифр (но не менее одной), следует применить модификатор + s:match('y=%d+') Эта функция будет искать в строке s подстроку состоящую из символов 'y=' и какого то количества цифр. Причем вернет подстроку максимально возможной длины, т.е. 'y=' и все цифры следующие за знаком равенства. Продолжение следует ...
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...