Questo alla fine si fermerà ...


41

Data una stringa di input S, stampa Sseguita da un separatore non vuoto nel modo seguente:

  • Passaggio 1: Sha la 1/2possibilità di essere stampato e 1/2il programma può essere chiuso.

  • Passaggio 2: Sha la 2/3possibilità di essere stampato e 1/3il programma può essere chiuso.

  • Passaggio 3: Sha la 3/4possibilità di essere stampato e 1/4il programma può terminare.

  • ...

  • Passaggio n: Sha la n/(n+1)possibilità di essere stampato e 1/(n+1)il programma può terminare.

Gli appunti

  • La stringa di input sarà composta solo da caratteri accettabili nel tipo di stringa della tua lingua.

  • È possibile utilizzare qualsiasi separatore non vuoto, purché sia ​​sempre lo stesso. Si prevede che il separatore venga stampato dopo l'ultima stampa Sprima che il programma termini.

  • Il programma 1/2potrebbe terminare prima di stampare qualsiasi cosa.

  • Una nuova riga finale è accettabile.

  • La tua risposta deve fare un autentico tentativo di rispettare le probabilità descritte. Ovviamente, quando nsarà grande, sarà sempre meno vero. È sufficiente una spiegazione adeguata di come vengono calcolate le probabilità nella tua risposta (e perché rispettano le specifiche, ignorando la pseudo-casualità e i problemi dei grandi numeri).

punteggio

Questo è , quindi vince la risposta più breve in byte.


Il separatore può essere una stringa vuota?
rturnbull,

16
@rturnbull Beh no, perché in quel caso non c'è un separatore.
Fatalizza il

Dobbiamo stamparli uno dopo l'altro o possiamo semplicemente stamparli tutti al termine del programma?
Dennis,

@Dennis Uno dopo l'altro.
Fatalizza il

Risposte:


18

Pyth , 7 byte

WOh=hZQ

Provalo online!

Come funziona

pseudocodice:

while rand_int_below(1 + (Z += 1)):
    print(input)

Pyth batte di nuovo 05AB1E, vero?
Erik the Outgolfer,

L'istruzione print non ha bisogno della propria probabilità insieme alla probabilità di terminazione?
tuskiomi,

1
@tuskiomi Nah, n / (n + 1) è solo 1-1 / (n + 1) o 1 - (probabilità di terminazione).
Adowrath,

29

C #, 94 85 byte

La mia prima risposta!

using System;s=>{var r=new Random();for(var i=2;r.Next(i++)>0;)Console.Write(s+" ");}

Tentativo precedente (mi è piaciuto goto):

using System;s=>{var i=2;var r=new Random();a:if(r.Next(i++)>0){Console.Write(s+" ");goto a;}}

Ungolfed:

using System;
class P
{
    static void Main()
    {
        Action<string> f = s =>
        {
            var r = new Random();
            for (var i = 2; r.Next(i++) > 0;) Console.Write(s + " ");
        };

        f("test");

        Console.ReadKey();
    }
}

Nota: in C # il Random.Next(N)metodo restituisce un numero intero non negativo nell'intervallo [0, N-1], quindi possiamo solo verificare che il numero restituito sia maggiore di 0.


1
Devi includere using System;nel conteggio dei byte. È possibile dichiarare rin linea, non c'è bisogno di impostare ad una variabile: new Random().Next(i++). Non è necessario il punto e virgola finale sulla funzione golf.
TheLethalCoder

1
Oh e bella prima risposta! Sarebbe stato più breve del mio tentativo :)
TheLethalCoder il

@TheLethalCoder grazie per i tuoi commenti! Ho provato ad usare new Random().Next(i++)ma quando ho provato ad eseguirlo, il risultato è sempre stato il programma si ferma senza stampare nulla, oppure il programma non si ferma mai. Quando dichiaro r=new Random()e utilizzo la rvariabile, il programma si interrompe in modo più casuale come richiesto dall'OP.
Charlie,

Ahhh probs perché il ciclo è così stretto.
TheLethalCoder

2
@TheLethalCoder - Sì, l'anello thight significa che il seme del generatore sarà lo stesso. Vedi: msdn.microsoft.com/en-us/library/system.random.aspx#Instantiate
Erno

12

R, 47 46 43 byte

43 byte dovuti a Robin Ryder nei commenti.

s=scan(,"")
while(sample(T<-T+1)-1)print(s)

Provalo online!

Spiegazione

s=scan(,"")  # Takes input from stdin.
             T<-T+1    # T is 1 by default, so this
                       # evaluates to 2, and will increment
                       # at each step.
      sample(T<-T+1)   # Take a sample of size 2, i.e. generate
                       # a list of integers from 1 to 2 in random order
      sample(T<-T+1)-1 # Subtract one from every element of this list.
while(sample(T<-T+1)-1)# while() will treat the first value in this list
                       # as a logical value, i.e. FALSE for zero and TRUE
                       # for nonzero values. The other elements of the list
                       # are ignored, triggering a warning.
                       print(s) # print s

Questo finisce mai?
mfloren,

@mfloren Sì, come tutte le altre risposte qui, è stocastica, con possibilità di terminazione che diminuisce man mano che avanza, ma alla fine si interromperà. C'è una possibilità .5 di non stampare nulla! Prova a eseguirlo più volte e confronta gli output.
rturnbull,

function(s)è più corto dis=scan(,'');
JAD il

1
Ed pryr::f(while(runif(1)<T/(T<-T+1))print(s))è ancora più breve.
JAD,

1
@JarkoDubbeldam Purtroppo non è possibile (ab) utilizzare Te Fcon funzioni anonime, poiché modifica una variabile globale e significa che la funzione può essere chiamata una sola volta. Vedi qui : "la funzione di soluzione funziona costantemente indipendentemente da quante volte è stata chiamata in precedenza".
rturnbull,

11

05AB1E , 8 byte

[NÌL.R#,

Provalo online!

Spiegazione

[         # start loop
 NÌL      # push range [1 ... current_iteration+2]
    .R    # pick a random number
      #   # if true (1), exit loop
       ,  # print input

@Fatalize: lo fa per me. Prova a eseguirlo alcune volte. Ha una probabilità del 50% di non produrre nulla, quindi potresti essere stato "sfortunato".
Emigna,

11
Il problema ereditario di compiti casuali. A volte tutte le probabilità sono contro di te.
J_F_B_M il

@J_F_B_M inerente?
Leaky Nun,

1
@LeakyNun No, è il "Problema ereditario" (la probabilità degli eventi non è ereditata dagli eventi precedenti). J_F_B_M si riferiva chiaramente all'errore del giocatore.
aebabis,

11

Javascript, 60 58 54 byte

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

Emetterà una stringa s. Il separatore che viene stampato al termine del programma è NaNo 0.

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

f('test')

Math.random()restituisce un valore compreso tra 0 e 1. Se tale valore è inferiore n/(n+1), sverrà stampato.

4 byte salvati grazie a @Neil


1
Perché non usare n/++n?
Neil,

1
@Neil grazie, risparmiato 4 byte!
Thomas W,

2
Se il tuo ambiente fosse un browser che potresti utilizzare alertinvece di console.logsalvare 6 byte - lo snippet potrebbe essere impostato alert = console.logper mostrare un output non invadente se lo desideri (se consentito - non salva byte, aiuta solo a mantenere un buon senso)
Craig Ayre

10

Java 8, 72 62 61 byte

s->{for(int n=2;Math.random()<1f/n++;System.out.println(s));}

-10 byte grazie a @cliffroot .
-1 byte grazie a @JollyJoker .

Delimitatore è una nuova linea.

Spiegazione:

Provalo qui.

s->{                          // Method with String parameter and no return-type
  for(                        //  Loop
    int n=2;                  //   Start `n` on 2
    Math.random()<1f/n++;     //   Continue loop as long as a random decimal (0.0-1.0)
                              //   is smaller than 1/`n` (and increase `n` by 1 afterwards)
    System.out.println(s)     //   Print the input-String
  );                          //  End of loop
}                             // End of method

2
non riesco a controllare al momento, ma perché non mettere la ifcondizione all'interno del forblocco delle condizioni?
cliffroot,

@cliffroot Si è nel forciclo.
Okx,

1
@Okx intendevo condizione in cui il forciclo dovrebbe terminare in modo che non abbia bisogno di esplicito return. La seconda espressione dentro per dichiarazione.
cliffroot,

@cliffroot Ah, ho capito.
Okx,

1
Funzionerebbe int n=2e 1f/n++funzionerebbe?
JollyJoker,

9

Mathematica, 43 byte

(n=1;While[RandomInteger@n>0,Print@#;n++])&

JungHwan Min ha salvato 1 byte (sopra) e ha suggerito qualcosa di meglio (sotto)

Mathematica, 37 byte

For[n=1,RandomInteger@n++>0,Print@#]&

1
RandomInteger@n!=0è lo stesso RandomInteger@n<1di questo caso e n++può essere unito a RandomInteger@n. Inoltre, Forè (quasi sempre) più corto di While: -5 byteFor[n=1,RandomInteger@n++>0,Print@#]&
JungHwan Min

"Per" vince! Ho pubblicato anche la tua risposta
J42161217

For[n=1,!n∣Hash[# n++],Print@#]&funzionerebbe anche a 34 byte, supponendo che l'hash sia abbastanza casuale. La casualità dipende dall'input, tuttavia. Ad esempio, prova% /@ Alphabet[]
Kelly Lowder il

8

Clojure, 61 56 byte

Oh, perché non sono andato con un forin primo luogo? Ma in realtà essere pedanti doseqdeve essere usato come forè valutato pigramente.

#(doseq[n(range):while(>(rand-int(+ n 2))0)](println %))

Originale:

#(loop[n 2](if(>(rand-int n)0)(do(println %)(recur(inc n)))))

non è (>(+(rand-int n)2)0)sempre vero?
cliffroot,

Ah buona cattura, intendevo incrementare n!
NikoNyrh,

8

> <> , 124 112 byte

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^

Provalo online! (Puoi anche guardarlo nel parco giochi dei pesci , ma a causa di alcuni bug devi aggiungere un }after-the lnella quarta riga e aggiungere un sacco di nuove righe dopo il codice per farlo funzionare correttamente.)

La casualità è complicata in> <>. L'unica istruzione casuale è x, che seleziona la direzione del pesce in modo casuale da quattro scelte (sinistra, destra, su e giù), quindi trasformarlo in qualcosa con probabilità 1 / n non è semplice.

Il modo in cui lo fa questo codice è usando le capacità di auto-modifica di> <> per costruire una Torre di casualità sotto il codice, quindi nella quarta fase, ad esempio, il codice appare come:

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\

Il pesce inizia nella parte inferiore della torre. Ad ogni livello della torre, xè intrappolato tra due specchi, quindi il pesce può scappare solo andando a sinistra o a destra. Ognuna di queste direzioni invia il pesce al livello successivo della torre, ma andando a sinistra spinge anche una 0pila. Quando il pesce raggiunge la cima della torre, la pila contiene un certo numero di 0s, e questo numero segue una distribuzione binomiale con n prove e p  = 1/2.

Se la lunghezza della pila è 0 (che ha probabilità 1/2 n ), il programma si interrompe. Se la lunghezza è 1 (con probabilità n / 2 n ), il pesce stampa l'ingresso e una nuova linea e costruisce un altro livello della torre. Se la lunghezza è qualcos'altro, il pesce scarta la pila e ritorna sul fondo della torre. In effetti, tra le possibilità che effettivamente fanno qualcosa, n di loro stampa la stringa di input e uno di loro ferma il programma, fornendo le probabilità richieste.


7

Python 3 , 72 69 66 byte

  • Salvato 3 byte grazie a Jonathan Allan : importa stenografia e inizia il conteggio da 2.
  • Salvato 3 byte grazie a L3viathan : Pointed randint () era inclusivo e anche abbreviato mentre condizione.
from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

Provalo online!


1
C'è un'impostazione per disattivare la cache di output - in questo modo
Jonathan Allan il

2
Penso che sia accettabile essere "off" per i grandi n (non riesco a mettere in marcia il cervello inglese, "... (e perché rispettano le specifiche, ignorando la pseudo-casualità e i problemi dei grandi numeri) ..." ignorando - giusto?) Se è così, allora puoi farlo random()<1/i.
Jonathan Allan,

1
Questo non inizia con probabilità ⅓? randintè inclusivo. Potresti quindi abbreviare quella linea awhile randint(0,i):print(s);i+=1
L3viathan,

1
Ho appena trovato la stessa soluzione.
Esolanging Fruit,

Collegamento TIO aggiornato. Ora il conteggio dei byte è uguale anche alla versione in virgola mobile.
Jonathan Allan,

6

QBIC , 19 17 byte

=1Condizionati rilasciati , commutati, salvati 2 byte

{p=p+1~_rp||?;\_X

Spiegazione

{       Infinitely DO
p=p+1   Add 1 to p (p starts as 0, so on first loop is set to 1, then 2 etc...)
~       IF
  _rp|| a random number between 0 and p
        (implicitly: is anything but 0)
?;      THEN print A$ (which gets read from the cmd line)
\_X     ELSE QUIT
        END IF and LOOP are auto-added at EOF

6

Braingolf , 23 byte

#|V12[R!&@v!r?<1+>1+]|;

Provalo online!

Genera un numero casuale xdove 0 <= x < n+1, termina se xè 0, altrimenti incrementi ne cicli. Il separatore è|

Spiegazione:

#|V12[R!&@v!r?<1+>1+]|;  Implicit input of commandline args to stack
#|                       Push |
  V                      Create stack2 and switch to it
   12                    Push 1, then 2
     [..............]    Do-While loop, will run indefinitely unless conditional skips
                         Closing bracket
      R                  Return to stack1
       !&@               Print entire stack without popping
          v              Switch to stack2
           !r            Generate random number 0 <= x < n where n is last item on stack
             ?           If last item is greater than 0..
              <          ..Move first item to end of stack
               1+        ..and increment, this is the loop counter number
                 >       ..Move back
                  1+     ..and increment, this is the upper range of the RNG
                    ]    ..end loop
                     |   Endif
                      ;  Suppress implicit output

6

Alice , 18 byte

/?!\v
\iO/>]qhUn$@

Provalo online!

Spiegazione

/     Reflect to SE. Switch to Ordinal.
i     Read all input as a string and push it to the stack.
!     Store the string on the tape.
/     Reflect to E. Switch to Cardinal.
>     Ensure that the IP moves east. This begins the main loop.

  ]   Move the tape head to the right. We'll be using the tape head's 
      position as a counter variable. Note that this tape head is independent
      of the one used in Ordinal mode to point at the input string.
  q   Push the tape head's position to the stack.
  h   Increment it (so that it's 2 initially).
  U   Get a uniformly random number in [0,n).
  n   Logical NOT. Gives 1 with probability 1/n and 0 otherwise.
  $@  Terminate the program if we got a  1.
  \   Reflect to NE. Switch to Ordinal.
  ?   Retrieve the input from the tape.
  O   Print it with a trailing linefeed.
  \   Reflect to E. Switch to Cardinal.

v     Send the IP south where it runs into the > to start the next
      loop iteration.



3

Carbone , 14 byte

A²γW‽γ«θ_A⁺γ¹γ

Provalo online! Il collegamento è alla versione dettagliata del codice. Utilizza _come separatore. Nota: la cache di output è disabilitata, quindi per favore non martellare il server di Dennis!


3

MATL , 9 byte

`G@QYrq]x

Provalo online!

Spiegazione

`        % Do...while
  G      %   Push input
  @      %   Push iteration index k, starting at 1
  QYrq   %   Random integer uniformly distributed in {0, 1, ..., k}. This is the
         %   loop condition. If non-zero (which occurs with probability k/(1+k))
         %   proceed with next iteration; else exit loop
]        % End
x        % Delete, as there are one too many strings. Implicitly display the stack


3

Python 3 , 55 byte

v=s=input();i=2
while hash(v)%i:print(s);i+=1;v=hash(v)

Spiegazione

Per evitare di dover importare casualmente, ho sfruttato il fatto che l'hash incorporato viene seminato casualmente ogni volta che viene avviato un processo Python (almeno in MacOS). Ogni hash dell'ultimo hash dovrebbe generare una serie di numeri interi pseudo-casuali.

Se l'hash è abbastanza pseudo-casuale, il modulo con iè zero con probabilità1/i .

Gli appunti

Sono un po 'infastidito dall'hash ridondante, ma senza un pò di tempo, o un incarico in condizione in Python, sono un po' bloccato.


Sai se l'hash iterato coprirà sempre l'intero spazio di numeri casuali o potrebbe potenzialmente rimanere bloccato in un ciclo? La maggior parte dei linguaggi di programmazione utilizza oggi algoritmi di hash randomizzati per evitare che le persone causino intenzionalmente collisioni di hash, ma non sono sicuro di come le garanzie di casualità degli algoritmi di hash siano paragonabili a quelle di un PRNG.

È un punto giusto. E non sono sicuro, ci vorrebbe qualche analisi dell'implementazione dell'hash Python per verificare (senza un controllo più esaustivo). Ho pensato che fosse una soluzione divertente, anche se c'è una possibilità che potrebbe non essere pseudo-casuale al 100% = p
Kit Ham

I'm a little bothered...ricorsione?
Felipe Nardi Batista,

3

C #

Questa è la stessa lunghezza della risposta C # principale, ma:

using System;s=>{var x=(1<<31)/new Random().Next();for(;++x>0;)Console.Write(s+" ");}

Volevo solo sottolineare che alcuni matematici possono produrre la probabilità corretta.

int.MaxValue/new Random().Next()-1

È equivalente a

(int)(1 / new Random().NextDouble()) - 1;

E la funzione f (x) = 1 / x-1 è:

f (1) = 0

f (1/2) = 1

f (1/3) = 2

f (1/4) = 3

Quindi 1/2 possibilità di arrotondare per difetto a 0, 1/6 possibilità di arrotondamento per difetto a 1 e 1 / (n + 1) (n + 2) possibilità di arrotondamento per difetto a n.

Forse un'altra lingua potrebbe trarre vantaggio da questo.

EDIT: risolto il mio errore

Ho pensato a qualcosa per renderlo più piccolo.

MODIFICA MODIFICA: ho sbagliato tutti i tipi. Estratto il Casuale dal ciclo perché se viene valutato più volte, non funzionerà.

EDIT EDIT EDIT: mi sono liberato della variabile i. Adesso smetterò di provare a ridurlo. No, ho mentito. Sbarazzarsi di un altro byte.



2

C, 41 byte

n;f(char*s){for(n=1;rand()%++n;puts(s));}

Presuppone randè seminato. Provalo online!


"Presuppone randè seminato." - È un presupposto valido da fare? randè richiesto dallo standard di avere un valore seed fisso pari a 1 per impostazione predefinita e tutte le implementazioni che conosco fanno proprio questo. Se questa funzione fa solo quello che la sfida richiede quando combinata con altro codice, penso che sia necessario includere altro codice nella risposta e nel conteggio dei byte.
hvd,

2

Braingasm , 22 byte

edit: Stesso numero di byte, ma mi sono reso conto che potevo intrufolarmi nella nuova Lfunzione di imitazione del nastro .

,[>,]>L+[+$rzQ>[.>]:>]

Utilizza 0come separatore. Funziona così:

,[>,]                   Read a byte and move to next cell until end of input.
     >                  After the loop we're in an empty cell;
                          Leave it empty and move to the next.
      L                 Set tape limit here:
                          The tape will then wrap around if we move further.
       +                Increase current cell by one.
                          This cell will be our counter.
        [            ]  Loop until the counter is zero.
                          That won't happen, so it's an infinite loop.
         +              Increase again, so the first time the counter is 2.
          $r            Get a random number, 0 <= r > current cell
            zQ          Quit the program if that random number was 0
              >         Wrap around to the start of the tape.
               [.>]     Print the input stored on the tape
                          The loop will stop at the blank cell.
                   :    Print the blank cell as a number ("0")
                    >   Go to the next (last) cell

2

Python , 54 byte

lambda s:int(1/random()-1)*(s+'|')
from random import*

Provalo online!

Generato il numero di copie floor(1/p)-1con puniformemente scelto nell'intervallo unitario. Il numero di copie è nquando 1/p-1cade tra ne n+1, che avviene quando 1/(n+2) < p < 1/(n+1). Questo succede con probabilità 1/(n+1)-1/(n+2)o 1/((n+1)*(n+2). Questa è la probabilità desiderata di produrre ncopie: 1/2prob di 0, 1/6prob di 1, 1/12prob di 2, ...


Perché è form random import*in fondo?
Calcolatrice

@CalculatorFeline L'ordine non ha importanza. La definizione della funzione funziona in entrambi i modi.
xnor

@CalculatorFeline Per passare ai byte non scrivendoli f=e posizionandoli nell'intestazione TIO
Mr. Xcoder

Ciò ha senso.
Calcolatrice

2

C ++, 97 96 57 byte

Ecco il mio primo tentativo su codegolf :)

#include<iostream>
int main(){std::string S;std::cin>>S;int i=1;while(rand()%++i)puts(S.data());}

Ho salvato un byte usando for

#include<iostream>
int main(){std::string S;std::cin>>S;for(int i=1;rand()%++i;)puts(S.data());}

Salvato 39 byte poiché nessuno sembra contare le inclusioni

void p(string S){for(int i=1;rand()%++i;)puts(S.data());}

ungolfed

#include <iostream>
int main()
{
  // Create and read string from inputstream
  std::string S;
  std::cin >> S;       

  // rand % i: create random int in range [0, i-1]
  // Zero is seen as false and all positive int as true
  int i = 1;
  while (rand() % ++i) 
    puts(S.data());    
}

Puoi prendere la stringa come argomento dalla riga di comando
Maliafo,

Le conteggi vengono conteggiate, a meno che non trovi un compilatore che le include per impostazione predefinita
Felipe Nardi Batista,

2

F #, 161 byte

Sicuramente non è la lingua migliore per giocare a golf, ma ho deciso di provarlo (inoltre, non so nulla di F #, quindi qualsiasi consiglio su come migliorare la mia risposta sarà il benvenuto).

let f s=
 let r,z=System.Random(),(<>)0
 let p _=printfn"%s"s
 seq {for i in 2|>Seq.unfold(fun i->Some(i,i+1))do yield r.Next(i)}|>Seq.takeWhile z|>Seq.iter p

Eseguire con:

[<EntryPoint>]
let main argv =
    "test" |> f
    0

Scrive una nuova riga come separatore.



2

JS (ES6), 47 byte

x=>{for(i=1;Math.random()<i/(i+1);i++)alert(x)}

A differenza dell'altra risposta ES6, questa utilizza bombe per loop e di allerta anziché ricorsione. Il separatore che viene stampato all'arresto del programma non è definito.



1

Python, 75 byte

L'altra risposta di Python è più breve, ma volevo provarla in un modo diverso:

from random import*
f=lambda d=1,s=input():randint(0,d)and s+'!'+f(d+1)or''
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.