ArtHacker 38 Опубликовано: 22 ноября, 2019 Как получить рандомное число? Просто math.random() в конце ещё .0 добавляет. Нам не нужно дробное число. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 14 января, 2022 2 часа назад, num_pi сказал: function rand() local res = "" for i = 1, 8 do res = res .. string.char(math.random(48, 57)) end return tonumber(res) end А зачем так сложно? В чём преимущество этого решения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
num_pi 29 Опубликовано: 14 января, 2022 (изменено) 11 минуту назад, eu_tomat сказал: А зачем так сложно? В чём преимущество этого решения? В том что оно работает =) Что конкретно тут сложно? Попробуй убрать string.char, посмотри что из этого получится. Изменено 14 января, 2022 пользователем num_pi Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 14 января, 2022 1 минуту назад, num_pi сказал: В том что оно работает =) Что конкретно тут сложно? Попробуй убрать string.char, посмотри что из этого получится. Конкретно тут math.random вызывается 8 раз. Разве не достаточно одного раза? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
num_pi 29 Опубликовано: 14 января, 2022 Только что, eu_tomat сказал: Конкретно тут math.random вызывается 8 раз. Разве не достаточно одного раза? math.random(48, 57). Число 48 это unicode символ, а именно число 0, соответственно для числа 57, почти тоже самое, это число 9. Получается что я, говорю math.random, дай мне рандомный unicode char, с 48 по 57, потом делаю конкатенацию в for. Главное что работает, и делает именно то что просил человек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 14 января, 2022 3 минуты назад, num_pi сказал: Главное что работает, и делает именно то что просил человек. Человек получил простое решение в первом же сообщении. Разумеется, можно придумать ещё сотню вариантов различной степени сложности. Но зачем? Твой вариант имеет два недостатка: громоздкий код и повышенную нагрузку на сервер. Это может быть оправданным, если недостатки компенсируются каким-нибудь преимуществом. Поэтому возвращаемся к исходному вопросу: 36 минут назад, eu_tomat сказал: В чём преимущество этого решения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 14 января, 2022 4 часа назад, num_pi сказал: res = res .. string.char(math.random(48, 57)) 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Anon 25 Опубликовано: 14 января, 2022 5 часов назад, num_pi сказал: Держи готовую функцию. for i = 1, 8 do: здесь поменяй 8, на большее число, если нужно что бы рандомное возвращаемое число было больше. function rand() local res = "" for i = 1, 8 do res = res .. string.char(math.random(48, 57)) end return tonumber(res) end 1) Магические числа - быдлокод. Что за 48 и 57? string.byte ('0'), string.byte ('9'). 2) Результат будет всегда 8-значный или N-значный 3) math.floor?????? Ну и наконец, math.random возвращает целое число, если в него передать целое значение. math.random (10000000). О производительности твоего примера я даже боюсь говорить. Вызов string.char в цикле, конкатенация строк, которые в луа иммутабельны просто убьют процессор, если функция будет использоваться часто. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Anon 25 Опубликовано: 14 января, 2022 2 часа назад, num_pi сказал: . Главное что работает Типичный сотрудник ubisoft: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 14 января, 2022 В 14.01.2022 в 12:19, num_pi сказал: Держи готовую функцию. for i = 1, 8 do: здесь поменяй 8, на большее число, если нужно что бы рандомное возвращаемое число было больше. Оставлю свои пять копеек для тех, кому нужно генерировать рандомные числа фиксированной длины. Хотя к теме это относится опосредованно, но мало ли: -- Вариант 1 local function fixedLengthRandom(digits) digits = 10 ^ (digits - 1) return math.random(digits, digits * 10 - 1) end -- Вариант 2 local function fixedLengthRandom(digits) digits = 10 ^ (digits - 1) return math.floor(digits + math.random() * (digits - 1)) end Вместо math.floor для ускорения процесса можно использовать операцию целочисленного деления // 1.0, однако она сохраняет нулевую дробную часть в результате и доступна только в Lua 5.3. На ваше усмотрение, короче. Результат: >> fixedLengthRandom(4) >> 4981 >> fixedLengthRandom(8) >> 15896813 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 14 января, 2022 2 часа назад, ECS сказал: Вместо math.floor для ускорения процесса можно использовать операцию целочисленного деления // 1.0 А зачем здесь требуется math.floor? В 22.11.2019 в 18:35, eu_tomat сказал: math.random(lower, upper) генерирует целое число в диапазоне [lower..upper]. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 14 января, 2022 1 час назад, eu_tomat сказал: А зачем здесь требуется math.floor Прогнал, скопипастив из 2 примера. Спасибо, исправил Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Joe 0 Опубликовано: 14 января, 2022 В 13.01.2022 в 21:34, eu_tomat сказал: @Joe Числа из одной последовательности и должны быть разными, как правило. Выше речь шла не о совпадении чисел внутри последовательности, а о совпадении самих последовательностей с момента запуска Lua. Получается как я понял, если использовать несколько раз команду print(math.random()) в компьютере из opencomputers, то получится один и тот же ответ? Или как? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 15 января, 2022 19 минут назад, Joe сказал: Получается как я понял, если использовать несколько раз команду print(math.random()) в компьютере из opencomputers, то получится один и тот же ответ? Или как? Нет. В этом случае получатся разные числа, хоть в цикле их запросишь, хоть без цикла, это не имеет значения. Об этом можно не волноваться. Мои примеры должны были лишь продемонстрировать, что последовательности не случайны. И для этого я использовал стерильные условия. В OpenComputers же этой стерильности нет. Предсказуемость может возникнуть разве что по ошибке программиста, инициализирующего ГПСЧ при каждом запуске программы одинаковым значением. Разумеется, так делать не надо. Но даже если инициализировать ГПСЧ текущим временем, то хакер, зная код программы, имеет шанс вычислить последовательность якобы случайных чисел, что позволит ему, например, выигрывать в неаккуратно написанных казино. О, я совсем забыл поделиться своей радостью! Как хорошо, что эта тема, спустя два года, поднялась вновь. С момента прошлого обсуждения я нашёл идеальный для OpenComputers источник энтропии. Вряд ли удастся найти лучший. Работает быстро и крайне непредсказуемо. math.randomseed( -1e18*(os.clock()-os.clock()) ) Что ещё может быть более случайным в OpenComputers? Предлагайте свои варианты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Joe 0 Опубликовано: 15 января, 2022 1 час назад, eu_tomat сказал: Предсказуемость может возникнуть разве что по ошибке программиста, инициализирующего ГПСЧ при каждом запуске программы одинаковым значением. Разумеется, так делать не надо. Это как при написание рандомайзера на плате arduino, и при компиляции код замкнуть один из цифровых контактов, числа всегда будут одинаковы. 1 час назад, eu_tomat сказал: Но даже если инициализировать ГПСЧ текущим временем, то хакер, зная код программы, имеет шанс вычислить последовательность якобы случайных чисел, что позволит ему, например, выигрывать в неаккуратно написанных казино. Я подозреваю, что на этапе получения кода, у хакера появятся сложности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 15 января, 2022 12 часа назад, eu_tomat сказал: math.randomseed( -1e18*(os.clock()-os.clock()) ) Идея с clock хорошая, но будет работать только в рамках мода из-за хука на вызовы функций в machine.lua. А как ты выбрал магическую константу? Это явно не math.mininteger/maxinteger, а что-то чернокнижное 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astral17 65 Опубликовано: 15 января, 2022 В 14.01.2022 в 16:49, ECS сказал: Оставлю свои пять копеек для тех, кому нужно генерировать рандомные числа фиксированной длины. Хотя к теме это относится опосредованно, но мало ли: -- Вариант 1 local function fixedLengthRandom(digits) digits = 10 ^ (digits - 1) return math.random(digits, digits * 10) end -- Вариант 2 local function fixedLengthRandom(digits) digits = 10 ^ digits return math.floor(digits + math.random() * (digits - 1)) end Только они чутка бракованные. В первом варианте поскольку рандом с границами генерирует включительно, иногда генерирует на 1 цифру больше, т. е. [1; 10], [10; 100] и т. д. А во втором варианте оно вообще фигню делает, [10; 18], [100; 198] и т. д. Ну и чутка бессмысленный момент: 0 это число длины 1, а должна ли функция его генерировать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 15 января, 2022 2 часа назад, astral17 сказал: Только они чутка бракованные Черт, стыдно стало, поправил диапазон :d 2 часа назад, astral17 сказал: 0 это число длины 1, а должна ли функция его генерировать? А тут начинается le classique, то есть выбор между производительностью и охватом всех вероятных условий и ошибок. По ТЗ, формируемому названием функции, - да, должна, а ещё ей по-хорошему не хватает парочки валидаций. Начнем с того, что количество цифр в генерируемом числе не должно быть < 1, ибо таких чисел не существует. Также оно не может быть больше 18 для 64-битного бинарника Lua, т.к. именно 18 является максимально допустимой степенью показательной функции f(x) = 10 ^ x, значение которой не превышает рабочий диапазон. Пруф: math.log(math.maxinteger, 10) > 18.964889726831 math.random(10 ^ 18) > 902800305889519796 math.random(10 ^ 19) > stdin:1: bad argument #1 to 'random' (number has no integer representation) И наконец, можно добавить поддержку генерации нуля в крайне странном случае, когда кто-то решил воспользоваться нашей функцией вместо math.random(0, 9): local function fixedLengthRandom(digits) assert(digits >= 1 and digits <= 18, "Digit count is out of range [1; 18]") if digits == 1 then return math.random(0, 9) end digits = 10 ^ (digits - 1) return math.random(digits, digits * 10 - 1) end Это что касается решения "по бумажкам в лабораторных условиях". На практике же оно на фиг никому не упало, и куда предпочтительнее был бы производительный вариант без избыточных проверок, которые имеют свой бюджет вызовов в опенкомпах. Так что же правильнее? Наверное, то, что лично ты считаешь правильным для конкретной ситуации Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 148 Опубликовано: 15 января, 2022 4 часа назад, ECS сказал: Идея с clock хорошая, но будет работать только в рамках мода из-за хука на вызовы функций в machine.lua. А разве нам требуется что-то кроме этого? Во взрослых средах имеются более адекватные источники энтропии. А в среде OpenComputers приходится импровизировать. 7 часов назад, ECS сказал: А как ты выбрал магическую константу? Это явно не math.mininteger/maxinteger, а что-то чернокнижное Это значение выбрано на глаз. На шаманский глаз. Достаточно было бы и math.pow(2,52), чтобы перевести в целую часть все разряды мантиссы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS 1 901 Опубликовано: 16 января, 2022 12 часа назад, eu_tomat сказал: А разве нам требуется что-то кроме этого? Во взрослых средах имеются более адекватные источники энтропии. А в среде OpenComputers приходится импровизировать Нет, для мода, конечно, не требуется. Я на всякий случай подчеркнул этот момент - вдруг какая-то заблудшая душа будет искать ответ и не поймет, какого ж черта os.clock() - os.clock() может выдавать что-то, отличное от нуля. И будет плакать... 12 часа назад, eu_tomat сказал: Достаточно было бы и math.pow(2,52), чтобы перевести в целую часть все разряды мантиссы А, вон какая логика была. Занятно, спасибо Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
hohserg 195 Опубликовано: 16 января, 2022 А почему os.clock() - os.clock() случайное? Первый вызов начинает выполняться в момент t1, какое-то время выполняется и возвращает значение T1 между t1 и t2 Второй вызов начинает выполняться в момент t2, какое-то время выполняется и возвращает значение T2 между t2 и t3 Какие значения тут случайны? Длительность выполнения os.clock()? Возвращаемые им значения?(в пределах длительности) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Как получить рандомное число?
Просто math.random() в конце ещё .0 добавляет. Нам не нужно дробное число.
Поделиться сообщением
Ссылка на сообщение
Поделиться на других сайтах