2012-06-20 11 views
5

Quindi, in pratica per divertimento stavo cercando di generare una colonna di numeri (7 cifre solo 0 e 1) il mio codice piuttosto breve:Come ottenere casuale 0 e 1 numeri

a = rand(0000000-1111111) 
b = 220 
a1 = rand(0000000-1111111) 
a2 = rand(0000000-1111111) 
a3 = rand(0000000-1111111) 
a4 = rand(0000000-1111111) 
a5 = rand(0000000-1111111) 

while b !=0 
    puts a 
    puts a2 
    puts a3 
    puts a4 
    puts a5 
end 

Il mio problema è che invece di generare una colonna casuale di 0s e 1s tutti i numeri vengono utilizzati.

+0

Fai stringa vuota. Generare un numero alla volta, ad esempio rand (0-1), e aggiungerlo alla stringa che era vuota all'inizio. Fatelo tutte le volte che volete le cifre. Non puoi trattare i numeri dei decimali in questo modo senza dire la lingua in un modo o nell'altro. Mi dispiace di non poter fare il codice per te - non ho installato un'implementazione ruby ​​... –

+0

Hai cercato come funziona la funzione casuale? E sottrazione? E la terminazione del ciclo? –

+2

Se è possibile stampare facilmente file binari, è possibile generare numeri da 0-127 e stampare il loro formato binario. – nhahtdh

risposta

12

Ecco idiomaticish Rubino:

5.times do 
    puts (1..7).map { [0, 1].sample }.join 
end 

Diciamo scompattarlo:

5.times do...end è abbastanza auto-esplicativo. Fai qualsiasi cosa tra do e end cinque volte.

(1..7) genera un array con sette elementi. In realtà non ci importa cosa ci sia in questo momento. map restituisce un nuovo array in cui ogni elemento è il risultato della chiamata di cosa c'è tra le parentesi. Quindi, sette volte chiameremo lo [0, 1].sample e spremeremo i risultati in un array. Lo stesso sample seleziona in modo casuale sia 0 o 1. Infine, .join trasforma una matrice in una stringa. Se avessimo detto .join('-'), per esempio, avrebbe messo un trattino tra ogni elemento (1-0-0-1-1-1-0-1). Ma dal momento che non abbiamo specificato nulla, non mette nulla tra ogni elemento (10011101).

E ce l'hai.

Come altri hanno notato, per questo particolare problema è possibile fare cose più veloci e più brevi utilizzando il binario. Però non penso che questa sia la Ruby Way. Per quanto riguarda la velocità, "l'ottimizzazione prematura è la radice di tutti i mali", e se hai una violenta avversione al codice lento non dovresti codificare comunque Ruby. Per quanto riguarda la leggibilità, quella via potrebbe essere più breve, ma la modalità sopra è molto più chiara. "Oh, stiamo facendo qualcosa cinque volte, e stamperemo una sequenza di 7 sequenze casuali di 0 e 1 ... come una stringa". Sembra quasi inglese (se conosci la parola map (definizione tre)).

+0

Suppongo che dipenda dall'affermazione del problema e dal _reason_ che il programma esiste del tutto. Quando sento che sette numeri '0' o' 1' devono essere generati, posso solo pensare alle rappresentazioni di '0..127', quindi mi sembra il più naturale per me. Il tuo intelligente '(1..7)' evita l'orribile proliferazione di variabili che verrebbero utilizzate in codice ingenuo e insegna lo strumento utile per creare un array anonimo che viene rapidamente scartato. – sarnold

+0

La tua versione sarebbe molto più semplice da _extend_ a N colonne di 'a',' 7' e '€' caratteri - ma la versione di minitech mi sembra più naturale se il problema è strettamente legato alle rappresentazioni _number_. – sarnold

+0

Ecco una versione modificata di questo codice che ho usato (a volte genera arte ASCII casuale: D) 'code'5.times do puts (1..7) .map {rand (2)} .join end'code ' – Delta

10

Il modo migliore per risolvere questo è probabilmente di fare la conversione di base:

someNumber = rand(1 << 7) # Seven digits, max; 1 << 7 is 10000000 in binary. 

puts someNumber.to_s(2).ljust(7, '0') # 10110100, e.g. 
+0

why ljust 4 and not 7? – DGM

+0

@DGM: Ho * veramente * grandi dita;) – Ryan

+0

per fortuna, ho ottenuto un'uscita di "0000": D – DGM

1

Rubino non capisce dal tuo rand() input che si desidera i numeri specificamente formattati.

Invece di generare ogni cifra in modo casuale (rand(2)) e creare l'intero numero di sette variabili come questa. Stampa il risultato su una riga a parte, quindi riavvia il ciclo.

Un'altra opzione è quella di generare un numero casuale tra 0 e 127 e quindi formattarlo per l'output binario. Questo trascorre molto meno tempo nel generatore di numeri casuali e riduce drasticamente le variabili nel programma.

Entrambi gli approcci vanno bene per un programma di apprendimento. Prova entrambi e vedi quale versione preferisci. Cerca di capire perché preferisci un modo piuttosto che un altro.

+0

qualcuno potrebbe dirmi come fare l'opzione 2? – Delta

+0

[la risposta di Minitech] (http://stackoverflow.com/a/11111899/377270) ha molto ben coperto. :) Non mi aspettavo che convertire il numero in binario fosse così semplice come to_s (2) '. – sarnold

2

Derivazione della risposta di @ MiniTech

5.times { puts "%07b" % rand(128) } 
1

Ecco un metodo che genera un numero arbitrario (predefinito 1) di numeri binari di una lunghezza specificata:

def random_binary(length, n=1) 
    raise ArgumentError if n < 1 
    (1..n).map { "%0#{length}b" % rand(2**length) } 
end 

random_binary(7, 5) 
#=> ["0011100", "1001010", "0101111", "0010101", "1100101"] 
Problemi correlati