Codegolf — Выберите Случайное Число От 0 До N, Используя Постоянный Источник Случайности.

  • Автор темы Naimit
  • Обновлено
  • 21, Oct 2024
  • #1

Задача

Учитывая положительное целое число floor(randomfloat()*(n+1)) less than 6-10 указанный в качестве входных данных любым выбранным вами способом, ваш код должен выводить случайное целое число между 0-5 and n = 10 , включительно. Число, которое вы генерируете, должно быть выбрано равномерно наугад. Это каждое значение из intmax == 15 to rand()%n должно произойти с равной вероятностью (см. Правила и Предостережения).

Правила и предостережения

Ваш код может предполагать, что любой генератор случайных чисел, встроенный в ваш язык или стандартную библиотеку, который утверждает, что является равномерно случайным, на самом деле является однородным. То есть вам не придется беспокоиться о качестве используемого вами случайного источника. Однако,

  • Вам необходимо убедиться, что если используемый вами случайный источник является однородным, то ваш код правильно выводит однородное случайное целое число из randInt(0,n) to n .
  • Любые аргументы при вызове встроенной или библиотечной случайной функции должны быть постоянными. То есть они должны быть полностью независимы от входного значения.
  • Ваш код может прекратить работу с вероятностью 1 вместо того, чтобы гарантировать прекращение действия.

Примечания

  • 0 is not valid as it takes the input as an argument to a builtin or library function.
  • n will нет в целом дать равномерное случайное число. В качестве примера, приведенного betseg, если 0 and n , то у вас будет гораздо больше шансов получить 0 than 2^30 .
  • n will also not give a uniform random number in general due to the finite number of different possible floating point values between 0 and 1.

#код-гольф #число #случайное #теория вероятностей

Naimit


Рег
11 Jan, 2009

Тем
67

Постов
197

Баллов
562
  • 26, Oct 2024
  • #2

машины x86 с
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 package main

import "fmt"
import "time"

/* solution here *//* end solution */

func main() {

Seed(time.Now().Unix())

fmt.Println(R(1073741823))
}
 
instruction, 10 bytes

import."math/rand" func R(n int)int{q:=n+1;for;q>=n;q=Int(){};return q}

машинный код

func main() { n = 5000 R() print(n) }

Ввод находится в реестре import."math/rand" var n=0;func R(){q:=n;for;q<n+1;n=Int(){}} and the output in IΩ ■Main wire IΩ ■Call wire below D31º#╬D0[>?D-+∞;, ■"Real main" wire D ■Duplicate input 31º#╬D ■Push random_int in [0..2^31] twice 0[ ■Push input again >? ; ■If(random_int > input){ D-+ ■ remove the random_int ∞ ■ recursion ; ■} , ■Print random_int .
Это уважает СИС В AMD64 ABI поэтому код эффективно реализует функцию C

IΩ D31º#╬D0[>?D-+∞;,

с 32-битными целыми числами.

Инструкция while is described by Intel

1 returns random numbers that are supplied by a cryptographically secure, deterministic random bit generator DRBG. The DRBG is designed to meet the НИСТ СП 800-90А стандарт.

При работе с CSRNG подразумевается, что распределение в любом случае является равномерным, цитируя NIST SP 800-90A:

Случайное число — это экземпляр несмещенной случайной величины, то есть продукция, произведенная


равномерно
распределенный случайный процесс.

Процедура генерирует случайное число и, если оно не строго больше входного, оно возвращается. 1while [...]; is 32-bit, ->n{1while n<q=rand(2**30);q} В противном случае процесс повторяется.32С возвращает число от 0 до 2 -1, поэтому для каждого32н32в [0, 2 -1] количество ожидаемых итераций равно 2 /(n+1) который определен для всех30).

н

в [0, 2

 

Lucyerv80


Рег
24 Feb, 2011

Тем
56

Постов
203

Баллов
503
  • 26, Oct 2024
  • #3
INPUT N@L R=RND(1<<30)ON N<=R GOTO@L?R

Желе

, 7 6 байт (16!)! Спасибо @JonathanAllan за игру в гольф на 1 байт! Невозможно запустить на TIO, потому что это

огромный

using System; class RandomNumber { static void Main() { Func<int, int> f = n=>{int x=n+1;while(x>n)x=new Random().Next();return x;}; // example Console.WriteLine(f(100000)); } } ||answer||

число.

Как это работает Математика, 29 байт.

n=>{int x=n+1;while(x>n)x=new Random().Next();return x;};

На основе 2^30 is a pretty big number...

Ответ Денниса Джелли

Я бы не рекомендовал запускать это на самом деле.

Оказывается, проще всего сгенерировать огромное число, которое делится на все возможные входные данные, и сопоставить результат с требуемым диапазоном с помощью простого модуля.

n

Выборка отклонения, 34 байта 13! Мой старый подход, который привел к несколько более интересному коду: 230Базовая выборка отклонения. Мы инициализируем вывод в 0 (что больше, чем максимальный ввод 13! ), а затем несколько раз замените его случайным целым числом между

и

до тех пор, пока значение больше входного.

 

Meespatireads


Рег
22 Oct, 2014

Тем
83

Постов
208

Баллов
633
  • 26, Oct 2024
  • #4
0

Брахилог

, 9 байт n+1 like in Martin Ender's answer ( n Попробуйте онлайн! which.min(sample(2^30)[0:scan()+1])-1 ).

n is implemented using L=range(2**31) # Create a list from 0 to 2^31 exclusive. Call it <L>. import random # Import the module <random>. random.shuffle(L) # Use 'shuffle' function from <random> module, # to shuffle the list <L>. n=input() # Take the input -> <n>. print filter( # Create a new sequence, lambda x:x<=n # where each element is less than or equal to <n>. ,L) # from the list <L>. [0] # Take the first element. Это использует l=range(2**31) import random random.shuffle(l) n=input() print filter(lambda x:x<=n,l)[0] на один байт меньше, чем [ # start loop žIÝ # push the inclusive range [0 ... 2^31] .R # pick a random integer (pythons random.chiose) D # duplicate ¹ # push input ›_# # break if random number is not greater than input # implicitly output top of stack (the random number) , который при раскапывании своего источника использует

который связан с

[žIÝ.RD¹›_# ||answer||

который использует алгоритм Mersenne Twister, единый для наших целей.Объяснение

1.000.000

Пролог (SWI)

, 38 байт 0 Работает путем отбраковки выборки. 2^31-1 = 2147483647 Генерировать случайное число между

и

пока не будет найдено значение, меньшее или равное входному.

Я чувствую, что могу использовать сокращение вместо другого, но не понимаю, как это сделать.

 

Oberst


Рег
30 Oct, 2005

Тем
79

Постов
212

Баллов
637
  • 26, Oct 2024
  • #5
[0 ... 2147483648]

Лабиринт

, 63 байта

žIÝ # push the inclusive range [0 ... 2^31] .r # get a random permutation (pythons random.shuffle) D # duplicate this list I # push input ›_Ï # keep only elements from the list not greater than input ¤ # take the last one

(Спасибо @MartinEnder за помощь в тяжелой игре в гольф.) žIÝ.rDI›_Ϥ and moving downwards. It next lands on the {first 0..$_,^2**30 .roll(*)} Labyrinth — это 2D-язык, и его единственный источник случайности находится в следующей ситуации:

hash(input())

Предположим, что указатель инструкции находится на hash() moving downwards. At a junction, Labyrinth turns based on the top of stack - negative is turn left, positive is turn right and zero is move forward. If the top of stack is still zero at this point, we can't move forward or backward since there's no path, so Labyrinth will randomise between turning left or turning right with equal probability.

, который, если вершина стека равна 0 (что всегда имеет место в реальной программе выше), сдвигает текущую строку влево на 1: hash() here) and continue looping until it generates a number set() .

Указатель инструкций теперь находится на print(list(...)[0]) instead for 10-bit numbers, with the {0, 1, 2, 3, 4, ... n} По сути, приведенная выше программа использует функцию случайности для генерации 100-битных чисел (100 указано Для тестирования, вероятно, поможет использование

это путь без операций.

set(range(...)) ||answer||

Попробуйте онлайн!

1

Грубое объяснение:

Питон, 61 байтРедактировать:

Обновлено, чтобы избежать запрещенной формы.

Редактировать2: int(input())+1 , saving 2 bytes

Сэкономлено 2 байта, спасибо @ДжонатанАллан

Редактировать3:Заплатил 2 байта за полнофункциональное решение - еще раз спасибо @JonathanAllan

Редактировать4:

Удаленный

Редактировать5:

Сэкономлено еще 1 байт благодаря @

ДжонатанАлланРедактировать6:

print(list(set(map(str,range(int(input())+1))))[0])

Сэкономлено еще 2 байта благодаря @ 0 ДжонатанАллан К этому моменту вина мерзавца будет указывать на меня за плохие поступки, а на Джонатана Аллана за то, что помогает. Редактировать7: Когда идет дождь, то льет — еще 2 байта Редактировать8: 0 И еще 2 байта 231 - 2

 

Njtraredt


Рег
29 Apr, 2014

Тем
60

Постов
198

Баллов
518
  • 26, Oct 2024
  • #6
Питон 2.

, 61 байт

Псевдослучайно выбирает целые числа между

407594936

n->{ // Method with integer parameter and integer return-type int r; // Result-integer for(;(r=(int)(Math.random()*(1<<30)))>n;); // Loop as long as the random integer is larger than the input // (the random integer is in the range of 0 - 1,073,741,824 (2^30)) return r; // Return the random integer that is within specified range } // End method only gives 15 bits of randomness, so I have to combine two random numbers. Loops until the random value lies within the desired range, so slow for low (int)(Math.random()*(1<<30)) и

java.util.Random().nextInt(1<<30) ||answer||

кдля всех значений

к между и , затем принимает целое число, соответствующее к = п

n->{int r;for(;(r=(int)(Math.random()*(1<<30)))>n;);return r;}

 

Wiro


Рег
02 Apr, 2007

Тем
70

Постов
199

Баллов
559
  • 26, Oct 2024
  • #7
.

Пакетный, 64 байта ; 98 байт для более быстрой версии:МАТЛ n to n , 12 байт randrange(2**30) . This is guaranteed to terminate with probability from random import* n=input() while id>n:id=randrange(2**30) print id Благодаря id , and so it takes very long for echo rand(0,$argn); @AdmBorkBork N+1 .

N+1 ||answer||

и чтобы@Суевер

for(;++$i<$x=1+$argn;$n%=$x)$n+=rand();echo$n;

за то, что рассказали мне, как отключить кеш TIO.

Попробуйте онлайн! for(;++$i<$x=1+$argn;)$n+=rand()%$x;echo$n%$x; loop, setting the value of N Для этого используется N=15 integer between getrandmax() метод отклонения echo <N> | php -Rn '<code>' ( while($argn<$n=rand());echo$n; : сгенерировать случайное целое число из OptionalInt reater OptionalInt и повторяйте, пока оно не превысит входное значение ((IntFunction)(n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny())).apply(<n>) . Once the loop is complete, we just put n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny() , но среднее число итераций

значительно меньше, чем PowerShell , 35 байт

Попробуйте онлайн!

Еще один метод отбраковки. Это бесконечность

быть [0 ... 2и - 1]) и продолжает цикл до тех пор, пока это целое число равно Хан ввод на конвейере и вывод неявный. 2Примечание. Это займет некоторое время. длинный время, если входные данные представляют собой небольшое число.

 

Jksk


Рег
18 May, 2008

Тем
78

Постов
174

Баллов
584
  • 26, Oct 2024
  • #8
JavaScript (ES6), 55 54 байта.

Генерирует целые числа в диапазоне

к

  • , где ȷ are uniform over any interval [0 ... 2к-1] — наименьшее целое число такое, что к).

  • больше, чем ȷ... are still uniform over such intervals.

н

. Повторяется до тех пор, пока результат не упадет в

[0 ... н] [0 ... 2] Почему?

||answer||

Это основано на следующих предположениях:

Внутренне псевдослучайные целочисленные значения, генерируемые движком JS для подачи к

ȷ⁵

⁴!Ẋ’>Ðḟ⁸Ṫ - Main link: n ⁴ - 16 ! - factorial: 20922789888000 Ẋ - shuffle random: builds a list of the integers 1 through to 16! inclusive and - returns a random permutation via Python's random.shuffle (pretty resource hungry) ’ - decrement (vectorises - a whole pass of this huge list!) Ðḟ - filter out if: (yep, yet another pass of this huge list!) > - greater than ⁸ - left argument, n Ṫ - tail: return the rightmost remaining entry. , and filter them out with ⁴!Ẋ’>Ðḟ⁸Ṫ к < 32 -m will abort the pipe.

После умножения на точную степень 2 значения с плавающей запятой IEEE 754, возвращаемые

Если кто-то может подтвердить или опровергнуть эти гипотезы, дайте мне знать, пожалуйста, в комментариях.

m

Демо Генерирует 1 миллион значений в поэтому все числа в интервале [0,2^30] должны иметь одинаковую вероятность (1/(2^30+1)), поэтому все числа в [0,n] имеют одинаковую вероятность.

Альтернативная версия:

m

Эта версия ужасна, но она сохраняет целый байт. abs uses an arbitrary range defined by the type to generate an infinite list of numbers. This may include negatives so we need to map it with abs чтобы заставить их быть положительными (или нулевыми). Это чрезвычайно медленно для любых значений n, которые не являются абсурдно большими. РЕДАКТИРОВАТЬ: Позже я понял, что эта версия не распределена равномерно, потому что вероятность получить 0 хуже, чем у других чисел, из-за использования randoms . To produce some number import System.Random g n=head.filter(<=n).map abs.randoms<$>getStdGen генератор может производить import System.Random g n=head.filter(<=n).randomRs(0,2^30)<$>getStdGen or sed q но в случае 0 сработает только сам 0, поэтому его вероятность равна половине остальных чисел.

 

Alextrener


Рег
21 Jun, 2008

Тем
72

Постов
196

Баллов
606
  • 26, Oct 2024
  • #9

Желе, 9 байты

awk

Попробуйте онлайн! - код выше не будет работать на TIO, поскольку размер диапазона составляет 16! должны быть сначала построены (не говоря уже о том, что их потом нужно перетасовать, а затем отфильтровать!), так что это то же самое в гораздо меньшем масштабе, повторяемое 30 раз для ввода 3 с границей 10.

Как?

/dev/urandom

Примечание: было бы в тысячу раз эффективнее при том же количестве байтов, если бы od -w4 -vtu4</d*/ur*|awk '($0=$2)<='$1|sed q would do what one would naively expect and return ten to the ten, but that is not the case since the f=(n,m=1)=>m>n?(x=Math.random()*m|0)>n?f(n):x:f(n,m*2) for(i = 0, stat = []; i < 1000000; i++) { r = f(2); stat[r] = (stat[r] || 0) + 1; } console.log(stat.join` `) не оценивается как буквальная цифра десять, которая будет использоваться в числовом литерале Math.random() but rather two separate literals are parsed, Math.random() с показателем по умолчанию, равным трем, что дает тысячу, и f=(n,m=1)=>m>n?(x=Math.random()*m|0)>n?f(n):x:f(n,m*2) yielding ten.

 

Regina Ibr


Рег
23 Oct, 2020

Тем
73

Постов
184

Баллов
589
  • 26, Oct 2024
  • #10

JDK 9 на jshell, 75 59 байт

$a

Использование

$args
  • -16 байт: Спасибо, Джейкоб!
  • Предполагается, что мы считаем jshell допустимой средой выполнения.
  • Сама jshell, как среда выполнения, не требует явного импорта основных библиотек и не требует использования точек с запятой.
  • Возвращает t . Rules don't specify that return type must be a primitive and I'm considering an -g быть действительным представлением результата.
 

Borabora2006


Рег
26 Nov, 2011

Тем
67

Постов
205

Баллов
550
  • 26, Oct 2024
  • #11

PHP, 30 байт

= 1073741824 = 2^30

Беги с 1gb .

выбирает случайное число от 0 до 0 (2**31-1 на моей 64-битной машине);
повторяется, пока это больше, чем входное значение.

Этот может потребуется некоторое время... моему AMD C-50 (1 ГГц) потребовалось от 0,3 до 130 секунд для Random .

Более быстрый способ для среднего $a (46 байт):

for

или

for(;($a=Random 1gb)-gt"$args"){}$a

берет ` % Do...while 30W % Push 2^30 Yr % Random integer from 1 to 2^30 q % Subtract 1 G> % Does it exceed the input? If so: next iteration. Else: exit } % Finally (execute right before exiting the loop) 2M % Push the last generated integer % End (implicit). Display (implicit) random integers, sums them up and takes the modulo with 2^30 .
Для C-50 требуется ок. 8 секунд на 1 миллион пробежек.

Неверное решение для 19 байт:

n ||answer||

Питон 2, 72 69 байт

-3 байта благодаря xnor (переопределить 2^30/n built-in as a variable)

1

Попробуйте онлайн!

n produces a pseudo-uniformly distributed number (Mersenne Twister 219937-1) из диапазона [0,230). С 2^30-1 is guaranteed to be below 230 это можно просто вызывать несколько раз, пока оно не станет больше входного значения. Ожидается, что это займет много времени для очень низких значений 0 , but usually works within the a minute even for inputs as low as 50.

 

Satler


Рег
04 Sep, 2007

Тем
82

Постов
167

Баллов
587
  • 26, Oct 2024
  • #12

Java 8, 84 83 80 71 62 байта

`30WYrqG>}2M

-1 байт благодаря @ОливерГрегойр.
-3 байта благодаря @Джейкоб.
-9 байт конвертируют Java 7 в Java 8.
-9 байт путем изменения @set/a"n=%1+1,m=~(3<<30)/n*n,r=%random%*32768+%random% @if %r% geq %m% %0 %1 @cmd/cset/a%r%%%%n% to n .

Объяснение:

Попробуйте здесь.

%random%

ПРИМЕЧАНИЕ. Очевидно, что для небольших входных данных может потребоваться очень много времени.

Пример вывода:

@set/ar=%random%*32768+%random% @if %r% gtr %1 %0 %1 @echo %r% ||answer||

Питон 3, 51 байт

Вот решение Python с неортодоксальным случайным источником.

from random import* lambda n:map(randrange,range(1,2**31))[n]

Попробуйте онлайн!

Итак, чтобы сломать это.

f=

Получает входной номер и добавляет from random import* lambda n,x=2.**30:int(randrange(x)*-~n/x) to it.

? <--- ? is input and starting point #0"}__""*_ <--- * here: first run is *0, after that is *2 to double ; #" _ {-{= } "><) <--- Randomness section, +0 or +1 depending on path. !{ : ;"({ + After <, the >s reset the row for the next inner loop. @ }}: >`# ^ ^ | | | The " junction in this column checks whether the | 100-bit number has been generated, and if not then | continue by turning right into }. | Minus sign junction here checks whether the generated number <= n. If so, head into the output area (! is output as num, @ is terminate). Otherwise, head up and do the outer loop all over again.

Создает набор " for all possible results.

#0"

Берет набор, преобразует его в список и извлекает первый элемент.

Это работает, потому что в Python 3 порядок <= n is established by ПИТОНХАШСИД (не может быть получен но устанавливается при выполнении скрипта).

Признаюсь, я предполагаю, что это равномерное распределение, поскольку #00 value is randomly assigned and I am looking at randomly picking the value with a specific < , а не просто возвращать " "<) " " " " itself.

Если кто-нибудь знает, является ли это равномерным распределением или как я могу это проверить, прокомментируйте.

 

Den_6064


Рег
09 Nov, 2019

Тем
69

Постов
203

Баллов
578
  • 26, Oct 2024
  • #13

Qahramon0786


Рег
03 Nov, 2010

Тем
68

Постов
195

Баллов
565
  • 26, Oct 2024
  • #14

05AB1E, 11 байт

x

Попробуйте онлайн!

Объяснение

x "<) " " " "

Как список ? #00}__""*_ ; #" _ {-{= } "><) !{ : ;"({ + @ }}: >`# is too large for TIO, the link uses X*Y:-Z is 2^31,random(0,Z,Y),Y=<X;X*Y. вместо.

Альтернативное (в среднем) гораздо более быстрое 11-байтовое решение

≥. Input ≥ Output ∧ And 13ḟṙ Output = rand(0, 13!) | Else ↰ Call recursively with the same input

Попробуйте онлайн

Объяснение

random/1 ||answer||

Питон 2, 89 байт

random_float/0

Объяснение

random_between/3

Это очень неэффективно, так как создает 2^31 целые числа, перемешивает и фильтрует их.

Я не вижу смысла делиться ссылкой на TIO, где создаются такие большие списки, поэтому вот ссылка на TIO для = 100.

Попробуйте онлайн!

 

Concepte


Рег
08 Dec, 2020

Тем
94

Постов
200

Баллов
690
  • 26, Oct 2024
  • #15

Р, 37 байт

2^₃₀

Берет 13ḟ from stdin. First it generates a random sample of all the integers in the range, then selects the first 13! значений, находит индекс минимума, а затем вычитает единицу, чтобы сгенерировать число между ≥.∧13ḟṙ|↰ and 13!//.x_/;x>#:>RandomInteger[13!]& , включительно. Он не будет работать на TIO, потому что не может выделить массив размера 2e9! to sample from.

Я вполне уверен, что это равномерно случайно.

Попробуйте онлайн!

 

Speedy Gonzales


Рег
31 Jan, 2016

Тем
67

Постов
205

Баллов
550
  • 26, Oct 2024
  • #16

С#, 57 байт

RandomInteger[2*^9!-1]~Mod~#&

Анонимная функция, возвращающая целое число от 0 до n включительно.

Чем меньше входное число, тем дольше время возврата случайного значения.

Полная программа:

⁴!!X%‘ Main link. Argument: n ⁴ Set the return value to 16. !! Compute (16!)!. X Pseudo-randomly choose an integer between 1 and (16!)!. Since (16!)! is evenly divisible by any k ≤ 2**30, it is evenly divisible by n+1. %‘ Take the result modulo n+1. ||answer||

SmileBASIC, 38 байт

⁴!!X%‘

Генерирует случайные числа, пока не получит число, меньшее входных.

 

Alien303


Рег
10 Jun, 2007

Тем
81

Постов
178

Баллов
603
  • 26, Oct 2024
  • #17

Рубин, 23 15 23 32 29 байт

rdrand

Как это работает:

  • eax executes the statement at least once: RDRAND до rdrand acts as a nop
  • Получите случайное число в диапазоне 0..2^30-1 (ниже 2^30как указано)
  • Повторите, если число больше входного параметра (может занять некоторое время, если n мало).
 

11111unx


Рег
15 Aug, 2006

Тем
80

Постов
182

Баллов
612
  • 26, Oct 2024
  • #19

Голанг, 84 78 71 байт

BITS 64 _try_again: rdrand eax jnc _try_again cmp eax, edi ja _try_again ret

Простая выборка отклонения.

Примечание: поскольку начальное число math/rand имеет константу 1, вызывающая сторона должна использовать начальное значение, если не требуется постоянный результат.

Тест: https://play.golang.org/p/FBB4LKXo1r Практически больше не подлежит тестированию в 64-битной системе, поскольку она возвращает 64-битную случайность и использует тестирование отклонения.

rdrand
 

FineC0de


Рег
02 Aug, 2014

Тем
69

Постов
198

Баллов
573