Genera qualsiasi numero intero casuale


17

Il tuo programma / funzione dovrebbe

  • output esattamente un intero
  • emette un numero intero con probabilità positiva
  • emette un numero intero maggiore di 1.000.000 o inferiore a -1.000.000 con almeno con una probabilità del 50%.

Esempi di output (tutto deve essere possibile):

59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001

chiarimenti:

  • È consentita un'interruzione di riga finale.
  • Gli zeri iniziali non sono ammessi.
  • -0 è permesso.

Il codice più corto vince.


2
@Optimizer perché stai assumendo una probabilità uniforme? La domanda non lo afferma. In effetti sembra chiaro da quel punto che la distribuzione non deve essere uniforme fintanto che almeno il 50% non rientra in [-1 milione, 1 milione].
Hobbs,

10
Una soluzione che produce una " distribuzione uniforme su tutti gli interi" è impossibile. Ci sono infiniti numeri interi, quindi ogni singolo numero intero appare con una probabilità di 0. (Oppure: Emettere un numero finito significherebbe che ne stai trascurando infiniti altri!) Qualsiasi soluzione dovrà sfavoreggiare valori più alti per raggiungere P (totale ) = 1.
joeytwiddle,

2
@Ypnypn La RAM del computer non è neanche un limite. Non è necessario archiviare l'output parziale da nessuna parte.
jimmy23013,

4
@GiantTree - way too long to fit in an integer- Questo è vero solo se si presume che integersignifichi il inttipo di dati su un arco a 32/64 bit, il che non è necessariamente un presupposto valido. "Numero intero" è iniziato come un termine matematico , che non ha vincoli di dimensione.
Nome falso

5
Chiunque utilizzi un generatore di numeri pseudo casuali per prendere le proprie decisioni sull'output escluderà quasi tutti i numeri interi e porrà un limite superiore alla dimensione degli interi che possono essere prodotti (supponendo che il PRNG abbia un periodo finito). Questo può essere ignorato nelle risposte o una risposta valida richiede un vero generatore di numeri casuali?
trichoplax,

Risposte:


12

CJam, 16 14 13 byte

0{Kmr(+esmr}g

Questo funzionerà per un tempo molto lungo, perché utilizza il timestamp corrente (nell'ordine di 10 12 ) per determinare se il ciclo deve terminare. Sto usando questo come invio, in quanto è il più breve, ma ci sono due alternative a 14 byte, che hanno i loro meriti:

0{esmr(+esmr}g

Questo non è limitato dal periodo del PRNG, poiché l'intervallo di tutti i numeri casuali dipende dal timestamp corrente. Pertanto, questo dovrebbe essere in grado di produrre qualsiasi numero, anche se la probabilità di numeri positivi negativi o anche piccoli positivi è sempre più piccola.

Di seguito è una versione equivalente che utilizza al 3e5posto del timestamp. E 20per il primo intervallo (come l'invio a 13 byte). È molto più veloce e rispetta anche tutte le regole. È una specie del caso limite ottenere la probabilità del 50% per numeri oltre 1.000.000 mantenendo un tempo di esecuzione ragionevole e dimensioni di codice ridotte. La spiegazione e la giustificazione matematica si riferiscono a questa versione:

0{Kmr(+3e5mr}g

Questo di solito richiede alcuni secondi per l'esecuzione. Puoi sostituirlo 5con a 2per farlo funzionare ancora più velocemente. Ma allora il requisito sulla probabilità del 50% sarà soddisfatto solo per 1.000 anziché per 1.000.000.

Sto iniziando da 0. Poi ho un ciclo, che interrompo con probabilità 1 / (3 * 10 5 ). All'interno di quel ciclo aggiungo un numero intero casuale compreso tra -1 e 18 (incluso) al mio totale parziale. C'è una probabilità finita (anche se piccola) che ogni numero intero verrà emesso, con numeri interi positivi molto più probabili di quelli negativi (non credo che ne vedrai uno negativo nella tua vita). Uscire con una probabilità così piccola e incrementare la maggior parte del tempo (e aggiungere molto più della sottrazione) assicura che di solito andremo oltre le 1.000.000.

0              "Push a 0.";
 {          }g "Do while...";
  Kmr          "Get a random integer in 0..19.";
     (         "Decrement to give -1..18.";
      +        "Add.";
       3e5mr   "Get a random integer in 0..299,999. Aborts if this is 0.";

Qualche giustificazione matematica:

  • In ogni passaggio aggiungiamo 8,5 in media.
  • Per arrivare a 1.000.000 abbiamo bisogno di 117.647 di questi passaggi.
  • La probabilità che faremo meno di questo numero di passaggi è

    sum(n=0..117,646) (299,999/300,000)^n * 1/300,000
    

    che valuta 0.324402. Quindi, in circa i due terzi dei casi, faremo più 117.647 passi e facilmente ogni 1.000.000.

  • (Si noti che questa non è la probabilità esatta, perché ci saranno alcune fluttuazioni su quelle in media 8,5, ma per arrivare al 50%, dobbiamo andare ben oltre 117.646 a circa 210.000 passi.)
  • In caso di dubbio, possiamo facilmente far saltare in aria il denominatore della probabilità di terminazione, 9e9senza aggiungere alcun byte (ma anni di runtime).

... o 11 byte?

Infine, esiste una versione da 11 byte, che non è limitata dal periodo del PRNG, ma che si esaurirà quasi ogni volta. Genera solo un numero casuale (basato sul timestamp) per ogni iterazione e lo utilizza sia per incrementare che per terminare. I risultati di ciascuna iterazione rimangono nello stack e vengono riassunti solo alla fine. Grazie a Dennis per questa idea:

{esmr(}h]:+

Ho aggiunto un commento alla domanda per vedere se le regole richiedono un vero generatore di numeri casuali, ma immagino che apprezzerai la pedanteria. La tua fonte casuale qui è pseudo casuale? Ciò limiterebbe la dimensione dell'insieme delle uscite possibili al massimo al periodo del tuo PRNG, giusto?
trichoplax,

(+1 indipendentemente dalla semplice eleganza)
trichoplax,

Sì, sto indovinando tutto finora. Sono curioso di vedere se qualcuno pubblica una risposta senza quel problema però ...
trichoplax,

Vedo che l'OP ha affermato che puoi presumere che il tuo generatore di numeri casuali sia un vero generatore di numeri casuali, che lo sia o no - quindi questo è ridondante ora ... :)
trichoplax,

La somma di Kmrin un periodo è ancora probabilmente sempre un grande numero positivo maggiore del periodo. E non può produrre ogni numero possibile in quel caso.
jimmy23013,

11

Java, 133 149

void f(){String s=x(2)<1?"-":"";for(s+=x(9)+1;x(50)>0;s+=x(10));System.out.print(x(9)<1?0:s);}int x(int i){return new java.util.Random().nextInt(i);}

Esempi di output

-8288612864831065123773
0
660850844164689214
-92190983694570102879284616600593698307556468079819964903404819
3264

Ungolfed

void f() {
    String s = x(2)<1 ? "-" : "";       // start with optional negative sign
    s+=x(9)+1;                          // add a random non-zero digit
    for(; x(50)>0; )                    // with a 98% probability...
        s+=x(10)                        // append a random digit
    System.out.print(x(9)<1 ? 0 : s);   // 10% chance of printing 0 instead
}

int x(int i) {
    return new java.util.Random().nextInt(i);
}

Vecchia risposta (prima del cambio di regola)

void f(){if(Math.random()<.5)System.out.print('-');do System.out.print(new java.util.Random().nextInt(10));while(Math.random()>.02);}

Entrambi avete ragione, ma la domanda afferma che la probabilità deve essere almeno del 50% non nell'intervallo di +/- 1.000.000
GiantTree

@Optimizer Redone.
Ypnypn,

Se usi letterali binari non devi stampare il file -.
TheNumberOne,

4

Mathematica - 47

Round@RandomVariate@NormalDistribution[0,15*^5]

Fondamentalmente, genera semplicemente un numero casuale usando una distribuzione normale con varianza pari a 1500000. Questo produrrà un numero intero compreso tra -10 ^ 6 e 10 ^ 6 con probabilità 49.5015%.


"Questo produrrà un numero intero compreso tra -10 ^ 6 e 10 ^ 6 con probabilità 50,4985%." - non è abbastanza. Hai letto male le specifiche? Forse intendevi usare 10 ^ 7 come varianza?
John Dvorak,

@JanDvorak Probabilità sbagliata, scusa. Ora è quello giusto.
Swish,

L'implementazione di questo in Mathematica copre davvero tutti i numeri interi? Non ho accesso alla fonte ma immagino di no ...
trichoplax,

@githubphagocyte Dipenderebbe dalla precisione attuale.
Swish,

4
Quello che voglio dire è che specificare una precisione specifica escluderà numeri più grandi di quello. L'unico modo in cui potrebbe funzionare è se si potesse specificare una precisione illimitata.
trichoplax,

4

Python 2, 75 69 byte

from random import*;s=0;j=randrange
while j(12):s=s*9+j(-8,9)
print s

È banale verificare che il ciclo while nel mezzo possa generare tutti gli interi (anche se distorti verso zero). "12" è scelto in modo tale che circa la metà dei numeri superi ± 10 6 .


Soluzione precedente:

Python 2, 44 byte

Basato sulla soluzione Mathematica .

from random import*;print int(gauss(0,8**7))

Non funziona davvero perché Python floatha solo una precisione limitata.


Questo non sarà in grado di generare tutti i numeri interi, perché il generatore di numeri pseudo-casuali ha una quantità finita di stato interno. Secondo la documentazione Python utilizza il Mersenne Twister, quindi lo stato è piuttosto ampio. Ma non è infinito, quindi può solo produrre un sottoinsieme finito di tutti gli interi.
Starblue,

@starblue: dall'OP: "Puoi presumere che il generatore di numeri casuali della tua lingua sia un vero generatore di numeri casuali anche se non è così".
kennytm,

3

Ruby, 70 anni

f=->{m=10**6
r=rand -m..m
r<1?(r>-5e5??-:'')+r.to_s+f[][/\d+/]:r.to_s}

Per rendere possibile la generazione di numeri molto grandi, sto restituendo il numero come Stringda una lambda. Se ciò non è consentito, conta 8 caratteri in più (per puts f[]) per renderlo un programma anziché una funzione.

Spiegazione

Genera un numero tra -1,000,000e 1,000,000. Se il numero è 1o superiore, il numero viene restituito come a String.

Se il numero è inferiore a 1, la funzione viene chiamata in modo ricorsivo per restituire il numero al di fuori dell'intervallo numerico. Per assicurarsi che anche i numeri negativi possano essere generati, a -viene anteposto il risultato Stringse il numero iniziale è maggiore di -500,000.

Spero di aver capito bene la sfida!


3

R, 38

library(Rmpfr)
round(rnorm(1,2e6,1e6))

Disegna dalla distribuzione gaussiana con 2.000.000 di media, scelti a caso e deviazione standard di 1.000.000, in modo che circa i 2/3 dei sorteggi si trovino tra 1.000.000 e 3.000.000. La distribuzione è illimitata, quindi in teoria questo può generare qualsiasi numero intero. Il pacchetto Rmpfr sostituisce i doppi galleggianti integrati di R con precisione arbitraria.


Sì, ho capito di aver letto male le specifiche. E immagino che abbia gli stessi limiti sulla precisione della macchina con Mathematica
Shadowtalker il

Hmm in quel caso non ne sono sicuro. Dovrò esaminarlo; considera questa risposta "in attesa" per ora
shadowtalker il

@ MartinBüttner riparato penso
shadowtalker il

Interessante. Non penso che tu abbia bisogno di tutto il sample(c(1,-1),1)pensiero però. Basta centrare su 1e6 dovrebbe essere sufficiente ..
Martin Ender il

@ MartinBüttner oh non deve essere il 50% ad entrambe le estremità? Non era chiaro
Shadowtalker il

2

Perl, 53 caratteri

print"-"if rand>.5;do{print int rand 10}while rand>.1

Certamente non vedo alcun motivo per lavorare con numeri interi quando ne stampo uno :)

Ha la stessa probabilità di stampare un numero con o senza un "-" iniziale.

Stampa un numero di 1 cifra il 10% delle volte, un numero di 2 cifre il 9% delle volte, un numero di 3 cifre l'8,1% delle volte, un numero di 4 cifre il 7,29% delle volte, un numero di 5 cifre 6,56% delle volte, un numero di 6 cifre 5,9% delle volte, ecc. È possibile qualsiasi lunghezza, con probabilità decrescente. I numeri da una a cinque cifre rappresentano circa il 41,5% dei casi di output e il numero 1.000.000 (o -1.000.000) solo il 6 milionesimo di percento, quindi il numero di output sarà al di fuori dell'intervallo compreso tra -1.000.000 e 1.000.000 circa 54,6 % del tempo.

Sia "0" che "-0" sono possibili output, che spero non sia un problema.


Questa stampa non "numera" gradisce -00000000167? Non è proprio un numero intero.
Isaacg,

1
@isaacg Non vedo perché non sia un numero intero.
Ottimizzatore il

2
@Optimizer Lo è, ma l'OP ha esplicitamente vietato il comando 0.
Martin Ender il

Potresti generare una cifra iniziale diversa da zero prima del ciclo, da -9 a +9. print int(rand(20)-10)||1. Tuttavia, ho bisogno di un modo per generare 0 come output. Forse || die 0, se la spazzatura finale dopo lo zero è consentita. Altrimenti è necessario un modo breve per stampare lo zero ed uscire senza ulteriore output se int(rand(20)-10)==0.
Peter Cordes,

@PeterCordes ha concordato, è un approccio decente ma non ho voglia di scriverlo e non penso che sarebbe competitivo dal punto di vista della lunghezza. Sentiti libero di
inviarlo da

2

Perl, 114 caratteri

use Math::BigInt;sub r{$x=Math::BigInt->new(0);while(rand(99)!=0){$x->badd(rand(2**99)-2**98);}print($x->bstr());}

Abbattersi:

use Math::BigInt;               -- include BigIntegers
  sub r{                        -- Define subroutine "r"
    $x=Math::BigInt->new(0);    -- Create BigInteger $x with initial value "0"
      while(rand(99)!=0){       -- Loop around until rand(99) equals "0" (may be a long time)
        $x->badd(               -- Add a value to that BigInt
          rand(2**99)-2**98);   -- Generate a random number between -2^98 and +2^98-1
        }print($x->bstr());}    -- print the value of the BigInt

La probabilità di ottenere un valore compreso tra -1.000.000 e 1.000.000 tende allo zero MA è possibile.

Nota: questa subroutine potrebbe funzionare a lungo ed errori con "Memoria esaurita!" errore ma sta generando tecnicamente qualsiasi numero intero come indicato nella domanda.

Perl, 25 anni

sub r{rand(2**99)-2**98;}

Genera un numero intero casuale nell'intervallo di +/- 2 ^ 99.

Abbattersi

sub r{                    -- Define subroutine "r"
     rand(2**99)          -- Generate a random integer between 0 and 2^99
                -2**98;}  -- Subtract 2^98 to get negative values as well

Testato con 1 milione di campioni:

~5 are inside the range of +/-1.000.000
~999.995 are outside that range
= a probability of ~99,99% of generating an integer outside that range.
Compare that number to the probability of 2.000.000 in 2^99: It is approx. the same.

Questo soddisfa tutte le regole:

  • 1 numero intero
  • è possibile qualsiasi numero intero
  • almeno il 50% (nel mio caso il 99,99%) di tutti gli interi generati è al di fuori dell'intervallo di +/- 1.000.000.

Questo funziona perché il generatore di numeri casuali sottostante definisce la stessa probabilità per ogni bit generato, e lo fa anche su numeri interi generati.
Ogni numero intero ha una probabilità di 1/2 ^ 99 da generare.

Modificare:

Ho dovuto aumentare l'esponente in modo da generare numeri più grandi. Ho scelto 99 perché mantiene il codice il più breve possibile.


Non siamo d'accordo sul fatto che non dovrebbero esserci limiti superiori / inferiori? Ad esempio, l'intero 2 ^ 31 + 1 ha 0 probabilità, infrangendo la regola 2
Ottimizzatore il

@Optimizer per me un numero intero è definito come in molti linguaggi di programmazione: un numero entro i limiti di -2^31e +2^31-1(32 bit). Puoi aumentare facilmente gli esponenti se desideri generare numeri interi più grandi, ma potrebbe non riuscire a seconda dell'implementazione di Perl.
GiantTree,

Ho appena visto che deve essere generato anche quell'intero ridicolmente grande. Modificherò rapidamente il mio codice.
GiantTree,

@ MartinBüttner Ho fatto del mio meglio per soddisfare le specifiche della domanda. Non è possibile per me (almeno non senza aiuto) generare numeri interi infinitamente grandi. Il numero intero più grande del Perl è circa 1,7e308 che è un limite che non posso controllare.
GiantTree,

@ MartinBüttner Entrambi sono possibili ma ad es. la stringa traboccarebbe dopo 2 GB di dati rendendola di nuovo finita. È difficile dire che un numero dovrebbe essere infinitamente grande se ci sono problemi con la memoria. Presto avrò un approccio diverso usando BigInts. Inoltre, il numero intero non trabocca a 1.7e308, ma viene convertito in infite ( 1.#INFper l'esattezza)
GiantTree,

2

C #, 126 107 byte

string F(){var a=new System.Random();var b=a.Next(-1E6,1E6+1)+"";while(a.Next(1)>0)b+=a.Next(10);return b;}

Ungolfed:

string F()
{
    System.Random rand = new System.Random();
    string rtn = rand.Next(-1E6, 1E6 + 1) + "";
    while (rand.Next(1) > 0)
         rtn += a.Next(10);
    return rtn;
}

La possibilità di generare un numero di n cifre è 1/2 ^ (n-10), che è maggiore di 0 per tutti i n positivi e 1/2 per n = 11.Crea anche zeri iniziali, che non sembrano essere vietati nella domanda originale o in nessuno dei suoi commenti.


Quando si utilizza using System;, non è necessario System.Randomdue volte, ma giusto Random, giusto?
Charlie, il

@Charlie Questa è una funzione, quindi non posso usare le usingdichiarazioni. Avrebbe comunque salvato solo 1 carattere.
LegionMammal978,

1
Puoi salvare 1 carattere rimuovendo lo spazio in -1E6, 1E6+1.
Programma FOX il

2

Perl, 62 byte

print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}

Ho avuto la stessa idea di @Hobbs, di generare una cifra alla volta, ma il suo codice non soddisfaceva il requisito senza zero iniziale aggiunto. Generare la prima cifra anziché solo il segno ha risolto quello. E a meno che non ci sia un modo più breve per uscire se abbiamo stampato uno zero, o un modo più breve per generare i primi da -9 a 9, questo dovrebbe farlo per dimensioni.

In un loop di shell: while perl -e '...'; do echo;done |less

Penso che questo sia uno dei più brevi che non richiede RAM infinita per soddisfare il problema. Come bonus, l'output non è fortemente distorto verso nulla e il runtime è molto veloce.

Ho provato a usare bit per bit e a salvare un personaggio nella condizione while, ma penso che questo finisca per essere vero più spesso, quindi il ciclo termina prima. Avrebbero bisogno di più caratteri per regolare altre cose per contrastare ciò, per mantenere la probabilità di generare addominali (output)> 1M.


Bene, hai spremuto alcune cose che non avrei mai pensato :)
hobbs,

1

Javascript (73)

Questa soluzione utilizza che è possibile costruire un numero con base n moltiplicando il numero precedente per n e aggiungendo una cifra in base n . Abbiamo un ulteriore ..?..:..in là per essere in grado di creare tutti gli interi negativi. Il seguente codice deve essere testato in una console del browser.

b=Math.round;c=Math.random;x=0;while(b(c()*99)){x*=b(c())?2:-2;x+=b(c())}

La probabilità di ottenere un numero intero> = 2^1(o <= -(2^1)) è uguale alla possibilità che il ciclo venga eseguito 2 volte. La possibilità che ciò accada è (98/99)^2. La possibilità di ottenere un numero maggiore di 2^20(o <= -(2^20)) è quindi (98/99)^21 = 0.808o 81%. Questo è tutto in teoria, però, e supponendo che Math.random sia veramente casuale. Ovviamente non lo è.


Snippet che verifica questo codice. Anche in un modo più leggibile.


1
L'OP ha ora confermato che puoi presumere che il tuo PRNG sia veramente casuale, anche se non lo è.
trichoplax,

1

GolfScript, 20 byte

0{)8.?rand}do.2&(*4/

Sì, anche questo è un po 'lento.

Rispetto a linguaggi come CJam e Pyth, GolfScript soffre di una parola chiave generica di generazione di numeri casuali (rand ) di . Per superare questo handicap, avevo bisogno di trovare un modo per usarlo solo una volta.

Questo codice funziona selezionando ripetutamente un numero casuale compreso tra 0 e 8 8 −1 = 16.777.215 inclusi e incrementando un contatore fino a quando il numero casuale risulta essere 0. Il valore del contatore risultante ha una distribuzione geometrica con una mediana di circa -1 / log 2 (1 - 1/8 8 ) ≈ 11.629.080, quindi soddisfa il test "oltre 1.000.000 almeno il 50% delle volte".

Purtroppo, il numero casuale così generato è sempre strettamente positivo. Pertanto, la .2&(*4/parte aggiuntiva è necessaria per renderla negativa o zero. Funziona estraendo il secondo bit più basso del numero (che è quindi 0 o 2), decrementandolo per renderlo -1 o 1, moltiplicandolo per il numero originale e dividendo il risultato per 4 (per sbarazzarsi di i due bit più bassi, che ora sono correlati con il segno, e anche per consentire al risultato di diventare zero). Anche dopo la divisione per 4, il valore assoluto del numero casuale ha ancora una mediana di -1 / log 2 (1 - 1/8 8 ) / 4 ≈ 2.907.270, quindi supera ancora il test del 50%.


1

JavaScript, 81 byte

Questo codice soddisfa tutte le regole:

  • Emette un numero intero con probabilità positiva
  • Interi di output al di fuori dell'intervallo di +/- 1000000 con almeno il 50% di probabilità
  • Nessun vantaggio 0nell'output

Come bonus, l'algoritmo funziona con una complessità temporale di O (log 10 n), quindi restituisce il numero intero quasi istantaneamente.

for(s="",r=Math.random;r()>.1;s+=10*r()|0);r(s=s.replace(/^0*/,"")||0)<.5?"-"+s:s

Ciò presuppone un ambiente REPL. Prova a eseguire il codice sopra nella console del tuo browser o usa lo snippet di stack qui sotto:

D.onclick = function() {
  for(s="", r=Math.random;r()>.1; s+=10*r()|0);
  P.innerHTML += (r(s=s.replace(/^0*/,"") || 0) <.5 ?"-" + s : s) + "<br>"
}
<button id=D>Generate a random number</button><pre id=P></pre>

Algoritmo :

  • Continua ad aggiungere cifre casuali alla stringa sfino a a Math.random() > 0.1.
  • In base a Math.random() > 0.5, rendere il numero negativo (anteponendo la stringa scon -).

Questo algoritmo non ha una distribuzione uniforme su tutti i numeri interi. I numeri interi con un numero di cifre più elevato sono meno probabili di quelli inferiori. In ognuno per l'iterazione del ciclo, c'è una probabilità del 10% che mi fermerò alla cifra corrente. Devo solo assicurarmi di fermarmi dopo 6 cifre più del 50% delle volte.

Questa equazione di @nutki spiega il valore massimo della percentuale di probabilità di arresto in base alla condizione di cui sopra:

1 - 50%^(1/6) ≈ 0.11

Quindi 0,1 è ben entro il raggio d'azione per soddisfare tutte e tre le regole della domanda.


Ci sono alcune cose che mi confondono su questa risposta. Hai supposto che Math.random () generi una distribuzione uniforme di numeri casuali, perché la specifica afferma che dipende dall'implementazione. Supponendo che si tratti di una distribuzione uniforme, P (Math.random ()> 0.1) = 0.9, quindi esiste un'enorme probabilità che si interrompa tra ogni iterazione. Un'implementazione del tuo algoritmo eseguito su Firefox 34.0 Ubuntu mi dà una probabilità di ~ 0,47 (<0,5) ogni volta che lo collaudo: jsfiddle.net/WK_of_Angmar/dh8gq4pb
Wk_of_Angmar

Inoltre, come sei riuscito a calcolare una complessità temporale per un algoritmo senza un input?
Wk_of_Angmar,

1

TI-BASIC, 14 byte

1-2int(2rand:randNorm(AnsE6,9

Simile alla risposta R di @ ssdecontrol, questo si basa sulla distribuzione gaussiana con media -1.000.000 o 1.000.000, scelti casualmente e deviazione standard 9. La distribuzione è illimitata, quindi in teoria questo può generare qualsiasi numero intero.

Spiegazione :

1-2int(2rand     - get a random integer 0 or 1, then multiply by 2 and subtract 1
:                - this gives the number 1 or -1 (with equal probability) to Ans
randNorm(AnsE6,9 - displays Gaussian distribution with mean (Ans * 1,000,000) and std. dev. 9

Ma può generare "2" o "-2"?
kennytm,


1
OK leggi il codice in modo errato (pensato :significa "stampa" a causa di come viene presentata la spiegazione). Ma può generare numeri con più di 20 cifre?
kennytm,

Qualunque numero intero lungo arbitrario è possibile come output? Non è limitato dalla gamma di randNorm?
Ottimizzatore il

"La distribuzione è illimitata, quindi in teoria questo può generare qualsiasi numero intero." Non c'è intervallo.
Timtech,

1

Bash, 66

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/random

Stampa quasi sempre 5000000. Ma se trova un numero valido in /dev/random , stampa invece quel numero.

E questo è più veloce:

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/urandom

1
@Optimizer Dovrebbe essere lento. Questo perché è una vera fonte casuale. Ma puoi provarlo con /dev/urandomquale è meno casuale.
jimmy23013,

@Optimizer Come sarebbe l'input manuale? Sta leggendo un file, ma tutto è un file.
Nit

@Optimizer Semplicemente non capisco il punto che stai cercando.
Nit

leggere da /dev/urandomuno script di shell è praticamente lo stesso che chiamare rand()in altre lingue. Sebbene se stai davvero usando bash, non POSIX sh, puoi ottenere numeri casuali da echo $RANDOM. wiki.ubuntu.com/DashAsBinSh fornisce hexdump /dev/urandomcome equivalente per bare-POSIX-minimo /bin/dash.
Peter Cordes,

1

C ++, 95 byte

void f(){int d=-18,s=-1;while(s<9){d=(rand()%19+d+9)%10;cout<<d;s=9-rand()%10*min(d*d+s+1,1);}}

Allargato:

void f() {
    int d=-18,s=-1;
    while(s<9) {
        d=(rand()%19+d+9)%10;
        cout<<d;
        s=9-rand()%10*min(d*d+s+1,1);
    }
}

Spiegazione:

La funzione continua a stampare cifre casuali consecutive fino a quando un interruttore a valore casuale assume il valore richiesto per arrestare la funzione. d è la variabile che mantiene il valore della cifra successiva da stampare. s è la variabile switch che accetta valori interi casuali nell'intervallo [0, 9], se s == 9 non vengono più stampate cifre e la funzione termina.

Le variabili d e s sono inizializzate per dare un trattamento speciale alla prima cifra (prendendo dall'intervallo [-9, 9] e se la prima cifra è zero, la funzione deve terminare per evitare zero iniziali). Il valore di d potrebbe essere assegnato come d = rand ()% 10 ma la prima cifra non potrebbe essere negativa. d viene invece assegnato come d = (rand ()% 19 + d + 9)% 10 e inizializzato a -18, quindi il primo valore di d sarà compreso tra [-9, 9] e i valori successivi saranno sempre compresi tra [0 , 9].

La variabile s varia in modo casuale da [0, 9] e se s è uguale a 9, la funzione termina, quindi dopo aver stampato la prima cifra, quella successiva verrà stampata con una probabilità del 90% (supponendo che rand () sia veramente casuale, e per soddisfare la terza condizione). s potrebbe essere facilmente assegnato come s = rand ()% 10, tuttavia, c'è un'eccezione, se la prima cifra è zero, la funzione deve terminare. Per gestire tale eccezione, s è stato assegnato come s = 9-rand ()% 10 * min (d * d + s + 1,1) e inizializzato come -1. Se la prima cifra è zero, il min restituirà 0 e s sarà uguale a 9-0 = 9. L'assegnazione della variabile s sarà sempre compresa tra [0, 9], quindi l'eccezione può verificarsi solo alla prima cifra.

Caratteristiche (supponendo che rand () sia veramente casuale)

  • L'intero viene stampato cifra per cifra, con una probabilità fissa del 90% di stampare un'altra cifra dopo aver stampato l'ultima.

  • 0 è il numero intero con la più alta probabilità di essere stampato, con una probabilità del 5,2% circa.

  • La probabilità di stampare un numero intero sull'intervallo [-10 ^ 6, 10 ^ 6] è approssimativamente del 44% (il calcolo non è scritto qui).

  • Gli interi positivi e negativi sono stampati con la stessa probabilità (~ 47.4%).

  • Non tutte le cifre sono stampate con la stessa probabilità. Ad esempio: nel mezzo della stampa del numero intero, se l'ultima cifra era 5, la cifra 3 avrà una probabilità leggermente inferiore di essere stampata successivamente. In generale, se l'ultima cifra era d, la cifra (d + 18)% 10 avrà una probabilità leggermente inferiore di essere stampata successivamente.

Esempi di output (10 esecuzioni)

-548856139437
7358950092214
507
912709491283845942316784
-68
-6
-87614261
0
-5139524
7

Process returned 0 (0x0)   execution time : 0.928 s
Press any key to continue.

1

Bash, 42 byte

printf "%d\n" 0x$(xxd -p -l5 /dev/random)
/ dev / random su OSX è solo byte casuali e xxd -p -l5converte 5 caratteri ASCII in esadecimali e li printftrasforma in formato decimale.


0

Pyth , 11 byte

WOyG~ZtOT)Z

Nota: questo programma probabilmente si arresterà in modo anomalo con un errore di memoria su qualsiasi computer reale. Per provarlo, prova a sostituirlo Gcon una stringa più corta, come in questo codice, che genera numeri in media intorno a 28000:

pyth -c 'WOy"abcdefghijklm"~ZtOUT)Z'

Questo codice scorre, aggiungendo un numero casuale da -1 a 8 a Z, con una probabilità 2 ^ -26 di uscire dal ciclo su ogni ripetizione. La probabilità 2 ^ -26 si ottiene selezionando un elemento casuale ( O) dell'insieme di tutti i sottoinsiemi ( y) dell'alfabeto ( G).

Dettagli tecnici e giustificazione:

La probabilità 2 ^ -26 è derivata da due fatti:, yquando chiamata su sequenze, è la funzione di accensione, costruisce l'elenco di tutti i sottoinsiemi dell'input. Poiché l'ingresso, Gè lungo 26 caratteri, questo set di potenza yGha 2 ^ 26 voci. OyGseleziona un elemento casuale tra quelle 2 ^ 26 voci. Esattamente una di quelle voci, la stringa vuota, verrà valutata come falsa quando passata al Wciclo while. Pertanto, esiste una probabilità 2 ^ -26 di uscire dal loop ogni volta.

In qualsiasi numero fisso di cicli di loop K, la probabilità di ottenere il numero K * 3,5 + m e di ottenere K * 3,5 - m sono uguali, poiché ogni sequenza di addend che raggiunge un totale può essere invertita, -1 -> 8, 0 -> 7, ecc., Per raggiungere l'altro. Inoltre, i numeri più vicini a K * 3.5 sono chiaramente più probabili dei numeri più lontani. Pertanto, se K> 2000000 / 3.5 = 571428.5 la probabilità di ottenere un numero superiore a 1000000 è maggiore del 75%, poiché alcuni dei risultati sopra quel numero possono essere inseriti in una corrispondenza uno a uno con tutti i risultati sottostanti che numero, e la metà inferiore della metà, può essere messa in una corrispondenza uno a uno con quelle inferiori a 1000000. La probabilità di ottenere almeno 571429 loop è (1-2 ^ -26) ^ 571429, che è no inferiore a (1-2 ^ -26 * 571429), il numero previsto di volte in cui si è usciti dal ciclo durante i primi 571429 tentativi, pari al 99,1%. Pertanto, con il 99,1% o più di prove, c'è una probabilità del 75% o più di ottenere almeno 1000000, quindi c'è più del 50% di probabilità di superare 1000000.

Questo codice si basa su un comportamento in Ocui un bug è stato introdotto accidentalmente 3 giorni fa ed è stato corretto oggi. Dovrebbe funzionare su qualsiasi versione di Pyth 3 precedente al 22 dicembre o dopo oggi. Il seguente codice è equivalente e ha sempre funzionato:

WOyG~ZtOUT)Z

Che cosa è successo al compilatore online?
Ottimizzatore

@Optimizer Problemi con il sito Web, ci lavorerò su.
isaacg

Ah, bello. Volevo lavorare sulla traduzione Pyth della mia risposta CJam ieri e ho scoperto che dà 404.
Optimizer,

0

Java, 113 byte

void g(){String a=Math.random()>0?"10":"01";for(;Math.random()>0;)a+=(int)(Math.random()*2);System.out.print(a);}

Questo programma stampa un numero binario sul flusso di output standard. Potresti dover aspettare un po 'perché la probabilità che finisca il numero (o sia positivo) è di circa 0. L'idea che il valore assoluto di un numero generato sia inferiore a 1 milione è divertente, ma possibile.

Ungolfed:

void g(){
    String a=Math.random()>0?"10":"01";             //Make sure there are no trailing zeroes.
    for(;Math.random()>0;)a+=(int)(Math.random()*2);//Add digits
    System.out.print(a);                            //Print
}

Esempio di output: pubblicherà quando viene generato un numero.


0

Java (JDK) , 140 127 byte

()->{int i;var o=System.out;for(o.print(i=(int)(19*Math.random())-10);i!=0&Math.random()<.9;)o.print((int)(11*Math.random()));}

-13 bytes inserendo più logica nell'intestazione del loop, grazie a @ceilingcat

Provalo online!

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.