Quanti dadi puoi lanciare senza tirare il numero più probabile


26

Problema

A partire dai n=2dadi:

  • Lancia i ndadi, con ogni numero da 1 a 6 ugualmente probabile su ogni dado.
  • Controlla se la loro somma è uguale alla somma più probabile per i ndadi, cioè 3.5*n.
    • Se sono uguali, termina.
    • Altrimenti, stampa ne ripeti dall'inizio con i n+2dadi

Il codice non deve eseguire esattamente questa procedura, ma dovrebbe fornire un output casuale probabilisticamente equivalente ad esso, in base alla nostra definizione di casualità .

Il tuo programma dovrebbe generare tutti i numeri sulla propria riga; per esempio, se il programma ottenesse fino a 8 dadi e tirasse il numero più probabile con 8 dadi, l'output sarebbe:

2
4
6

Esempio di esecuzione

Su 2 dadi, 7è la somma più probabile. Diciamo che i numeri ottenuti erano 2e 3. Quindi, si stampa 2.

Su 4 dadi, 14è la somma più probabile. Diciamo che i numeri erano arrotolati 3, 4, 2, e 5. Quindi, la somma è 14, quindi il programma terminerebbe qui.

L'output finale in questo caso è "2".

Regole


Questa risposta, così com'è, non è molto chiara. C'è un input, o è destinato a generare l'output da nessun input come un loop? C'è qualche casualità? Non sembra vedere alcuna casualità coinvolta.
HyperNeutrino,

A proposito, benvenuto in PPCG! :)
HyperNeutrino il

Grazie, mi dispiace, sono molto nuovo in questo. Cosa lo renderebbe più chiaro? Non ci sono input, dovresti iniziare con un dado e salire il più in alto possibile.
Zoecarver,

@pudility Quindi, se ho capito bene, dovrei continuare a 2, 4, 6, 8, ...lanciare un lancio di tanti dadi ogni volta fino a quando non raggiungo il numero più probabile per quell'iterazione?
HyperNeutrino,

5
Grazie per aver dedicato del tempo per modificare la tua sfida in base al nostro feedback! Per la cronaca, abbiamo un posto dove è possibile pubblicare sfide per elaborare alcuni dettagli prima di pubblicare: il sandbox .
FryAmTheEggman,

Risposte:


17

Python 2 , 70 byte

from random import*
n=2
while eval("+randrange(6)-2.5"*n):print n;n+=2

Provalo online!

Il trucco è calcolare la somma evalinging una stringa che assomiglia

'+randrange(6)-2.5+randrange(6)-2.5'

con ncopie dell'espressione concatenate. Le randrange(6)uscite un numero casuale da [0,1,2,3,4,5], che viene spostata dalla 2.5abbiano media 0. Quando la somma se 0, la whilecondizione fallisce e il ciclo termina.

Un'alternativa usando mapera 4 byte più lunghi:

from random import*
n=2
while sum(map(randrange,[6]*n))-2.5*n:print n;n+=2

Ho trovato un sacco di espressioni di uguale lunghezza per un dado spostato a zero, ma nessuna più breve

randrange(6)-2.5
randint(0,5)-2.5
randrange(6)*2-5
uniform(-3,3)//1

11
Mi piace questo! Principalmente perché è l'unico che capisco.
Zoecarver

7

MATL , 13 byte

`@E6y&Yrs@7*-

Provalo online!

Spiegazione

`       % Do...while top of the stack is truthy
  @E    %   Push 2*k, where k is the iteration index starting at 1
  6     %   Push 6
  y     %   Duplicate 2*k onto the top of the stack
  &Yr   %   Array of 2*k integers distributed uniformly in {1, 2, ..., 6}
  s     %   Sum
  @7*   %   Push 7*k
  -     %   Subtract
        % End (implicit). If the top of the stack is non-zero, the loop
        % proceeds with the next iteration. Else the loop is exited.
        % Display stack (implicit)

6

Gelatina ,  19  14 byte

-5 byte con l'aiuto di Leaky Nun (passando dal conteggio alla ricorsione)

‘‘6ṗX_3.L⁶S?Ṅß

Un programma completo che stampa i risultati separati da nuove righe (vengono stampati anche uno spazio extra e una nuova riga e gli errori del programma alla fine).

Provalo online! - ogni volta che vengono superati 6 dadi TIO lo uccide a causa dell'utilizzo della memoria, ma funziona in linea di principio - ci vogliono anche ~ 40 secondi per farlo.

È disponibile una versione più amichevole di 15 byte che non richiede così tanto tempo o richiede così tanta memoria qui .

Come?

Lancia in modo ricorsivo altri 2 dadi fino a quando la somma delle facce ridotta di 3,5 è zero, stampando il numero di dadi mentre procede, quando viene raggiunto lo zero tenta di usare un carattere spazio causando un errore di tipo.

‘‘6ṗX_3.L⁶S?Ṅß - Main link: no arguments (implicit left=zero)
‘              - increment (initial zero or the previous result)
 ‘             - increment  (= # of dice to roll, n)
  6            - literal 6
   ṗ           - Cartesian power - all possible rolls of n 6-sided dice with faces 1-6
    X          - pick one of them
      3.       - literal 3.5
     _         - subtract 3.5 from each of the roll results
           ?   - if:
          S    -          sum the adjusted roll results (will be 0 for most common)
        L      - ...then: length (number of dice that were rolled)
         ⁶     - ...else: literal ' ' (causes error when incremented in next step)
            Ṅ  - print that plus a newline
             ß - call this link with the same arity (as a monad with the result)

Caspita, sono pochissimi byte. Molto bene! Mi sto trattenendo dall'accettarlo fino a quando poche altre persone risponderanno.
Zoecarver

Sì, è normale aspettare un po 'prima di accettare, anche se mai lo fa. Molte persone lo danno una settimana o due.
Jonathan Allan,

inoltre, dovresti produrre tutte le iterazioni, non solo l'ultima.
Zoecarver

Oh, ho risposto a una vecchia modifica - che la modifica completamente, non posso usare questo metodo in molti modi.
Jonathan Allan,

Oh aspetta solo la ns, OK forse è salvabile. Pensavo intendessi le somme :)
Jonathan Allan il

6

TI-BASIC, 28 byte

2→N
While mean(randInt(1,6,N)-3.5
Disp N
N+2→N
End

Spiegazione

  • randInt(1,6,N) genera un elenco di N numeri casuali da 1 a 6
  • mean(randInt(1,6,N)-3.5 ottiene la media dei tiri spostati verso il basso di 3,5
  • While continua fino a quando l'espressione media è uguale a zero (la somma più probabile)

5

R , 49 byte

n=2
while(sum(sample(6,n,T)-3.5)){print(n)
n=n+2}

sample(6,n,T) genera n campioni (pseudo) casuali dall'intervallo 1:6con la sostituzione. Sottraendo 3,5 da ciascun elemento si ottiene un risultato il cui valore sumè 0 (falso) se e solo se è il valore più comune.

Provalo online!

Salta i tiri di dado dispari.


Questo sembra produrre 80 ogni volta per me, possibile bug?
Zoecarver

@pudility puoi aggiungere spazi alla fine per riprovare; memorizza nella cache gli snippet di input / codice ogni volta
Giuseppe,

3
@Giuseppe È possibile disabilitare la cache in TIO in Impostazioni.
xnor

dopo aver disabilitato la cache come ha detto @xnor, ha funzionato molto bene. Grazie per la risposta!
Zoecarver,

@xnor che lo sapeva! Buono a sapersi in futuro.
Giuseppe,

4

Java 8, 123 149 113 108 byte

()->{for(int n=0,s=1,i;s!=n*7;){for(i=s=++n*2;i-->0;s+=Math.random()*6);if(s!=n*7)System.out.println(n*2);}}

O 107 byte se utilizziamo un Object nullparametro come inutilizzato .

+26 byte per una correzione di bug, sottolineata correttamente da @Jules nei commenti.
-41 byte grazie al grande pensiero di @ OliverGrégoire !

Spiegazione:

Provalo qui.

()->{                           // Method without parameter nor return-type
  for(int n=0,                  //  Amount of dice
          s=1,                  //  Sum
          i;                    //  Index
      s!=n*7;){                 //  Loop (1) as long as the sum doesn't equal `n`*7,
                                //  because we roll the dice per two, and 3.5*2=7
    for(i=s=++n*2;              //   Reset both the index and sum to `n`*2,
                                //   so we can use random 0-5, instead of 1-6
                                //   and we won't have to use `+1` at `Math.random()*6`
        i-->0;                  //   Inner loop (2) over the amount of dice
        s+=Math.random()*6      //    And increase the sum with their random results
    );                          //   End of inner loop (2)
    if(s!=n*7)                  //   If the sum doesn't equal `n`*7
      System.out.println(n*2);  //    Print the amount of dice for this iteration 
  }                             //  End of loop (1)
}                               // End of method

1
Penso che ci sia un errore nella funzione. Se ruguale a, 3.5*nil programma dovrebbe terminare direttamente. Ma, se capisco correttamente la funzione, verrà stampata nun'ultima volta prima di terminare.
raznagul,

@raznagul In realtà, non stava stampando un'altra volta. È stato comunque infastidito. Cosa ha fatto prima: random 1-12 (bug 1: avrebbe dovuto essere 2-12); controlla se questo equivale a 7: se lo è: abbiamo finito senza stampare; in caso contrario: tira di nuovo 2 dadi (bug 2, avrebbe dovuto essere di nuovo 4 dadi invece di 2); quindi stampa 2 e rilancia ndi 2. Quindi conteneva due bug (1-12 invece di 2-12; e lanciava dadi come 2 -> 2 -> 4 -> 6 -> ..., invece di 2 -> 4 -> 6 -> ...). Stava stampando correttamente comunque, perché non sarebbe andato System.out.println(n),n+=2se rfosse davvero uguale a 3.5*n.
Kevin Cruijssen,

2
"Lancia due dadi contemporaneamente, scegliendo un numero casuale da 2-12" - questo non è probabilisticamente equivalente al lancio di due dadi e all'aggiunta dei numeri come richiesto nella domanda, quindi non è una soluzione corretta.
Jules,

1
Shorter da pochi byte (113), ma probabilmente ancora golfable: ()->{for(int n=2,s=0,e=7,i;s!=e;n+=2,e+=7){for(i=n,s=n;i-->0;)s+=Math.random()*6;if(s!=e)System.out.println(n);}}. Inoltre, correggi riguardo al commento di Jules e alla mia spiegazione. nè cubo, sè somma, eè previsto, iè indice. Infine, la somma inizia con nper evitare a +1, nvolte e s!=eviene ripetuta perché non so proprio come evitare quel caso.
Olivier Grégoire,

1
L'ho giocato di nuovo un po ';)()->{for(int i=0,s=1,j;s!=i*7;){for(j=s=++i*2;j-->0;)s+=Math.random()*6;if(s!=i*7)System.out.println(i*2);}}
Olivier Grégoire il

3

05AB1E , 22 20 byte

-2 byte grazie a Emigna

[YF6L.RO}7Y*;ïQ#Y=ÌV

Provalo online!

Spiegazione

[YF6L.RO}7Y*;ïQ#Y=ÌV
[                    # Infinite loop start
 YF     }            # Y times... (Y defaults to 2)
   6L.R               # Push a random number between 1 and 6 (why does this have to be so looooong ._.)
       O              # Sum
         7Y*;ï       # Push 3.5 * Y as an int
              Q      # Is it equal to 3.5 * Y?
               #     # If so: Quit
                Y    # Push Y
                 =   # Print without popping
                  ÌV # Set Y to Y + 2

1
Se ti sposti Odopo .Rpuoi rimuovere )e s.
Emigna,

3

R, 48 44 42 byte

Un miglioramento di 5 byte sulla risposta di Giuseppe .

while(sum(sample(6,F<-F+2,1)-3.5))print(F)

Questo (ab) usa il fatto che Fè una variabile di default assegnata alla FALSEquale si costringe 0e può quindi essere incrementata, risparmiandoci la necessità di inizializzare una variabile contatore.


1
certo, puoi salvare due byte chiamando sample(6)invece di sample(1:6)ma barrato 44 è ancora 44 .... codegolf.stackexchange.com/a/82343/67312
Giuseppe

@Giuseppe Certo, grazie! Ho modificato la risposta ora.
rturnbull,

2

PHP , 75 byte

for($d=2;(++$i*7/2-$r+=rand(1,6))||$i<$d;)$i%$d?:$d+=1+print"$d
".$r=$i="";

Provalo online!


1
5^2/++$i*$d+=rand()%6è una condizione leggermente più breve per il loop. Inoltre penso che il loop corrente si chiuda erroneamente se il primo "dado" lanciato è un "1" (genera uno 0 per l'iniziale $d).
user59178

@ user59178 Bella idea ma potrebbe essere una divisione per errore zero quindi devo modificarla. Hai ragione la mia soluzione prima di fermarsi in questo caso che è sbagliato.
Jörg Hülsermann,

La risposta di 45 byte non è valida perché la distribuzione risultante non è la stessa della domanda, vedere qui . Penso che la tua risposta a 42 byte stia utilizzando anche una distribuzione errata; sembra supporre, ad esempio, che per due dadi, sia altrettanto probabile avere 2 e 7 come somma.

@Pakk Sì, la risposta a 45 byte non è valida. Penso che il tuo pensiero sia falso su ciò che accade nella versione a 42 byte. Guarda la versione ampliata Provalo online!
Jörg Hülsermann,

@ JörgHülsermann Quella versione estesa conferma ciò che dico. In una corretta implementazione, il valore di $ r / $ i dovrebbe avvicinarsi a 3,5 per valori maggiori di $ i, ma non vedo che ciò accada affatto. Ho ottenuto una media di 1,16 per 9984 dadi, statisticamente estremamente improbabile.


1

Mathematica, 47 byte

For[n=1,Tr@RandomInteger[5,2n++]!=5n,Print[2n]]

-5 byte da LLlAMnYP


1

05AB1E , 17 byte

[N·ÌD6Lã.R7;-O_#,

Provalo online!

Spiegazione

[                   # loop over N in 0...
 N·Ì                # push N*2+2
    D               # duplicate
     6L             # push range [1 ... 6]
       ã            # cartesian product (combinations of N*2+2 elements in range)
        .R          # pick one at random
          7;-       # subtract 3.5 from each dice roll
             O_#    # if sum == 0 exit loop
                ,   # otherwise print the copy of N*2+2

1

Lotto, 109 byte

@set/an=%1+2,s=n*5/2
@for /l %%i in (1,1,%n%)do @call set/as-=%%random%%%%%%6
@if %s% neq 0 echo %n%&%0 %n%

Piuttosto fastidiosamente, randomè una variabile d'ambiente magica, quindi viene sostituita con un valore casuale durante l'espansione dell'ambiente, che di solito accade prima che inizi il ciclo for. calllo fa accadere ogni volta attraverso il ciclo, ma è necessario raddoppiare i %segni per impedire l'espansione prima del ciclo. Il divertimento inizia perché vogliamo modulare il risultato per 6, che richiede un %segno reale , che ora deve essere raddoppiato due volte. Il risultato è sei %s consecutivi .


1

JavaScript (ES2015), 75 78 byte

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

Emette una serie di risultati separati da newline

Modifica: salvato un byte grazie a Shaggy, aggiunti 4 byte per avviare la funzione da 2

Spiegazione

f=n=>
  [...Array(n)]                // Array of size n
    .reduce(                   // Combine each item
      a=>a+Math.random()*6|0,  // Add a random roll between 0 and 5 for each item
    n)                         // Start at n to correct rolls to between 1 and 6
    ==3.5*n                    // Compare total to most probable roll total
  ? ''                         // If true, end
  : n+'\n'+f(n+2)              // Otherwise, output n and continue

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

let roll = _ => document.getElementById('rolls').innerHTML = f();
document.getElementById('roll-button').onclick = roll;
roll();
<button id="roll-button">Roll</button>
<pre id="rolls"></pre>


2
Salvare un byte utilizzando una nuova riga letterale racchiusa tra i backtick, anziché '\n'.
Shaggy,

Questo non inizia con n=2, invece devi specificare il numero iniziale di dadi quando viene chiamata la funzione.
MT0

1

php - 89 personaggi

$r=0;$n=2;while($r!=$n*3.5){$r=$i=0;while($i<$n){$r+=rand(1,6);$i++;}print $n."
";$n+=2;}

non è necessario il primo $r=0;utilizzo al echoposto di print $n."può essere scritto come "$ne per i loop anziché mentre while consente di fare qualcosa nel ciclo after o prima per salvare alcuni byte
Jörg Hülsermann


1

Haskell 133 132 byte

import System.Random;import Control.Monad
s k=do n<-replicateM k$randomRIO(1,6);if sum n==7*div k 2 then pure()else do print k;s(k+2)

Ringraziamo @Laikoni per i suggerimenti nei commenti qui sotto.


1.) Le importazioni devono essere conteggiate nel conteggio dei byte. 2.) return()può essere abbreviato pure()e putStrLn$showaccorciato print.
Laikoni,

Lo riparerò subito. Grazie
Davide Spataro il

Altre piccole cose: div k 2 thenpuò essere div k 2thened do print k;s(k+2)è print k>>s(k+2).
Laikoni,

1

Ottava 55 byte

n=2;
while mean(randi(6,n,1))-3.5!=0
n
n=n+2;
end

Ispirato dalla risposta di Andrewarchi. Se qualcuno ha qualche suggerimento per accorciarlo, sono i benvenuti.


Wow, TI-BASIC e Octave hanno sintassi sorprendentemente simili
andrewarchi,

@andrewarchi Octave (la versione online è ciò che uso) sono solo le basi delle basi quando si tratta di programmazione.
Michthan,


0

QBIC , 40 byte

{[1,r|g=g+_r1,6|]~g=r*3.5|_X\g=0?r┘r=r+2

Questo abbastanza letteralmente fa ciò che la sfida richiede; sembra il modo più breve per ottenere la distribuzione corretta.

Spiegazione

{          DO infinitely
[1,r|      FOR a=1, a<=r (at start, r == 2), a++
g=g+       Add to g (0 at start)
  _r1,6|   a random number between 1 and 6 incl.
]          NEXT
~g=r*3.5   IF the result of all dice rolls equals the expected value
|_X        THEN quit
\g=0       ELSE, reset the dice total
?r┘        PRINT the number of dice used
r=r+2      and add 2 dice.
           END IF and LOOP are courtiously provided by QBIC at EOF.


0

JavaScript (ES6) - 69 caratteri

r=n=>n?r(n-1)+(Math.random()*6|0)-2.5:0;f=(n=2)=>r(n)?n+`
`+f(n+2):""

console.log(f())

Spiegazione :

r=n=>                                     # Roll n dice
     n?                                   # If there is a dice left to roll
       r(n-1)                             #   Roll n-1 dice
             +(Math.random()*6|0)         #   Add a random number from 0 .. 5
                                 -2.5     #   Subtract 2.5 so sum of average is 0
                                     :0   # Else total is 0

e:

f=(n=2)=>                                 # Start with n = 2
         r(n)                             # Roll n dice
             ?n+"\n"+f(n+2)               # If non-zero then concatenate n, newline and
                                          #    result for n+2 dice
                           :""            # If zero (average) terminate.

0

Calc2 0,7, 119 118 111 byte

using"runtime";for(n=2,d=0;d!=3.5*n;Console.WriteLine(n),n+=2)for(i=d=0;i++<n;)d+=Math.Int(Random().Next(1,7));

ungolfed:

using "runtime";
var d = 0;
var r = Random();
for(var n = 2; d != 3.5 * n; Console.WriteLine(n), n += 2)
{
    d = 0;
    for(var i = 0; i < n; i++)
        d += Math.Int(r.Next(1,7));
}

Potrei fare a meno di Math.Int () ma sfortunatamente in 0.7 le funzioni Random (). Next () hanno un bug in cui tutti restituiscono double invece di ints. È stato risolto ma solo dopo che questa domanda è stata pubblicata. Non vincerò nulla, ma hey, bella dimostrazione del concetto.

Modificare:

  • rimosso lo spazio non necessario tra l'utilizzo e "runtime" (-1 byte)

Edit2:

  • rimosso var r e crea un nuovo casuale dove è necessario (-4 byte)

  • modificato i = 0, d = 0 in i = d = 0 (-2 byte)

  • i incrementato dopo il controllo (-1 byte)


0

Rubino , 52 byte

s=x=2;(s=0;p x.times{s+=rand(6)-2.5};x+=2)while s!=0

Spiegazione

s=x=2;                                                # sum=2, x=2
      (                                  )while s!=0  # while sum != 0:
       s=0;                                           #  reset the sum
           p                                          #  print
             x.times{              };                 #  repeat x times:
                     s+=                              #   Add to sum:
                        rand(6)                       #    random int in 0..5
                               -2.5                   #    subtract average
                                                      #  (implicitly return x for printing)
                                     x+=2             #  Increment x by 2

Provalo online!


@Pakk nota la s=0parte anteriore del loop e l'uso di x.times. Ciò significa che la somma viene resettata ogni volta e quindi i xdadi vengono lanciati, il che dovrebbe essere la distribuzione corretta. Scriverò una spiegazione del mio codice.
Value Ink

Hai ragione, sono stato troppo veloce con la mia conclusione.

0

Javascript, 87 caratteri

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)alert(n)

Prova con console.loginvece di alert:

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)console.log(n)
console.log('Done')


0

lua, 102 byte

function r(n,t) for d=1,n do t=t+math.random(1,6)end return t==n*3.5 or print(n)or r(n+2,0)end r(2,0)

O la versione più leggibile

function r(n,t) --recursive function does its magic, t is given to safe usage bytes(no local)
    for d=1,n do --roll n dice and count them up to the total (t)
         t =t+math.random(1,6)
    end 
    return t==n*3.5 or --check if t==n*3.5. If it is then it ends
           print(n) or --t != n*3.5 thus print n. print returns nil
           r(n+2,0) --both the check and the return value from print are false thus r gets executed.
end 
r(2,0) --start the process

Una versione più economica per 96 byte

function r(n,t,m)t=t+m(1,6)+m(1,6)return t==n*3.5 or print(n)or r(n+2,t,m)end r(2,0,math.random)

Funziona praticamente come il primo ma riutilizza i tiri delle chiamate precedenti. Per questo motivo posso rimuovere il ciclo for. Entrambi sono testati in lua 5.2



-1

PHP, 51 byte

$r=2;$n=2;while(rand(0,6)-2.5*$r){print $n;$n=$n+2;}

Se l'output è sempre 2, questa non è una risposta valida ...

Se stampiamo $ n dentro mentre il ciclo, quindi stamperà quanto segue: 2,4,6,8,10 .....
Shiva,

2
Tuttavia, non vedo come questo segue i requisiti della domanda. Si utilizzano due variabili: "$ n" e "n". "n" non è definito, quindi verrà impostato su zero. In modo efficace, ciò che fai è stampare un numero pari e avere una probabilità di 5/6 di stampare il numero pari successivo. Questo non è matematicamente equivalente alla distribuzione nella domanda.

Errore di battitura, che n dovrebbe essere sempre 2, aggiornato il codice.
Shiva,

Ancora non si pone la domanda ... Ora stai lanciando un dado, controlla se è cinque (= 2 * 2.5); se il dado è cinque, ti fermi e se non è cinque, scrivi il prossimo numero pari e continua. Matematicamente efficacemente lo stesso di quello che hai fatto nella versione precedente del codice.
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.