1 / N de probabilidad

29

Porque no hay suficientes desafíos simples de :

Cree un programa o función opcionalmente sin nombre que, dado (por cualquier medio) un número entero 1 ≤ N ≤ 10000, genera el valor Verdadero de su idioma con una probabilidad pseudoaleatoria de 1 / N, Falso de lo contrario.

Tenga en cuenta que se ha eliminado el requisito de denominación. Siéntase libre de editar las respuestas y las puntuaciones en consecuencia.

Algunos idiomas usan 1 (o -1) y 0 para Verdadero y Falso, eso también está bien.

Ejemplo:

Ejemplo de pruebas de entrada:

4 -> True
4 -> False
4 -> False
4 -> False
4 -> False
4 -> True
4 -> False
4 -> False

Es decir, 4; devuelve True con una probabilidad del 25% y False con una probabilidad del 75%.

Adán
fuente
2
Meta publicación relevante
FryAmTheEggman
1
También meta post relevante .
AdmBorkBork
Como no todos los idiomas han construido en "pseudoaleatoriedad", ¿es posible obtener una semilla como segundo argumento? (Por ejemplo, Brainfuck)
falla
@flawr usa milisegundos actuales ...
Adám
1
¿Qué es lo más grande Nque tenemos que aceptar?
Toby Speight

Respuestas:

27

Plantillas MediaWiki con ParserFunctions , 48 bytes

{{#ifexpr:1>{{#time:U}} mod {{{n}}}|true|false}}
DuhHola
fuente
13
Interesante elección de idioma :-)
Adám
66
¿Quién diablos pensó que sería sensato agregar funciones no deterministas a las plantillas de MediaWiki?
user253751
44
@immibis: bueno, el no determinismo ocurre #time, probablemente para actualizar la edad de las personas vivas, etc.
Willem Van Onsem
15

Pyth, 3 bytes

!OQ

Pruébalo en línea

Inversión simple de elección aleatoria de 0 a entrada

Divertidamente en Pyth no es posible hacer una función que lo haga sin esto $porque las funciones de Pyth se memorizan automáticamente.

FryAmTheEggman
fuente
1
Es posible.
Leaky Nun
@LeakyNun Ah, claro, me había olvidado de usar el tiempo para una función aleatoria, eso es bastante inteligente.
FryAmTheEggman
No, solo utilicé el tiempo para eliminar la memoria.
Leaky Nun
1
Soy consciente, supongo que simplemente no lo dije bien: P Dicho esto, no creo que realmente funcione como una solución para la mayoría de las presentaciones, si alguna vez fuera mejor que un programa completo por alguna razón. Tomar el tiempo como argumento probablemente no solo esté permitido por defecto.
FryAmTheEggman
1
@LeakyNun Creo que esta pregunta es anterior al Qrelleno al final, de lo contrario habría respondido !O;)
FryAmTheEggman
12

CJam, 5 bytes

Tengo que ser rápido con estos ...

rimr!

Pruébalo aquí.

Explicación

ri e# Read input and convert to integer N.
mr e# Get a uniformly random value in [0 1 ... N-1].
!  e# Logical NOT, turns 0 into 1 and everything else into 0.
Martin Ender
fuente
11
" Tengo que ser rápido con estos ... ", que es una razón para estar en desacuerdo con OP de que " no hay suficientes desafíos simples de código de golf ". Si FGITW es un problema, IMO es demasiado simple.
Peter Taylor
12

TI-BASIC, 4 bytes usando tokens de un byte

not(int(Ansrand

Determina si la parte entera de la entrada multiplicada por un número aleatorio en [0,1) es cero. Ansrand<1También funciona.

lirtosiast
fuente
¿Cómo ... son cuatro bytes?
John Dvorak
3
@JanDvorak Los primeros bytes no son (, el siguiente es int (, el siguiente es Ans, el siguiente es rand. En general, las calculadoras gráficas no usan ASCII como su representación interna para programas.
user253751
@immibis En general, las computadoras tampoco usan ASCII. Esto podría ser cuestionable, ¿hay una meta discusión sobre eso?
Kroltan
77
@Kroltan Sí; Esta es la meta discusión, y esta es la lista de tokens que son un byte, que incluye los cuatro que utilicé.
lirtosiast
@ThomasKwa gracias!
Kroltan
11

MATL, 5 bytes

Tres versiones diferentes de este, todas de longitud 5.

iYr1=

que toma una entrada ( i), genera un número entero aleatorio entre 1 y ese número ( Yr), y ve si es igual a 1 ( 1=). Alternativamente,

li/r>

hacer un 1 ( l, una solución alternativa porque hay un error al hacer 1ien este momento), tomar una entrada ( i), dividir para obtener 1 / N ( /), hacer un número aleatorio entre 0 y 1 ( r), y ver si el azar El número es menor que 1 / N. O,

ir*1<

take e input ( i), y multiplique por un número aleatorio entre 0 y 1 ( r*), y vea si el resultado es menor que 1 ( 1<).

En Matlab, no en MATL, puedes hacer esta función anónima

@(n)n*rand<1

para 12 bytes, que se usa haciendo ans(5), por ejemplo.

David
fuente
10

JavaScript ES6, 15 bytes

-5 bytes gracias a Downgoat.

x=>1>new Date%x

Basado en (usos) de la técnica de esta respuesta.

Conor O'Brien
fuente
1
new Datetambién puede funcionar y puede ahorrar algunos bytes
Downgoat
@Downgoat Ah, cierto, fecha de aleatoriedad!
Conor O'Brien
10

Julia, 17 16 15 bytes

n->2>rand(1:n)

Esta es una función que genera un número entero aleatorio entre 1 y nprueba si es menor que 2. Habrá una probabilidad de 1 / n de que esto suceda y, por lo tanto, una probabilidad de 1 / n de regresar true.

¡Salvado 1 byte gracias a Thomas Kwa!

Alex A.
fuente
9

Microscript II , 3 bytes

NR!

Lee un entero n, genera un entero aleatorio entre 0y n-1(inclusive), luego aplica una negación booleana a ese valor.

SuperJedi224
fuente
8

Candy , 2 bytes

Hn

H significa Heisen-double

n significa no

La 'n' se pasa con la bandera -i como entrada numérica. Los valores que quedan en la pila se imprimen al salir.

"Forma larga:

rand   # number between 0 and pop()
not    # cast to int, invert non-zero to zero, and zero to one
Dale Johnson
fuente
Creo que deberías contar -icomo un byte.
lirtosiast
1
Básicamente, la única forma de pasar la entrada numérica es con el indicador -i. ¿Supongo que solo los idiomas que leen stdin no sufren penalización por especificación de entrada?
Dale Johnson
Bueno, si hubiera un indicador de entrada genérico, o si solo usó CLA regulares para pasar argumentos, definitivamente estaría bien. Sin embargo, parece injusto que el tipo de datos se especifique de forma gratuita.
lirtosiast
2
@ThomasKwa ¿Debería una función escrita en un lenguaje dinámico contar los bytes para especificar que el argumento es un entero en la documentación? En lambda x: random.random()<1/x(sin golf) también se "especifica de forma gratuita" que el argumento es un número.
user253751
@immibis Hmm, ese es un buen punto. Supongo que tratar de mantener las reglas para programas y funciones iguales debería permitir esto, entonces. Haré una publicación en meta.
lirtosiast
7

En serio, 3 bytes

,JY

0es falsey y 1es sincero. Pruébalo en línea

Explicación:

,JY
,    get input
 J   push a random integer in range(0, input) ([0, ..., input-1])
  Y  logical not: push 0 if truthy else 1  
Mego
fuente
7

R, 30 22 bytes

código

cat(runif(1)<1/scan())          #new
f=function(N)cat(runif(1)<1/N)  #old

Genera un número a partir de una distribución uniforme (0 a 1) y debe evaluar a verdadero 1 / n de las veces.

Mutador
fuente
6

Japt, 6 bytes

1>U*Mr

Pruébalo en línea!

Mres equivalente a JS's Math.random. El resto es bastante obvio. Probablemente podría agregar una función numérica que genere un flotante aleatorio entre 0 y el número. Cuando esto sucede, se guardarán dos bytes:

1>Ur    // Doesn't currently work

Versión alternativa:

1>Ð %U

Ðes equivalente a new Date(, y el objeto Fecha, cuando se le pide que convierta a un número, se convierte en la marca de tiempo actual en milisegundos. Por lo tanto, esto es completamente aleatorio, a menos que se ejecute varias veces por ms.

ETHproducciones
fuente
6

Maravilloso , 21 bytes

}0    # takes one input n
--    # decrements n
??    # random value from range 0..n (inclusive)
=0?0  # push right if not equal to 0, fall through otherwise | convert to zero
++    # increment | no-op
{0//  # output | push left

He considerado 0ser falso y 1sincero, aunque no hay una razón real para eso, ya que Marbelous realmente no tiene un if. Más Marbelousy se generaría como {0verdadero y {>falso. Esto se vería así:

}0
--
??
=0{>
{0

Pero no estoy seguro de que sea válido.

overactor
fuente
Estaría listo para una meta discusión sobre esto. Versión corta de mi punto de vista: la salida de un valor a una salida diferente es equivalente a tener diferentes tuplas de salida en otro idioma. Si (nil, 1) y (1, nil) pueden ser sus valores verdaderos y falsos en otro idioma, entonces {0 vs {> debería permitirse en Marbelous. PD: tu {> versión no se cerrará porque nunca llenas la otra salida.
Sparr
@Sparr saldrá por inactividad, ¿no?
overactor
Tienes razón. Me siento tonto.
Sparr
6

APL, 6 3 bytes

+=?

Este es un tren de funciones que toma un número entero y devuelve 1 o 0 (APL verdadero / falso). Generamos un entero aleatorio de 1 a la entrada usando ?, luego verificamos si la entrada es igual a ese entero. Eso da como resultado una probabilidad de 1 / entrada de verdadero.

¡Guardado 3 bytes gracias a Thomas Kwa!

Alex A.
fuente
@ThomasKwa Pensé en algún tipo de tren, pero ¿eso realmente cuenta como una "función con nombre" si se le asigna? Supongo que la parte "nombrada" me está arrojando aquí ya que es atípica.
Alex A.
@ThomasKwa La asignación de trenes (y funciones derivadas) es completamente paralela a todas las demás asignaciones.
Adám
@NBZ, ¿qué quieres decir con paralelo?
lirtosiast
@ThomasKwa Equivalente; comportarse como cualquier otra asignación de función.
Adám
Usaría en lugar de '+' porque +significa Conjugar para números complejos. Por supuesto, no importa aquí, y +es la función de identidad tradicional (no-op), pero ahora tenemos (lo mismo). Otros no-ops para escalares son: (materialize), (pick), (adjuntar), (split), (mix), (unique), (allist), ,(ravel), (table), (reverse), (reverse primero) y (transponer). Algunos cambian el escalar en un vector o matriz.
Adám
6

PlatyPar , 3 bytes

#?!

#?obtiene un número aleatorio [0,n)donde nse ingresa. !devuelve truesi el número anterior es 0, de lo contrario, regresa false.

Utilizando funciones más recientes que fueron implementadas (pero desafortunadamente para mí no comprometidas) antes de que se hiciera esta pregunta, puedo bajarla a 2 con ¡ ~! Pruébelo en línea !

Cyoce
fuente
5

Java, 43 bytes

boolean b(int a){return a*Math.random()<1;}
SuperJedi224
fuente
1
a->a*Math.random()<1Es más corto.
TheNumberOne
Debe especificar "Java 7 o anterior".
corsiKa
@corsiKlauseHoHoHo Esto también funciona en Java 8
SuperJedi224
1
Por supuesto que sí, pero no está diseñado para Java 8, que usaría lambdas para ahorrar espacio. Según esa lógica, todas las respuestas de Java también son respuestas de Groovy, pero Groovy siempre es igual o más pequeño porque tiene accesos directos que Java no tiene.
corsiKa
5

C, 24 bytes

f(n){return!(rand()%n);}
Level River St
fuente
Revertí la edición de OP eliminando los primeros 4 caracteres. Es bueno tener bytes reducidos, pero para mí, tener el returnsin el f(n)no tiene ningún sentido sintáctico.
Level River St
1
@insertusernamehere rand()%nes una forma estándar de obtener un número aleatorio en el rango 0..n-1. Tiene razón, se basa en nser mucho más pequeño que, RAND_MAXpero no hay un límite superior para nmencionar en la pregunta. Un enfoque alternativo sería rechazar y volver a tirar todos los números desde nRAND_MAX, pero sería ineficaz en absoluto n.
Level River St
5

> <>, 27 + 3 para -v = 30 bytes

Aquí hay una solución no uniforme en absoluto donde modifico N la suma de 15876 selecciones aleatorias de 0 o 1:

0"~":*>:?vr%0=n;
1-$1+$^-1x

N debe ingresarse en la pila con el indicador -v, la salida es 0 para falsey y 1 para verdadero.

Una solución mucho más inteligente y uniforme que funciona para 1/2 ^ N en su lugar:

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n;
1n;>
 

Para una entrada 3 tienes 1/8 de posibilidades de obtener 1 y 7/8 de obtener 0.

Explicacion:

Agrego todo lo xque sea necesario en la cuarta línea y los rodeo con instrucciones, por lo que solo hay dos formas de salir x: la salida falsey o la siguiente x. Si todos xvan en la dirección correcta, el último se dirigirá a la salida verdadera.

Por ejemplo, para N = 5, el espacio de código final es el siguiente:

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n; > > > > >
1n;>x>x>x>x>x>
    ^ ^ ^ ^ ^
Aaron
fuente
Si bien es cierto que no se puede obtener una distribución perfecta para N arbitrario, tampoco nadie más puede usar un PRNG. Puede recorrer un xa varias veces para obtener un montón de bits aleatorios, ensamblarlos en un int I, luego usar I% N como su valor aleatorio.
Sparr
@Sparr editó mi respuesta, pero siento que usar una gran cantidad de iteraciones 'promediará' el entero resultante, haciendo que la salida tenga una gran tendencia hacia (iterNum/2)%N. No creo que usar un número más bajo sea una solución tampoco. ¿Acaso no te entendí bien, o tendrías alguna idea adicional para mejorar la solución?
Aaron
en lugar de sumar 15000 bits, produzca solo 32 bits y concatenelos, proporcionándole un entero aleatorio de 32 bits distribuido uniformemente. mod eso.
Sparr
@Sparr eso parece mejor, incluso si no tengo idea de por qué;) Eso costará mucho más bytes (> <> apesta para operaciones de bytes y conversión de base) pero cambiaré mi respuesta esta noche (CEST).
Aaron
puede concatenar bits multiplicando por dos y agregando: r = 0; para (0..32) r = r * 2 + randbit;
Sparr
4

Mathematica, 18 16 bytes

#RandomReal[]<1&

Solución básica El anónimo Functioncrea un número aleatorio en [0, 1), lo multiplica por su argumento y comprueba si aún es menor que 1.

LegionMammal978
fuente
4

Python, 42 bytes

import random
lambda n:1>random.random()*n

Editar : se eliminó la time.time()respuesta debido a la distribución.

DuhHola
fuente
2
Para random, vale la pena hacer from random import*para ahorrar random.. timeAunque no por eso .
xnor
1
Los números aleatorios generados por la división del módulo no están distribuidos uniformemente .
Trang Oul
@TrangOul Ese es un buen punto; para mayor nel efecto podría ser notable. Creo que 1>time.time()%1*npodría funcionar
lirtosiast
@TrangOul Supongo que conoce la diferencia entre randC y time.timePython ... Una característica obvia de este último es que devuelve el tiempo actual , que no tiene límites, por lo que time.time()%ntiene una distribución uniforme (durante períodos de tiempo lo suficientemente largos) para cualquier n.
user253751
4

TeaScript , 3 bytes

!N×

Pruébalo aquí.

Explicación

 N  maps to Math.rand which is a utility function that returns an integer
    between `arg1` and `arg2` or `0` and `arg1` if only one argument is
    provided.
  × is expanded to `(x)`, where `x` is initialised with the value provided
    in the input boxes; × represents byte '\xd7'
!   negate the result, 0 results in true, anything else false
Dom Hastings
fuente
1
¿Cómo suman siete caracteres hasta 6 bytes? ¿Y es el (R) un carácter (ANSI) de ANSI?
Adám
@NBZ, jaja! Creo que mentí ... culpo a la resaca ... ¡Me actualizaré ahora, ya que voy a cambiar el mecanismo a uno más sencillo que acabo de notar! En esta versión actual, ®representa el carácter, '\xae'por lo que es solo un byte. :)
Dom Hastings
4

Fuzzy Octo Guacamole, 10 bytes

^-!_[0]1.|

Explicación:

^-!_[0]1.|

^          # Get input.
 -         # Decrement, so we can append <ToS> zeros and a 1 to the stack.
  !        # Set loop counter.
   _       # Pop, since we are done with the input.
    [      # Start loop
     0     # Push 0
      ]    # End for loop. We have pushed input-1 0s to the stack.
       1   # Push a single 1 to the stack.
        .  # Switch stacks
         | # Pick a random item from the inactive stack, which has n-1 falsy items and 1 truthy item, so the truthy probability is 1/n.
           # (implicit output)
Rɪᴋᴇʀ
fuente
3

Perl 6 ,  10   8 bytes

!(^*).pick
#  ^- The * is the argument

Este código crea un rango desde 0 hasta, pero excluye la entrada *. Luego pickes uno al azar y !devuelve True cuando recibe a 0.

1>*.rand
# ^- The * is the argument

Esto toma la entrada *y la multiplica por un Num aleatorio y 0..^1luego devuelve True si era menor que 1.

# store it in a lexical code variable for ease of use
my &code = 1>*.rand;

die "never dies here" unless code 1;

for ^8 { say code 4 }
False
True
False
False
False
True
False
False
Brad Gilbert b2gills
fuente
3

Prólogo (SWI), 24 bytes

Código:

p(N):-X is 1/N,maybe(X).

quizás (+ P) es una función que tiene éxito con probabilidad P y falla con probabilidad 1-P

Ejemplo:

p(4).
false

p(4).
false

p(4).
true
Emigna
fuente
3

PowerShell, 25 bytes

!(Random -ma($args[0]--))

La Get-Randomfunción cuando se le da un -Maparámetro ximum ndevuelve un valor del rango [0,n). Aprovechamos eso restando 1 de nuestra entrada $args[0], por lo que estamos indexados adecuadamente a cero y obtenemos un valor aleatorio. Precisamente 1/nla mayor parte del tiempo, este valor será 0, así que cuando lo booleanos, no con !él, devolveráTrue . Los otros tiempos volverán False.

AdmBorkBork
fuente
3

J, 3 bytes

0=?

Esta es una bifurcación monádica que lleva un argumento a la derecha. De manera similar a APL,? genera un entero aleatorio; sin embargo, las matrices J están basadas en cero. Entonces comparamos a 0 en lugar de a la entrada.

lirtosiast
fuente
3

Minkolang 0.14 , 7 bytes

1nH1=N.

Pruébalo aquí.

Explicación

1          Pushes 1
 n         Takes number from input
  H        Pops b,a and pushes a random integer between a and b, inclusive
   1=      1 if equal to 1, 0 otherwise
     N.    Output as number and stop.
El'endia Starman
fuente
3

PHP, 22 bytes

<?=2>rand(1,$argv[1]);

Lee ndesde la línea de comandos, como:

$ php probability.php 4

Salidas ( falsese convierte en una cadena vacía en PHP) o 1(en caso de true).

insertusernamehere
fuente
3

C #, 56 45 bytes

Gracias a, pinkfloydx33 es 45 ahora.

bool b(int n){return new Random().Next(n)<1;}

56 bytes antiguos

Genera un entero positivo aleatorio mayor o igual a 0 y menor que ny comprueba si es menor 1y devuelve el resultado de la comparación.

bool a(int n){Random r=new Random();return r.Next(n)<1;}
ivaan
fuente
1
Bienvenido a PPCG! Desafortunadamente, este envío no funciona, porque Random.Next(k)devuelve un número entero ktal que 0 <= k < n. Al cambiar la condición a <1, será correcta. Además, el uso de una expresión lambda puede acortar su código.
Mego
@Mego Claro, gracias por tu comentario. Lo hice 0 < k <= ny debería ser como dijiste. Lo corregiré de inmediato.
ivaan
2
El uso var rahorra tres. O si es c # 6, bool a(int n) => new Random().Next(n)<1;para 41. ¿Aunque no está seguro si inicializar una nueva Randomllamada por método funcionará correctamente en cuanto a distribución?
pinkfloydx33