Вам предоставляется функция Rand5 (). Эта функция возвращает совершенно случайные (равное распределение) целые числа от 1 до 5.
Предоставьте функцию Rand7 (), которая использует Rand5 () для получения совершенно случайных целых чисел от 1 до 7.
code-challenge
math
random
Дэн МакГрат
источник
источник
Ответы:
Ява - 61 символ
Тестовый драйвер для проверки:
Полученные результаты
источник
rand5
. Я вычислил их в Maple, используя простую матричную алгебру, но вы можете сделать это карандашом и бумагой за несколько минут, если хотите. Так или иначе, оказывается, что Омар уже опубликовал те же цифры (без нормализующего фактора) в комментарии к другому ответу пару дней назад. (Также, вы можете @ уведомить только одного пользователя за комментарий, хотя автор сообщения всегда уведомляется.)Perl - 47 (было 52) символов
Плюс я использую троичный оператор И рекурсию. Самый лучший день!
ОК, 47 символов, если вы используете мод вместо div:
источник
&
знака, чтобы уменьшить его до 46 символов (включая пробел, в котором ваша текущая версия равна 48).JavaScript, 42
Бонус ES5 вещь:
источник
Ruby - 54 символа (на основе решения Дэна МакГрата с использованием цикла)
Рубин - 45 символов (то же решение, с использованием рекурсии)
источник
(x=rand5+5*rand5-5)>7?
.В Python:
источник
В Common Lisp 70 персонажей:
Скобки занимают больше места, чем хотелось бы.
источник
(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
В c / c ++ используется выборка отклонения
62 персонажа.
источник
while(x>7)
так, что оно будет удовлетворяться только числами в допустимом диапазоне.Перевод на PHP, из ответа выложил Дэн МакГрат.
67 символов.
источник
R, 34 символа
В R (язык, построенный для статистических вычислений), преднамеренно обманчивое решение:
Благодаря ленивой оценке аргументов я исключил точку с запятой и скобки.
Вывод более 10 ^ 6 копий:
источник
Rand7=function(){r=Rand5();sample(7)[r]}
Rand7=function(){sample(7)[Rand5()]}
Скала,
47, 4059 символов:с 2 входами от rand5:
Я умножаю первое-1 на 5 и добавляю второе. Большинство результатов игнорируются и приводят к новым расчетам. Результат должен быть равным распределением значений от 1-25, из которого я выбираю только первые 7. Я мог бы принять первые 21 с построением по модулю, но это привело бы к более длинному коду.
исторический кодекс, который провалился, но не очень очевидно. Спасибо Ильмари Каронену за указание на это:
Спасибо Yoshiteru Takeshita, за этот подход scala-2.8.0, который сделал «сумму» такой простой. Мое решение раньше:
rand5:
источник
def rand7=(1 to 7).map(_=>rand5).sum%7+1
C ++
С ++ (109)
Golfed
источник
Перевод в Javascript, из ответа, опубликованного Дэном МакГрат.
62 символа
источник
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}
немного короче: PJavaScript, 85
Я знаю, что есть более короткий ответ, но я хотел показать тест этой головоломки. Оказывается, что только ответ Клайда Лобо, использующий выборку отклонения Дэна Макгрэта, является правильным (между ответами JS).
источник
С ++
Распределение чисел (1000000 целых чисел):
Среднее количество вызовов Rand5 () на каждое сгенерированное целое число составляет около 2,2 (от 2 до 10+).
источник
В Java (или C / C ++, я полагаю)
используя формулу генерации Александру, в 65 символов:
используя формулу генерации Дэна МакГрата, в 60 символов
источник
Clojure - 58 символов
источник
Питон,
5637 символовДругое решение, которое может быть неправильным, в Python:
Это кажется слишком простым, но когда я пытаюсь:
Я получаю достаточно равномерное распределение (все между 14000 и 14500).
Хорошо, теперь, когда кто-то голосовал за этот пост: действительно ли это решение правильно? Я более опубликовал это здесь, чтобы люди критиковали это. Ну, если это правильно, моя версия для гольфа будет:
который выходит на 37 символов.
источник
Java, 65 символов:
источник
Питон, 70 символов
но совершенно правильно, основываясь на рассуждениях здесь .
источник
Perl, 43 символа, итеративная выборка отклонения
Это дает предупреждение
Ambiguous use of -rand5 resolved as -&rand5()
, но работает правильно. При добавлении&
также ко второмуrand5
вызову это исправляется за счет одного удара. (И наоборот, другой&
также может быть удален, еслиrand5
он был определен с()
прототипа.)Ps. Следующая версия из 46 символов примерно в три раза быстрее:
источник
Java - 66 символов
Дольше, чем предыдущая процедура, но я думаю, что она возвращает равномерно распределенные числа за меньшее время.
источник
PostScript (46)
Это использует двоичную кодировку токена, поэтому вот hexdump:
Чтобы попробовать это, вы также можете скачать его .
Вот код без комментариев и комментариев, а также тестовый код.
источник
источник
R (30 символов)
Определите rand7:
Поскольку R был написан с учетом статистического анализа, эта задача тривиальна, и я использую встроенную функцию
sample
с заменой, установленной на TRUE.Образец вывода:
источник
Groovy
Пример распределения по 35 000 итераций:
Это плохо, что это с состоянием?
источник
Математика, 30
источник
Как насчет этого?
источник
/
оператор выполняет целочисленную математику? Что происходит с вашими результатами, если он выполняет десятичную, с плавающей или целочисленную математику?[2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]
. Не совсем равномерно.Ява - 54
Распределительный тест:
[1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]
Алгоритм:
> Числа больше не взаимно коррелированы, а индивидуально совершенно случайны.
источник
Рубин (43 байта)
Решение cemper93, портированное на Ruby, на три байта короче;) (34 байта)
источник
Код C / C ++, основной код имеет только одну строку!
Srand7 () - это семя rand7, оно должно вызывать эту функцию перед rand7, точно так же, как вызывать srand перед rand в C.
Это очень хороший вариант, потому что он вызывает rand () только один раз, и никакой цикличности, никакой дополнительной памяти не тратится.
Позвольте мне объяснить это: рассмотрим целочисленный массив размером 5:
Итак, мы получили ТАБЛИЦУ, каждая из 1-7 встречается в ней 5 раз и имеет все 35 чисел, поэтому вероятность каждого числа составляет 5/35 = 1/7. И в следующий раз
После достаточного количества раз мы можем получить равномерное распределение 1-7.
Таким образом, мы можем выделить массив для восстановления пяти элементов 1-7 по loop-left-shift и каждый раз получать одно число из массива по rand5. Вместо этого мы можем сгенерировать все семь массивов и использовать их циклически. Код также прост, имеет много коротких кодов, способных сделать это.
Но мы можем использовать свойства операции%, поэтому строки таблицы 1-7 эквивалентны (rand5 + i)% 7, то есть: a = rand ()% 5 + 1 - это rand5 на языке C, b = gi ++ % 7 генерирует все перестановки в таблице выше, а 0 - 6 заменяют 1 - 7 c = (a + b)% 7 + 1, генерируют 1 - 7 равномерно. Наконец, мы получили этот код:
Но мы не можем получить 6 и 7 при первом вызове, поэтому нам нужно начальное число, например srand for rand в C / C ++, чтобы дезорганизовать перестановку для первого формального вызова.
Вот полный код для тестирования:
источник
6
или7
позвонив один раз ?int main(){if(rand7()==6) printf("Hello, world!");}
, аппроксимация с использованием цикла выведет «Hello, world!» 1 в 7 раз, но ваш код не.