1 / N probabilità


29

Perché non ci sono abbastanza semplici sfide di :

Crea un programma o una funzione opzionalmente senza nome che, dato (in qualsiasi modo) un numero intero 1 ≤ N ≤ 10000, genera il valore Vero della tua lingua con una probabilità pseudo-casuale di 1 / N, Falso altrimenti.

Si noti che il requisito per la denominazione è stato rimosso. Sentiti libero di modificare le risposte e i punteggi di conseguenza.

Alcune lingue usano 1 (o -1) e 0 per Vero e Falso, anche questo va bene.

Esempio:

Esempi di test di input:

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

Vale a dire 4; restituisce True con una probabilità del 25% e False con una probabilità del 75%.




Dato che non tutte le lingue hanno incorporato la "pseudorandomness", è possibile ottenere un seme come secondo argomento? (Ad esempio Brainfuck)
flawr

@flawr usa il millisecondo corrente ...
Adám

1
Qual è il più grande Nche dobbiamo accettare?
Toby Speight,

Risposte:


27

Modelli MediaWiki con ParserFunctions , 48 byte

{{#ifexpr:1>{{#time:U}} mod {{{n}}}|true|false}}

13
Interessante scelta della lingua :-)
Adám

6
Chi diavolo ha pensato che sarebbe sensato aggiungere funzioni non deterministiche ai modelli MediaWiki !?
user253751

4
@immibis: beh, il non determinismo si verifica #time, probabilmente per aggiornare l'età delle persone viventi, ecc.
Willem Van Onsem,

15

Pyth, 3 byte

!OQ

Provalo online

Semplice inversione di scelta casuale da 0 a input

In modo divertente in Pyth non è possibile creare una funzione che lo faccia senza $perché le funzioni Pyth vengono automaticamente memorizzate.



@LeakyNun Ah giusto, mi ero dimenticato di usare il tempo per una funzione casuale, è piuttosto intelligente.
FryAmTheEggman,

No, ho appena usato il tempo per cancellarlo.
Leaky Nun,

1
Sono consapevole, immagino di non averlo detto bene: P Detto questo, non penso che funzionerebbe davvero come soluzione alternativa per la maggior parte degli invii, se fosse mai meglio di un programma completo per qualche motivo. Prendersi il tempo come argomento probabilmente non è consentito solo per impostazione predefinita.
FryAmTheEggman,

1
@LeakyNun Credo che questa domanda preceda la Qcompilazione alla fine, come altrimenti avrei risposto !O;)
FryAmTheEggman,

12

CJam, 5 byte

Devo essere veloce con questi ...

rimr!

Provalo qui.

Spiegazione

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.

11
" Devo essere veloce con questi ... " che è una ragione per non essere d'accordo con OP che " non ci sono abbastanza semplici sfide di code-golf ". Se FGITW è un problema, IMO è troppo semplice.
Peter Taylor,

12

TI-BASIC, 4 byte usando token a un byte

not(int(Ansrand

Determina se la parte intera dell'input moltiplica un numero casuale in [0,1) è zero. Ansrand<1funziona anche.


Come ... Sono quattro byte?
John Dvorak,

3
@JanDvorak I primi byte non sono (, il prossimo è int (, il prossimo è Ans, il successivo è rand. In generale, i calcolatori grafici non usano ASCII come rappresentazione interna per i programmi.
user253751

@immibis In generale, neanche i computer usano ASCII. Questo potrebbe essere discutibile, c'è una meta discussione a riguardo?
Kroltan,

7
@Kroltan Sì; questa è la meta discussione e questa è la lista dei token che sono un byte, che include tutti e quattro quelli che ho usato.
lirtosiast,

@ThomasKwa grazie!
Kroltan,

11

MATL, 5 byte

Tre diverse versioni di questa, tutta la lunghezza 5.

iYr1=

che accetta un input ( i), genera un numero intero casuale compreso tra 1 e quel numero ( Yr) e vede se è uguale a 1 ( 1=). In alternativa,

li/r>

crea un 1 ( l, una soluzione alternativa perché al momento c'è un bug nel fare 1i), prendi un input ( i), dividi per ottenere 1 / N ( /), crea un numero casuale tra 0 e 1 ( r) e vedi se il casuale il numero è inferiore a 1 / N. O,

ir*1<

prendere e inserire ( i) e moltiplicare per un numero casuale compreso tra 0 e 1 ( r*) e vedere se il risultato è inferiore a 1 ( 1<).

In Matlab, non MATL, puoi svolgere questa funzione anonima

@(n)n*rand<1

per 12 byte, che viene utilizzato facendo ans(5), ad esempio.


10

JavaScript ES6, 15 byte

-5 byte grazie a Downgoat.

x=>1>new Date%x

Basato su (usi) della tecnica di questa risposta.


1
new Datepuò anche funzionare e potrebbe salvare qualche byte
Downgoat

@Downgoat Ah, giusto, data casualità!
Conor O'Brien,

10

Julia, 17 16 15 byte

n->2>rand(1:n)

Questa è una funzione che genera un numero intero casuale compreso tra 1 e nverifica se è inferiore a 2. Ci sarà una possibilità 1 / n che ciò accada, e quindi una possibilità 1 / n di tornare true.

Salvato 1 byte grazie a Thomas Kwa!


9

Microscript II , 3 byte

NR!

Legge un numero intero n, genera un numero intero casuale compreso tra 0e n-1(inclusi), quindi applica una negazione booleana a tale valore.


8

Caramella , 2 byte

Hn

H sta per Heisen-double

n sta per no

La 'n' viene passata con il flag -i come input numerico. I valori lasciati nella pila vengono stampati all'uscita.

"Forma lunga:

rand   # number between 0 and pop()
not    # cast to int, invert non-zero to zero, and zero to one

Penso che dovresti contare -icome un byte.
lirtosiast,

1
fondamentalmente l'unico modo per passare l'input numerico è con il flag -i. Immagino che solo le lingue che leggono da stdin non subiscano penalità per le specifiche di input?
Dale Johnson,

Bene, se ci fosse un flag di input generico, o se avessi semplicemente usato i normali CLA per passare degli argomenti, ciò andrebbe sicuramente bene. Tuttavia, sembra ingiusto che il tipo di dati sia stato specificato gratuitamente.
lirtosiast,

2
@ThomasKwa Una funzione scritta in un linguaggio dinamico deve contare i byte per specificare che l'argomento è un numero intero nella documentazione? In lambda x: random.random()<1/x(ungolfed) è anche "specificato gratuitamente" che l'argomento è un numero.
user253751

@immibis Hmm, questo è un buon punto. Immagino che provare a mantenere le regole per i programmi e le funzioni uguali dovrebbe consentire questo, quindi. Farò un post su meta.
lirtosiast,

7

Scherzi a parte, 3 byte

,JY

0è falsità ed 1è verità. Provalo online

Spiegazione:

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

7

R, 30 22 byte

codice

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

Genera un numero da una distribuzione uniforme (da 0 a 1) e dovrebbe essere valutato al vero 1 / n dei tempi.


6

Japt, 6 byte

1>U*Mr

Provalo online!

Mrè equivalente a JS Math.random. Il resto è abbastanza ovvio. Probabilmente potrei aggiungere una funzione numerica che genera un float casuale tra 0 e il numero. Quando ciò accade, verranno salvati due byte:

1>Ur    // Doesn't currently work

Versione alternativa:

1>Ð %U

Ðè equivalente a new Date(e l'oggetto Date, quando viene chiesto di convertirlo in un numero, diventa il timestamp corrente in millisecondi. Pertanto, questo è del tutto casuale, a meno che non venga eseguito più volte per ms.


6

Marbelous , 21 byte

}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

Ho preso 0per essere falso ed 1essere sincero, anche se non vi è alcuna ragione reale per questo visto che Marbelous non ha davvero un se. Più Marbelousy verrebbe emesso {0per vero e {>falso. Questo sarebbe simile a questo:

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

Ma non sono sicuro che sia valido.


Sarei pronto per una meta discussione su questo. Breve versione del mio punto di vista: fornire un valore a un output diverso equivale ad avere tuple di output diverse in un'altra lingua. Se (zero, 1) e (1, zero) possono essere i tuoi valori di verità e falsità in un'altra lingua, allora {0 vs {> dovrebbe essere consentito in Marbelous. PS: la tua versione {> non verrà chiusa perché non riempi mai l'altro output.
Sparr,

@Sparr uscirà a causa di inattività, no?
overactor

Hai ragione. Mi sento stupido.
Sparr,

6

APL, 6 3 byte

+=?

Questo è un treno di funzioni che accetta un numero intero e restituisce 1 o 0 (vero / falso di APL). Generiamo un numero intero casuale da 1 all'input usando ?, quindi controlliamo se l'input è uguale a quell'intero. Ciò si traduce in una possibilità 1 / input di true.

Salvato 3 byte grazie a Thomas Kwa!


@ThomasKwa Ho pensato a un qualche tipo di treno, ma conta davvero come una "funzione denominata" se assegnato? Immagino che la parte "nominata" mi stia gettando qui poiché è atipica.
Alex A.

@ThomasKwa L'assegnazione dei treni (e le funzioni derivate) è completamente parallela a tutte le altre assegnazioni.
Adám,

@NBZ cosa intendi per parallelo?
lirtosiast,

@ThomasKwa Equivalent; comportarsi come qualsiasi altra assegnazione di funzioni.
Adám,

Vorrei usare invece di '+' perché +significa Coniugato per numeri complessi. Naturalmente qui non importa, ed +è la tradizionale funzione di identità (no-op), ma ora abbiamo (lo stesso). Altre no-op per gli scalari sono: (materializza), (seleziona), (racchiudi), (diviso), (mescola), (unico), (arruolato), ,(ravel), (tabella), (retro), (retro prima) e (trasporre). Alcuni cambiano lo scalare in un vettore o una matrice.
Adám,

6

PlatyPar , 3 byte

#?!

#?ottiene un numero casuale [0,n)dove nviene inserito. !ritorna truese il numero prima è 0, altrimenti ritornafalse .

Utilizzando le funzionalità più recenti che sono state implementate (ma purtroppo per me non impegnate) prima che mi facesse questa domanda, posso ridurlo a 2 con ~! Provalo online !


5

Java, 43 byte

boolean b(int a){return a*Math.random()<1;}

1
a->a*Math.random()<1è più corto.
TheNumberOne,

Dovrebbe specificare "Java 7 o precedenti".
corsiKa

@corsiKlauseHoHoHo Funziona anche in Java 8
SuperJedi224

1
Certo che lo fa - ma non è golfato per Java 8, che userebbe lambdas per risparmiare spazio. Secondo quella logica, tutte le risposte Java sono anche risposte Groovy, ma Groovy è sempre uguale o più piccolo perché ha scorciatoie che Java non ha.
corsiKa

5

C, 24 byte

f(n){return!(rand()%n);}

Ho ripristinato la modifica di OP rimuovendo i primi 4 caratteri. È bello avere byte ridotti, ma per me avere il returnsenza il f(n)non ha alcun senso sintattico.
Level River St,

1
@inserire username rand()%nè un modo standard per ottenere un numero casuale nell'intervallo 0..n-1. Hai ragione, si basa nsull'essere molto più piccolo di RAND_MAXma non c'è limite superiore per nmenzionato nella domanda. Un approccio alternativo sarebbe quello di rifiutare e ripetere il roll- nover su tutti i numeri da a RAND_MAX, ma sarebbe irrimediabilmente inefficiente in generale n.
Level River St,

5

> <>, 27 + 3 per -v = 30 byte

Ecco una soluzione per nulla uniforme in cui mod N la somma di 15876 scelte casuali di 0 o 1:

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

N deve essere inserito nello stack con -v flag, l'output è 0 per falsey e 1 per verità.

Una soluzione molto più intelligente e uniforme che funziona invece per 1/2 ^ N:

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

Per un input 3 hai 1/8 possibilità di ottenere 1 e 7/8 di ottenere 0.

Spiegazione :

Aggiungo quanto basta xsulla quarta riga e li xcircondo di direzioni in modo che ci siano solo due vie di uscita : la falsa uscita o la successiva x. Se tutti xvanno nella giusta direzione, l'ultimo verrà indirizzato all'output vero.

Ad esempio per N = 5, lo spazio dei codici finale è il seguente:

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

Sebbene sia vero non è possibile ottenere una distribuzione perfetta per N arbitraria, né chiunque altro può utilizzare un PRNG. È possibile eseguire un ciclo attraverso un xa alcune volte per ottenere un gruppo di bit casuali, assemblarli in un int I, quindi utilizzare I% N come valore casuale.
Sparr,

@Sparr ha modificato la mia risposta, ma ho la sensazione che l'uso di un gran numero di iterazioni "farà la media" dell'intero risultante, facendo sì che l'output tenda fortemente verso (iterNum/2)%N. Non penso che usare un numero inferiore sia una soluzione. Forse non ti ho capito bene o avresti qualche idea in più per migliorare la soluzione?
Aaron,

invece di aggiungere 15000 bit insieme, produrre solo 32 bit e concatenarli, ottenendo un intero casuale a 32 bit distribuito uniformemente. mod che.
Sparr il

@Sparr sembra davvero migliore, anche se non ho idea del perché;) Costerà molto più byte (> <> fa schifo per operazioni su byte e conversione di base) ma cambierò la mia risposta questa sera (CEST).
Aaron,

puoi concatenare i bit moltiplicando per due e aggiungendo: r = 0; per (0..32) r = r * 2 + randbit;
Sparr,

4

Mathematica, 18 16 byte

#RandomReal[]<1&

Soluzione di base. Il senza nome Functioncrea un numero casuale in [0, 1), lo moltiplica per il suo argomento e verifica se è ancora inferiore a 1.


4

Python, 42 byte

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

Modifica : rimossa la time.time()risposta a causa della distribuzione.


2
Per random, vale la pena fare from random import*per risparmiare random.. Non per timeperò.
xnor

1
I numeri casuali generati dalla divisione modulo non sono distribuiti uniformemente .
Trang Oul,

@TrangOul Questo è un buon punto; per maggiore nl'effetto potrebbe essere evidente. Penso che 1>time.time()%1*npotrebbe funzionare.
lirtosiast,

@TrangOul Presumo che tu sappia la differenza tra randin C e time.timein Python ... Una caratteristica ovvia di quest'ultima è che restituisce l'ora corrente , che è illimitata, quindi time.time()%nha una distribuzione uniforme (per periodi abbastanza lunghi) per qualsiasi n.
user253751

4

TeaScript , 3 byte

!N×

Provalo qui.

Spiegazione

 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

1
In che modo sette caratteri aggiungono fino a 6 byte? Ed è (R) un carattere (singolo byte) ANSI?
Adám,

@NBZ, haha! Penso di aver mentito ... Dò la colpa ai postumi di una sbornia ... Ora aggiornerò mentre cambierò il meccanismo in uno più semplice che ho appena notato! In questa versione corrente ®rappresenta il carattere, '\xae'quindi è solo un byte. :)
Dom Hastings,

4

Fuzzy Octo Guacamole, 10 byte

^-!_[0]1.|

Spiegazione:

^-!_[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)

3

Perl 6 ,  10   8 byte

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

Questo codice crea un intervallo compreso tra 0 e escluso l'input *. Quindi pickè uno a caso e !restituisce True quando riceve un 0.

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

Questo prende l'input *e lo moltiplica per un numero casuale da 0..^1quindi restituisce True se era inferiore a 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

3

Prolog (SWI), 24 byte

Codice:

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

forse (+ P) è una funzione che ha successo con la probabilità P e fallisce con la probabilità 1-P

Esempio:

p(4).
false

p(4).
false

p(4).
true

3

PowerShell, 25 byte

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

La Get-Randomfunzione quando viene assegnato un -Maparametro ximum nrestituisce un valore dall'intervallo [0,n). Lo sfruttiamo sottraendo 1 dal nostro input $args[0], quindi siamo correttamente indicizzati a zero e otteniamo un valore casuale. Proprio 1/nnel tempo, questo valore lo sarà 0, quindi quando booleano non lo !restituirà True. Le altre volte torneranno False.


3

J, 3 byte

0=?

Questa è una forcella monadica che prende una discussione a destra. Analogamente a APL,? genera un numero intero casuale; tuttavia, le matrici J sono a base zero. Quindi confrontiamo con 0 anziché con l'input.


3

Minkolang 0,14 , 7 byte

1nH1=N.

Provalo qui.

Spiegazione

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.

3

PHP, 22 byte

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

Legge ndalla riga di comando, come:

$ php probability.php 4

Output ( falseviene castato su una stringa vuota in PHP) o 1(in caso di true).


3

C #, 56 45 byte

Grazie a pinkfloydx33 sono 45 adesso.

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

Vecchi 56 byte

Genera intero positivo casuale maggiore o uguale a 0 e minore di ne verifica se è minore di 1e restituisce il risultato del confronto.

bool a(int n){Random r=new Random();return r.Next(n)<1;}

1
Benvenuti in PPCG! Sfortunatamente, questo invio non funziona, perché Random.Next(k)restituisce un numero intero ktale 0 <= k < n. Modificando la condizione in <1, sarà corretta. Inoltre, l'uso di un'espressione lambda può ridurre il codice.
Mego

@Mego Certo, grazie per il commento. L'ho fatto 0 < k <= ne dovrebbe essere come hai detto tu. Lo correggerò immediatamente.
ivaan,

2
Usa var rsalva tre. O se c # 6, bool a(int n) => new Random().Next(n)<1;per 41. Non sei sicuro che l'inizializzazione di una nuova Randomchiamata per metodo funzionerà correttamente per quanto riguarda la distribuzione?
pinkfloydx33,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.