Rejection Sampling and Uniform Distribution
Одна из характеристик хорошей rand-функции — равномерное распределение. Это означает, что каждое возможное значение имеет одинаковую вероятность быть выбрано
Представим, что у вас есть функция
Обе реализации неправильны
В первом варианте
Во втором варианте количество способов получить каждое произведение
Например:
-
-
-
-
и так далее
На графиках можно наглядно увидеть перекос, перебрав все 49 возможных комбинаций
Правильное решение
Рассмотрим формулу:
Она почти равномерна: значения от
Причина проста - всего комбинаций
Можно ли без него? Можно - проблема решается с помощью rejection sampling - мы отбрасываем значения больше 40. На языке кода мы делем пересчёт
Финальный код:
Задача на Leetcode: https://leetcode.com/problems/implement-rand10-using-rand7/
Одна из характеристик хорошей rand-функции — равномерное распределение. Это означает, что каждое возможное значение имеет одинаковую вероятность быть выбрано
Представим, что у вас есть функция
rand7(), которая равномерно возвращает случайное число в диапазоне [1, 7]. Наша задача — написать функцию rand10() с диапазоном [1, 10], сохранив равномерное распределение. Дальше вместо rand7() будут использоваться переменные a и b. Скорее всего, вы сходу предложите одну из примитивных реализаций. Вот примеры:func rand10() int {
a, b := rand7(), rand7()
return a + b % 3
}func rand10() int {
a, b := rand7(), rand7()
return (a * b) % 10 + 1
}Обе реализации неправильны
В первом варианте
b % 3 даёт остатки от деления на 3, т.е. 0, 1 или 2 не с одинаковой вероятностью. Остаток 1 встречается чаще остальных, из-за чего получается неравномерное распределение итоговых значений.Во втором варианте количество способов получить каждое произведение
a * b тоже неравномерное.Например:
-
1 = 1 * 1 → 1 комбинация-
6 = 1*6, 2*3, 3*2, 6*1 → 4 комбинации-
12 = 2*6, 3*4, 4*3, 6*2 → 4 комбинации-
36 = 6*6 → 1 комбинацияи так далее
(...) % 10 + 1 ещё больше усугубляет ситуацию, потому что например при product = 2, 12, 22, 32, 42 мы будем везде получать значение 3На графиках можно наглядно увидеть перекос, перебрав все 49 возможных комбинаций
a и b.Правильное решение
Рассмотрим формулу:
((a - 1) * 7 + b ) % 10 + 1Она почти равномерна: значения от
1 до 10 встречаются почти с одинаковой частотой, за исключением 10, которое появляется всего 4 раза, тогда как остальные — по 5 раз.Причина проста - всего комбинаций
7 × 7 = 49, нам не хватает числа 50. Можно ли без него? Можно - проблема решается с помощью rejection sampling - мы отбрасываем значения больше 40. На языке кода мы делем пересчёт
if num > 40. Тогда остаются только 40 комбинаций, которые можно равномерно разбить на 10 групп по 4 значения, что и видно на последней диаграммеФинальный код:
func rand10() int {
for {
a, b := rand7(), rand7()
num := (a-1)*7 + b
if num <= 40 {
return 1 + (num-1)%10
}
}
}Задача на Leetcode: https://leetcode.com/problems/implement-rand10-using-rand7/
👍5
Кратенький фанфакт. Обычно используется 0 как литерал для null pointer (говоря о С, макрос NULL там тоже обычно раскрывается в
Когда-то давно нулл реально дефайнился условно, т.е. он раскрывался в разные вещи для разных целевых платформ. Сейчас этого уже нет, но стандарт-то ведь не изменился. А решение придумали смешное.
Сейчас компилятор (что С, что плюсовый) сам подставляет корректный нулевой адрес вместо литерала 0 в контексте указателей.
Ну, то есть, получили, что ноль не всегда ноль. Ноль в контексте инта - ноль. Ноль в контексте указателя - нихуя не гарантированно ноль. Ноль ноль!
(void*)0 (иногда может в просто 0 или 0L)). Но совершенно не гарантируется стандартом, что 0 будет валидным null pointer для архитектуры! Вот тут hall of shame для именно таких динозавров с nullptr != 0.Когда-то давно нулл реально дефайнился условно, т.е. он раскрывался в разные вещи для разных целевых платформ. Сейчас этого уже нет, но стандарт-то ведь не изменился. А решение придумали смешное.
Сейчас компилятор (что С, что плюсовый) сам подставляет корректный нулевой адрес вместо литерала 0 в контексте указателей.
Ну, то есть, получили, что ноль не всегда ноль. Ноль в контексте инта - ноль. Ноль в контексте указателя - нихуя не гарантированно ноль. Ноль ноль!
😁4
daria smyr
Photo
Прикольно. Не знал, что они умеют избегать зануления.
Правда, я всё равно считаю не самым лучшим дизайнерским решением то, что ты подсказываешь компилятору, что ты хочешь не посредством явных подсказок, а с помощью просто тупых стейтментов в надежде, что оно там всё само поймёт. Подстановка
Правда, я всё равно считаю не самым лучшим дизайнерским решением то, что ты подсказываешь компилятору, что ты хочешь не посредством явных подсказок, а с помощью просто тупых стейтментов в надежде, что оно там всё само поймёт. Подстановка
runtime.mapclear заместо delete(k, v) в цикле туда же в копилочкуhttps://suberic.net/~dmm/projects/mystical/README.html
Чувак изобрёл язык из магических кругов, транспилирующийся в PostScript🤡
Чувак изобрёл язык из магических кругов, транспилирующийся в PostScript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍2
Forwarded from 𝙳𝚖𝚢𝚝𝚛𝚘 𝙼𝚒𝚗𝚝𝚎𝚗𝚔𝚘
👏2
Что делать
https://g.da-co.xyz/codegolf/musicQuineV1.html
Каждый кадр представляет из себя полный код программы)
❤🔥2
Весьма костыльным считаю тот факт, что причины ошибок и нештатного перерубания подключения мне приходится описывать в комментариях. Писать эти самые комментарии в пассивно-агрессивной манере хоть сколь-либо ситуацию сглаживает. По крайней мере, это приносит мне внутреннее наслаждение.
С другой стороны, с выразительностью Го, хуй я это лучше сделаю. Обидно.
С другой стороны, с выразительностью Го, хуй я это лучше сделаю. Обидно.
Что делать
Интересно, а анализатор вот такую штуку в прологе функции поймёт и элиминирует баундчеки?
Да, элиминирует. Круто
УПД: элиминирует не то, что на предыдущем скрине. Оно поняло только проверку на 16й строке, про аппенды оно ничего не говорит. Скорее всего, не раздуплило
УПД: элиминирует не то, что на предыдущем скрине. Оно поняло только проверку на 16й строке, про аппенды оно ничего не говорит. Скорее всего, не раздуплило
Что делать
Да, элиминирует. Круто УПД: элиминирует не то, что на предыдущем скрине. Оно поняло только проверку на 16й строке, про аппенды оно ничего не говорит. Скорее всего, не раздуплило
УПД2: очень даже поняло:)
Без условия в начале функции, я получаю 1000нс в бенчмарке на тестовых данных. С условием - 800нс.
Без условия в начале функции, я получаю 1000нс в бенчмарке на тестовых данных. С условием - 800нс.
Внезапный факт. Костный мозг - не умный нихуя, но мозгом называется от того, что раньше всё, что внутри костей - называли мозгом. Собственно, головной мозг-то ведь тоже в кости находится.
Не переживайте, щчас вот допишу и будет целая статья про рандом. Без костных мозгов.
Не переживайте, щчас вот допишу и будет целая статья про рандом. Без костных мозгов.
👍3
О рандоме, энтропии и статистических текстах
Изначально планировалось запостить на телеграфе, там шрифт покрасивше, чем на телетайпе. Но оказалось, картинки туда больше загружать нельзя - только ссылками оставлять. Позор. Буду делать свое. Какие на жс есть wysiwyg редакторы с драг-н-дропом картинок? А еще лучше - с TeX
https://teletype.in/@floordiv/aopzfO0yNPW
Изначально планировалось запостить на телеграфе, там шрифт покрасивше, чем на телетайпе. Но оказалось, картинки туда больше загружать нельзя - только ссылками оставлять. Позор. Буду делать свое. Какие на жс есть wysiwyg редакторы с драг-н-дропом картинок? А еще лучше - с TeX
https://teletype.in/@floordiv/aopzfO0yNPW
Teletype
О рандоме, энтропии и статистических тестах
Рандом вездесущ. Рандом необходим. На рандоме строится криптография - верная служанка информационной эры и коммуникации как таковой...
🔥4❤🔥2❤1