使用恒定的随机源选择一个介于0和n之间的随机数


26

任务

给定的正整数n小于2^30您选择以任何方式指定的输入,您的代码应输出介于0和之间的随机整数n,包括。您生成的数字应该随机选择。也就是说,从0到的每个值都n必须以相等的概率出现(请参阅规则和警告)。

规则和警告

您的代码可以假定您的语言或标准库中内置的任何声称统一随机的随机数生成器实际上都是统一的。那就是您不必担心所使用的随机源的质量。然而,

  • 您必须确定,如果您使用的随机源是统一的,则您的代码正确地输出了从0到的统一随机整数n
  • 调用内置或库随机函数时,任何参数都必须是常量。也就是说,它们必须完全独立于输入值。
  • 您的代码可能以1的概率终止而不是保证终止。

笔记

  • randInt(0,n) 是无效的,因为它将输入作为内置函数或库函数的参数。
  • rand()%n通常不会给出统一的随机数。作为betseg提供的示例,如果intmax == 15n = 10,那么您获得的可能性0-5将比更高6-10
  • floor(randomfloat()*(n+1)) 由于0到1之间的可能浮点值的数量有限,因此通常也不会给出统一的随机数。

您将如何确认输出是一致随机的?给定的语言/库可能会输出统一的随机数,但是操纵可能会导致输出不一致。(例如,rng()提供0- 100,如果n = 75和函数为rng()%75,则0-25会更常见...)
Baldrickk

1
@Baldrickk通过人群的智慧:)我们只能阅读代码并仔细考虑。

提出最简单的可能的概率理论问题的可悲结论是:对随机性和概率的了解很少。:((显然,阅读规则很难。)
Martin Ender

这想到了:随机数
BgrWorker

三个较短的答案为什么会接受x86答案?
丹尼斯

Answers:


25

rdrand指令的x86机器,10字节

BITS 64

_try_again:

 rdrand eax
jnc _try_again

 cmp eax, edi
ja _try_again

 ret

机器码

0FC7F0 73FB 39F8 77F7 C3

输入在寄存器中rdi,输出在中rax
这尊重SYS V AMD64 ABI,因此代码有效地实现了C函数

unsigned int foo(unsigned int max); 

具有32位整数。

该说明rdrand由英特尔描述

RDRAND返回由加密安全的确定性随机位生成器DRBG提供的随机数。DRBG旨在满足NIST SP 800-90A标准。

在处理CSRNG时,无论如何,引用NIST SP 800-90A暗含了分布是均匀的:

随机数是无偏随机变量的实例,即由均匀分布的随机过程产生的输出。


该过程生成一个随机数,如果非严格大于输入,则将其返回。
否则,将重复该过程。

因为eax是32位,所以rdrand返回0到2 32 -1 之间的数字,因此对于[0,2 32 -1]中的每n ,期望的迭代次数是2 32 /(n + 1),为所有n个定义在[0,2 30)中。


极低的水平。谢谢。

有什么jnc
l4m2

@ l4m2 rdrand设置CF返回的数据是否有效。数据可能无效,因为太多的请求耗尽了熵池。有关rdrandthis的信息,请参见手册。
玛格丽特·布鲁姆

20

果冻7 6字节

⁴!!X%‘

感谢@JonathanAllan打高尔夫球1个字节!

无法在TIO上运行,因为(16!)!是一个巨大的数字。

怎么运行的

⁴!!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.

这是我删除的答案的固定版本,相同的想法。虽然我确实有不必要的取幂。
orlp

抱歉,发布之前我没有看过。
丹尼斯,

哦,没关系,我也不打算修复它。我对Jelly感到不舒服,无法真正使用它。
orlp

1
“先生,我不知道你为什么生气。算法是固定时间的。这是一件好事,对吗?为什么安全和人力资源不在门外?”
corsiKa'3

1
同意 8位数字和417亿位数数字之间的差值位数:p
Jonathan Allan

11

Mathematica,29个字节

基于丹尼斯的果冻答案

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

我不建议实际运行它。2e9!是一个很大的数字...

事实证明,生成一个可以被所有可能的输入整除的巨大数字并将其结果映射到所需范围的最简单方法是最短的。

拒绝采样,34个字节

我的旧方法导致了一些更有趣的代码:

13!//.x_/;x>#:>RandomInteger[13!]&

基本剔除采样。我们将输出初始化为13!(大于最大输入2 30),然后用013之间的随机整数重复替换它只要该值大于输入。


1
您的意思是“小于或等于输入”吗?

1
@Lembik否。只要值不落在所需范围内,我们就希望重新生成该值。
Martin Ender

哦,我懂了。由于某种原因,我认为我们是在所需范围内反复采样。谢谢。

1
提醒我下次添加时间限制:)

9

Brachylog,9个字节

≥.∧13ḟṙ|↰

在线尝试!

这将使用13!在马丁安德的答案一样(13ḟ一个字节小于2^₃₀)。

是使用来实现的random_between/3,在挖掘其来源时,使用random_float/0链接到random/1,并使用针对我们的目的统一的Mersenne Twister算法。

说明

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

7

Prolog(SWI),38字节

X*Y:-Z is 2^31,random(0,Z,Y),Y=<X;X*Y.

通过剔除采样工作。

生成一个介于02 ^ 31-1 = 2147483647之间的随机数,直到找到小于或等于输入的1。

我觉得我应该可以使用剪切代替其他剪切,但是我看不到如何。


1
您可以避免使用else repeat,但是最终会长3个字节…我不确定是否有比重复重复点更短的无限选择点方式。
Fatalize

@Fatalize:是的,我也尝试过重复。我曾经使用过,!.强制回溯的方式,但是我记错了或者它不适用于此解决方案。
Emigna

7

迷宫,63字节

 ?
 #00}__""*_
 ;    #"  _
{-{=  } "><)
!{ : ;"({ +
@  }}:  >`#

(感谢@MartinEnder在这里提供一些打高尔夫球的帮助。)

迷宫是一种2D语言,其唯一的随机性来源是在如下情况下:

   x
  "<)
 " "
 " "

假设指令指针在上x并向下移动。接下来将<其放在上,如果栈顶为0(在上面的实际程序中总是如此),则将当前行向左移动1:

   "
 "<)
 " "
 " "

指令指针现在在<向下移动。在一个交界处,迷宫根据栈顶旋转-负号向左转,正号向右转,零号向前移动。如果此时栈顶仍为零,则由于没有路径,我们将无法前进或后退,因此迷宫将以相等的概率在左转或右转之间随机化。

本质上,上面的程序所做的是使用随机性功能生成100位数字(#00此处指定为100 )并继续循环直到生成数字<= n

对于测试,将其用作无操作路径可能会有助于#0"代替使用10位数字"在线尝试!

粗略解释:

 ?            <--- ? 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.

7

Python,61个字节

from random import*
lambda n,x=2.**30:int(randrange(x)*-~n/x)

编辑:已更新,以避免出现禁止使用的表格

Edit2:保存了2个字节,谢谢@ JonathanAllan

Edit3:支付2个字节以获取功能齐全的解决方案-再次感谢@JonathanAllan

Edit4:删除f=,节省2个字节

Edit5:多亏了@ JonathanAllan,节省了1个字节

Edit6:由于@ JonathanAllan,又节省了2个字节

到现在为止,git怪会因为坏事而指责我,而JonathanAllan会帮我指责。

Edit7:下雨时,倒水-另外2个字节

Edit8:另外2个字节


1
这将永远不会输出n,但是当通过使用from random import*和删除r.
乔纳森·艾伦,

1
是的,您可以使用“ ta运算符”来避免否则必须的括号,...*(-~n*1.0/2**30))而不是...*((n+1)*1.0/2**30))
Jonathan Allan

1
真?甜!您对70号有长期的仇恨吗?非常感谢您的帮助
iwaseatenbyagrue

1
实际上randrange似乎接受浮点数,因此lambda n,x=2.**30:int(randrange(x)*-~n/x)可以节省另外两个[编辑...]四个!
乔纳森·艾伦,

1
^还有两个用括号删除的符号。只是显示您的乘法才是可行的方法!
乔纳森·艾伦

6

Python 2,61个字节

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

伪随机地选择的整数0ķ对的所有值ķ之间02 31 - 2,然后发生在对应于整数K = N


5

批处理,64字节

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

%random%仅给出15位随机性,因此我必须将两个随机数组合在一起。循环直到随机值在期望的范围内,所以慢到低n;98字节的更快版本:

@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%

代码可能很慢,但是您的回答很快!

3
@Lembik我已经准备好回答您删除的问题了……
Neil

这不是首先回显所需的数字,然后回显所有其他大于n
暴民埃里克(Erik the Outgolfer)'17

@EriktheOutgolfer号;除非您使用call,否则调用批处理脚本将终止当前脚本。
Neil

5

MATL,12字节

感谢@AdmBorkBork@Suever告诉我如何禁用TIO缓存。

`30WYrqG>}2M

在线尝试!

这使用拒绝方法:从0to 生成一个随机整数2^30-1,并在超出输入范围时重复n。这样可以保证终止的可能性1,但是平均的迭代次数是2^30/n,因此要花很长的时间才能n显着小于2^30

`         % 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)

4

JavaScript(ES6),55 54字节

f=(n,m=1)=>m>n?(x=Math.random()*m|0)>n?f(n):x:f(n,m*2)

生成范围为[0 ... 2 k -1]的整数,其中k是最小的整数,使得2 k大于n。重复直到结果落入[0 ... n]为止。

为什么?

这是基于以下假设:

  • 在内部,由JS引擎生成的用于馈送的伪随机整数值Math.random()在任何间隔[0 ... 2 k -1]k <32)上都是一致的。

  • 一旦乘以2的精确乘方,返回的IEEE 754浮点值Math.random()在这样的时间间隔内仍然是一致的。

如果有人可以确认或驳斥这些假设,请在评论中让我知道。

演示版

[0 ... 2]中生成一百万个值,并显示结果统计信息。


Math.floor(Math.random()*(n + 1))为我产生同样均匀的分布结果,因此很高兴看看是否存在任何现实的N <2 ^ 30,这将产生任何分布异常完全没有
齐柏林飞艇

1
@zeppelin您将需要进行太多次尝试才能查明任何异常,因为该范围内的随机浮动将具有2 ^ 53值之一,该值将尽可能均匀地分布在2 ^ 30的结果中。因此,即使对于该范围内的大量数字,误差也将类似于2 ^ 23中的1,这意味着您需要大量的尝试。您可能想要的数量级要比初始样本数量(2 ^ 53)多几个数量级。但是,如果乘数没有均匀地除以样本数,就不可能是完全均匀的,这就是Arnauld使用2的幂的原因。
Martin Ender

4

Bash(+ coreutils),44个字节

基于/ dev / urandom的解决方案

od -w4 -vtu4</d*/ur*|awk '($0=$2)<='$1|sed q

将从中读取无符号的32位整数/dev/urandom,并将其过滤掉,awk直到找到给定范围内的整数,然后sed q中止管道。


bash的万岁:)

4

Haskell,70个字节

import System.Random
g n=head.filter(<=n).randomRs(0,2^30)<$>getStdGen

这不是一个非常有效的算法,但它可以工作。它会生成一个以[0,2 ^ 30]为边界的无限整数列表(如果需要,则是浮点数,因为有Haskell的类型系统),并且取第一个小于或等于n的整数。对于小n,这可能需要很长时间。随机数应该按照文档中对randomR的规定进行均匀分布,因此区间[0,2 ^ 30]中的所有数字都应具有相同的概率(1 /(2 ^ 30 + 1)),因此[ [0,n]具有相同的概率。

备用版本:

import System.Random
g n=head.filter(<=n).map abs.randoms<$>getStdGen

这个版本很糟糕,但是却保存了整个字节。randoms使用由类型定义的任意范围来生成数字的无限列表。这可能包括负数,因此我们需要将其映射abs为强制它们为正数(或零)。对于任何不大的n值,这都非常慢。编辑:后来我意识到这个版本不是均匀分布的,因为由于使用了导致获得0的可能性比其他数字差abs。要生成某个数字m,生成器可能会生成,m或者-m在生成0的情况下,只有0本身会起作用,因此它的概率是其他数字的一半。


Haskell的万岁!

4

果冻,9 个字节

⁴!Ẋ’>Ðḟ⁸Ṫ

在线尝试!-上面的代码不会在TIO上运行,因为范围为16!必须首先构建(更不用说它们需要重新组合然后过滤!),因此这是相同的事情,但是规模要小得多,对于3的输入(边界为10)重复30次。

怎么样?

⁴!Ẋ’>Ðḟ⁸Ṫ - 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.

注:这将是一千多时间多为相同的字节数有效的,如果ȷ⁵会做什么人会天真地期望和返回十到十,但这并不是因为案件中使用未评估为字面10按数字字面量ȷ...,而是解析两个单独的字面量,ȷ其默认指数3产生一千,产生十。


呵呵,多数民众赞成在9个字符,但22个字节
Kristoffer Sall-Storgaard

@ KristofferSall-Storgaard每个字符都是Jelly代码页中 256个字节中的一个,我忘了像平常一样将字节一词设置为链接。
乔纳森·艾伦

1
一年,我查了一下,发现了一样的东西
Kristoffer Sall-Storgaard

4

JDK 9上jshell,75 59个字节

n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny()

用法

((IntFunction)(n->(new Random()).ints(0,1<<30).dropWhile(x->x>n).findAny())).apply(<n>)
  • -16个字节:谢谢雅各布!
  • 假设我们认为jshell是有效的运行时环境。
  • jshell本身作为运行时环境不需要核心库的显式导入,也不需要分号。
  • 返回OptionalInt。规则未指定返回类型必须为原始类型,而我正在考虑将an OptionalInt作为结果的有效表示形式。

1
感谢@ kevin-cruijssen的启发。我的第一个代码高尔夫!
皮特·特里普

是否接受盒装输出与是否接受盒装输出不同Optional。我会和海报确认我是否是你。同样,无需计算整个任务;仅lambda表达式就足够了。
雅各布

1
您可以通过删除lambda参数n和周围的括号来节省4个字节new Random()
雅各布

3

PHP,30个字节

    while($argn<$n=rand());echo$n;

用运行echo <N> | php -Rn '<code>'

从0到getrandmax()(64位机器上的2 ** 31-1)之间选择一个随机数;
大于输入时重复。

可能需要一段时间...我的AMD C-50(1 GHz)需要0.3至130秒N=15

平均的更快方法N46字节):

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

要么

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

接受N+1随机整数,将它们求和,并使用取模N+1
C-50大约需要 8秒钟,运行一百万次。

19个字节的无效解决方案:

echo rand(0,$argn);

3

PowerShell,35个字节

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

在线尝试!

另一种拒绝采样方法。这是一个无限for循环,将的值设置为和()之间$aRandom整数,并保持循环,直到该整数大于输入。循环完成后,我们只需放置在管道上即可,输出是隐式的。01gb= 1073741824 = 2^30-gt$args$a

注意:如果输入的数字很小,这将花费很长时间


3

Python 2中72 69个字节

-3字节归功于xnor(将id内置变量重写为变量)

from random import*
n=input()
while id>n:id=randrange(2**30)
print id

在线尝试!

randrange(2**30)产生[0,2 30 ]范围内的伪均匀分布数(Mersenne Twister 2 19937-1。由于保证低于2 30,因此可以简单地反复调用它,直到不大于输入值为止。的极低值会花费较长的预期时间,但即使输入低至50,也通常会在一分钟内起作用。nn


2
您可以初始化r=''为“无穷大”。或者,更好的是,不要初始化r,而是id在各处使用r
xnor


2

05AB1E,11个字节

žIÝ.rDI›_Ϥ

在线尝试!

说明

ž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

由于该列表[0 ... 2147483648]对于TIO太大,因此使用链接1.000.000

备用(平均)更快的11字节解决方案

[žIÝ.RD¹›_#

在线尝试

说明

[             # 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)

žJL.R%除非我错过了巨大的东西,否则为6。按2 ^ 32,从0到2 ^ 32列出,随机选择。模输入。绝对会提高您的效率。
Magic Octopus Urn'Mar

@carusocomputing。您需要I在其中放置7个字节,以正确的顺序(或Ý代替L)获取模数的参数,但是肯定是一个较短的解决方案。我看到丹尼斯(Jenly)在Jelly的回答中这样做了,但是由于这是我的第一个想法,所以我坚持了这一点。由于该方法与此不同,您可以将其作为单独的答案发布。
Emigna

DI‹Ï将避免循环。
Magic Octopus Urn'Mar

同样,不能保证终止。如果我没记错的话,输入0几乎总是会导致无限循环,从而难以终止。尽管该解决方案确实允许在所有情况下终止,但由于随机性,不能保证。
Magic Octopus Urn'Mar

@carusocomputing:对于非常小的输入,第二个版本平均需要很长时间才能完成,但是给定足够的时间。
Emigna

2

Python 2,89个字节

l=range(2**31)
import random
random.shuffle(l)
n=input()
print filter(lambda x:x<=n,l)[0]

说明

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.

这是非常低效的,因为它会创建2 ^ 31个整数,对它们进行混洗和过滤。

我看不到共享一个创建如此大的列表的TIO链接的意义,所以这里是一个n= 100 的TIO链接。

在线尝试!


2

Java 8,84 83 80 71 62字节

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

-1个字节感谢@OliverGrégoire
-3个字节,感谢@Jakob
-9字节将Java 7转换为Java8。
通过更改java.util.Random().nextInt(1<<30)为-9字节(int)(Math.random()*(1<<30))

说明:

在这里尝试。

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

注意:对于小输入,可能显然会花费很长时间。

输出示例:

407594936

2
@Aaron我也对此提出了疑问,但看到了第二个要点:“调用内置或库随机函数时,任何参数都必须是常量。也就是说,它们必须完全独立于输入值。” 这就是使用max int的原因。

1
2^30= 1073741824。您更喜欢使用-1>>>1(= 2147483647)。但这存在:1<<30完全等于2^30; 并且短1个字节。
OlivierGrégoire'17

1
怎么int c(int n){int r;for(;(r=new java.util.Random().nextInt(1<<30))>n;);return r;}
雅各布

@Jakob谢谢。我什至使用Java 8而不是7并使用Math.random()代替来将其缩短了18个字节java.util.Random().nextInt
凯文·克鲁伊森

2

Python 3,51个字节

这是带有非正统随机源的python解决方案。

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

在线尝试!

因此,将其分解。

int(input())+1

获取输入数字,并将其添加1

set(range(...))

{0, 1, 2, 3, 4, ... n}为所有可能的结果创建集合。

print(list(...)[0])

取得集合,将其转换为列表,并获取第一项。

之所以可行set()是因为在Python 3中,PYTHONHASHSEED建立了的顺序无法获得,但在脚本执行时建立)。

诚然,我猜测这是一个均匀分布,因为该hash()值是随机分配的,并且我正在考虑使用特定的随机选择值hash(),而不是仅仅返回hash(input())自身。

如果有人知道这是统一分布还是我可以对其进行测试,请发表评论。


1

C#,57个字节

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

匿名函数,返回介于0和n之间(含0和n)的整数。

输入数字越小,返回随机值的时间越长。

完整程序:

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));
    }
}

2
“调用内置或库随机函数时,任何参数都必须恒定。也就是说,它们必须完全独立于输入值。” 的参数Next不是静态的。
Yytsi'2

1

Bash + coreutils,20个字节

打高尔夫球

seq 0 $ 1 | shuf | sed 1q

shuf-生成随机排列

Shuf将使用以下代码:生成排列:

permutation = randperm_new (randint_source, head_lines, n_lines);

最终在 randint_genmax

/* Consume random data from *S to generate a random number in the range
0 .. GENMAX.  */

randint
randint_genmax (struct randint_source *s, randint genmax) 
{
      ...

      randread (source, buf, i);

      /* Increase RANDMAX by appending random bytes to RANDNUM and
         UCHAR_MAX to RANDMAX until RANDMAX is no less than
         GENMAX.  This may lose up to CHAR_BIT bits of information
         if shift_right (RANDINT_MAX) < GENMAX, but it is not
         worth the programming hassle of saving these bits since
         GENMAX is rarely that large in practice.  */
      ...
}

反过来,它将 从低级随机性源中读取一些字节的随机数据:

/* Consume random data from *S to generate a random buffer BUF of size
   SIZE.  */

void
randread (struct randread_source *s, void *buf, size_t size)
{
  if (s->source)
    readsource (s, buf, size);
  else
    readisaac (&s->buf.isaac, buf, size);
}

即在低级别,shuf输入值和从随机性源读取的数据之间不存在直接依赖关系(除了计算所需的字节缓冲区容量)。


6
这不是将输入作为自变量生成器的参数吗?
Martin Ender

即使这无效,也请提交另一个bash答案!

@MartinEnder很好,不是直接使用,它只是使用输入来定义生成的整数范围的上限和jot will arrange for all the values in the range to appear in the output with an equal probability(可能是边界线,但仍然)。
齐柏林飞艇

2
如果我深入研究任何随机数生成器,那么我肯定会找到不直接使用原始参数的较低级RNG的调用。挑战的关键是要从固定大小的分布中获得任意大小的均匀分布,而您仍然没有这样做。
Martin Ender

1

SmileBASIC,38个字节

INPUT N@L
R=RND(1<<30)ON N<=R GOTO@L?R

生成随机数,直到获得小于输入的数字为止。


1

Ruby,23 15 23 32 29个字节

->n{1while n<q=rand(2**30);q}

怎么运行的:

  • 1while [...];至少执行一次该语句:1while充当点之前
  • 获取0..2 ^ 30-1范围内的随机数(小于2 ^ 30,如指定)
  • 如果数字大于输入参数,则重复此操作(n较小时可能需要一些时间)

1

欧姆,26个字节

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

说明:

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

是否有该语言的口译员?那代码页呢?
ATaco

@ATaco:口译员,代码页:CP-437
Emigna


1

Golang,84 78 71字节

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

简单的拒绝采样。

注意:由于math / rand种子是常数1,因此除非需要恒定的结果,否则调用方必须播种。

测试:https : //play.golang.org/p/FBB4LKXo1r 不再可在64位系统上进行实际测试,因为它返回了64位随机性并使用了拒绝测试。

package main

import "fmt"
import "time"

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

func main() {
    Seed(time.Now().Unix())
    fmt.Println(R(1073741823))
}

1
如果使用import."math/rand"then,那么Int31它在全局名称空间中可用,并且可以保存4个字节,也int保证至少为32位,从而又为您节省了6个字节
Kristoffer Sall-Storgaard

使用:=另外3个字节的语法
Kristoffer Sall-Storgaard

使用int代替int32不会节省任何字节,因为我们需要转换Int31()的结果-3 * int +()= 11个字节,而2 * int32 = 10个字节。
Riking

1
无需强制转换,Int()rand包中还有一个功能,此外,您可以在之后删除空格import
Kristoffer Sall-Storgaard
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.