Isso acabará parando ...


41

Dada uma sequência de entrada S, imprima Sseguida por um separador não vazio da seguinte maneira:

  • Etapa 1: Stem a 1/2chance de ser impressa e a 1/2chance de o programa terminar.

  • Etapa 2: Stem uma 2/3chance de ser impressa e uma 1/3chance de o programa terminar.

  • Etapa 3: Stem a 3/4chance de ser impressa e a 1/4chance de o programa terminar.

  • ...

  • Etapa n: Stem a n/(n+1)chance de ser impressa e a 1/(n+1)chance de o programa terminar.

Notas

  • A sequência de entrada será composta apenas por caracteres aceitáveis ​​no tipo de sequência do seu idioma.

  • Qualquer separador não vazio pode ser usado, desde que seja sempre o mesmo. Espera-se que o separador seja impresso após a última impressão Santes de o programa terminar.

  • O programa pode 1/2terminar antes de imprimir qualquer coisa.

  • Uma nova linha à direita é aceitável.

  • Sua resposta deve fazer uma tentativa genuína de respeitar as probabilidades descritas. Obviamente, quando nfor grande, isso será cada vez menos verdadeiro. Uma explicação adequada de como as probabilidades são computadas em sua resposta (e por que elas respeitam as especificações, desconsiderando problemas de pseudo-aleatoriedade e grandes números) é suficiente.

Pontuação

Isso é , então a resposta mais curta em bytes vence.


O separador pode ser uma sequência vazia?
rturnbull

16
@rturnbull Bem, não, porque nesse caso não há separador.
Fatalize

Temos que imprimi-los um após o outro, ou podemos apenas imprimi-los quando o programa terminar?
217 Dennis

@ Dennis Um após o outro.
Fatalize

Respostas:


18

Pitão , 7 bytes

WOh=hZQ

Experimente online!

Como funciona

Pseudo-código:

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

Pyth bate 05AB1E novamente, não é?
Erik the Outgolfer

A declaração de impressão não precisa de sua própria probabilidade juntamente com a probabilidade de rescisão?
tuskiomi

11
@tuskiomi Nah, n / (n + 1) é apenas 1-1 / (n + 1) ou 1 - (probabilidade de rescisão).
Adowrath

29

C #, 94 85 bytes

Minha primeira resposta!

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

Tentativa anterior (gostei disso 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: em C # o Random.Next(N)método retorna um número inteiro não negativo no intervalo [0, N-1], para que possamos apenas verificar se o número retornado é maior que 0.


11
Você precisa incluir using System;na sua contagem de bytes. Você pode declarar rem linha, sem necessidade de defini-lo como uma variável: new Random().Next(i++). Você não precisa do ponto e vírgula à direita na função do golfe.
TheLethalCoder

11
Ah, e boa primeira resposta! Teria sido mais curto do que a minha tentativa :)
TheLethalCoder

@TheLethalCoder obrigado por seus comentários! Eu tentei usar, new Random().Next(i++)mas quando tentei executar isso, o resultado sempre foi: o programa para sem imprimir nada ou o programa nunca para. Quando declaro r=new Random()e uso a rvariável, o programa para de forma mais aleatória conforme o OP pede.
Charlie

Ahhh probs porque o loop é muito apertado.
TheLethalCoder

2
@TheLethalCoder - Sim, thight loop significa uma chance de que a semente do gerador seja a mesma. Consulte: msdn.microsoft.com/en-us/library/system.random.aspx#Instantiate
Erno

12

R, 47 46 43 bytes

43 bytes devido a Robin Ryder nos comentários.

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

Experimente online!

Explicação

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

Isso já termina?
mfloren

@mfloren Sim, como todas as outras respostas aqui, é estocástico, com a chance de término diminuindo à medida que avança, mas acabará terminando. Há uma chance de 0,5 de imprimir nada! Tente executá-lo várias vezes e compare as saídas.
rturnbull

function(s)é mais curto ques=scan(,'');
JAD

11
E pryr::f(while(runif(1)<T/(T<-T+1))print(s))é ainda mais curto.
JAD

11
@JarkoDubbeldam Infelizmente você não pode (ab) usar Te Fcom funções anônimas, pois modifica uma variável global e significa que a função pode ser chamada apenas uma vez. Veja aqui : "a função solução executa de maneira consistente, independentemente de quantas vezes foi chamada anteriormente".
rturnbull

11

05AB1E , 8 bytes

[NÌL.R#,

Experimente online!

Explicação

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

@Fatalize: Faz para mim. Tente executá-lo algumas vezes. Ele tem 50% de chance de não gerar nada, então você pode ter sido "azarado".
Emigna

11
O problema herdado de tarefas aleatórias. Às vezes, todas as probabilidades estão contra você.
J_F_B_M 12/06

@J_F_B_M inerente?
Leaky Nun

11
@LeakyNun Não, é o "Herdar problema" (a probabilidade de eventos não é herdada de eventos anteriores). J_F_B_M estava claramente se referindo à falácia do jogador.
aebabis

11

Javascript, 60 58 54 bytes

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

Produzirá a string s. O separador que é impresso se o programa terminar é NaNou 0.

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

f('test')

Math.random()retorna um valor entre 0 e 1. Se esse valor estiver abaixo n/(n+1), sserá premido.

4 bytes salvos graças a @Neil


11
Por que não usar n/++n?
Neil

11
@ Neil obrigado, salvou 4 bytes!
Thomas W

2
Se o ambiente era um navegador que você poderia usar alertem vez de console.logsalvar 6 bytes - o trecho poderia definir alert = console.logpara mostrar produção não intrusivos se desejado (se for permitido - não salva bytes, apenas ajuda a manter um sã)
Craig Ayre

10

Java 8, 72 62 61 bytes

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

-10 bytes graças a @cliffroot .
-1 byte graças a @JollyJoker .

Delimitador é uma nova linha.

Explicação:

Experimente aqui.

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
não consigo fazer o check-in no momento, mas por que não colocar a ifcondição dentro do forbloco de condições?
Cliffroot

@cliffroot Ele é no forcircuito.
Okx

11
@Okx eu quis dizer condição quando o forloop deve terminar para que ele não precise explícito return. A segunda expressão dentro de for statement.
Cliffroot

@cliffroot Ah, eu entendo.
Okx

11
Seria int n=2e 1f/n++funcionaria?
jollyjoker

9

Mathematica, 43 bytes

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

JungHwan Min salvou 1 byte (acima) e sugeriu algo melhor (abaixo)

Mathematica, 37 bytes

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

11
RandomInteger@n!=0é o mesmo que RandomInteger@n<1neste caso e n++pode ser mesclado com RandomInteger@n. Além disso, Foré (quase sempre) mais curto do que While: -5 bytesFor[n=1,RandomInteger@n++>0,Print@#]&
JungHwan Min

"For" vence! Também postei sua resposta
J42161217

For[n=1,!n∣Hash[# n++],Print@#]&também funcionaria com 34 bytes, assumindo que o hash seja bastante aleatório. A aleatoriedade depende da entrada, no entanto. Por exemplo, tente% /@ Alphabet[]
Kelly Lowder

8

Clojure, 61 56 bytes

Oh, por que eu não fui com um forem primeiro lugar? Mas, na verdade, ser pedante doseqdeve ser usado como foré avaliado preguiçosamente.

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

Original:

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

nem (>(+(rand-int n)2)0)sempre é verdade?
Cliffroot

Ah boa captura, eu pretendia incrementar n!
NikoNyrh

8

> <> , 124 112 bytes

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

Experimente online! (Você também pode assisti-lo no playground de peixes , mas devido a alguns erros, é necessário adicionar um }depois do lna quarta linha e adicionar várias linhas novas após o código para fazê-lo funcionar corretamente.)

A aleatoriedade é complicada em> <>. A única instrução aleatória é x, que escolhe a direção do peixe aleatoriamente entre quatro opções (esquerda, direita, para cima e para baixo), de modo que transformar isso em algo com probabilidade 1 / n não é simples.

Da maneira que esse código faz, é usando os recursos de autod modificação de> <> para criar uma Torre de Aleatoriedade abaixo do código; portanto, no quarto estágio, por exemplo, o código se parece com:

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

O peixe começa na parte inferior da torre. Em cada nível da torre, a xarmadilha fica presa entre dois espelhos, de modo que o peixe só pode escapar indo para a esquerda ou direita. Qualquer uma dessas direções envia o peixe para o próximo nível da torre, mas ir para a esquerda também empurra um 0para a pilha. Quando o peixe chega ao topo da torre, a pilha contém algum número de se 0esse número segue uma distribuição binomial com n tentativas ep  = 1/2.

Se o comprimento da pilha for 0 (com probabilidade 1/2 n ), o programa será interrompido. Se o comprimento for 1 (com probabilidade n / 2 n ), o peixe imprime a entrada e uma nova linha e constrói outro nível da torre. Se o comprimento for qualquer outra coisa, o peixe descarta a pilha e volta para o fundo da torre. De fato, dentre as possibilidades que realmente fazem algo, n delas imprimem a sequência de entrada e uma delas interrompe o programa, fornecendo as probabilidades necessárias.


7

Python 3 , 72 69 66 bytes

  • Economizou 3 bytes graças a Jonathan Allan : importe taquigrafia e comece a contar a partir de 2.
  • Economizou 3 bytes graças ao L3viathan : O randint apontado () foi inclusivo e também encurtado durante a condição.
from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

Experimente online!


11
Há uma configuração para desativar o cache de saída - como assim
Jonathan Allan

2
Eu acho que é aceitável estar "desligado" para n grande (não consigo entender o cérebro inglês) "... (e por que eles respeitam as especificações, desconsiderando problemas de pseudo-aleatoriedade e grandes números) ..." desconsiderando - certo?) Se sim, então você pode fazer random()<1/i.
Jonathan Allan

11
Isso não começa com probabilidade ⅓? randinté inclusivo. Você pode então encurtar a linha parawhile randint(0,i):print(s);i+=1
L3viathan

11
Eu apenas vim com a mesma solução.
Esolanging Fruit

Link TIO atualizado. Agora, a contagem de bytes também é a mesma da versão em ponto flutuante.
Jonathan Allan

6

QBIC , 19 17 bytes

Descartados =1, condicionais comutados, salvos 2 bytes

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

Explicação

{       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 bytes

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

Experimente online!

Gera um número aleatório em xque 0 <= x < n+1, termina se xfor 0, caso contrário, incrementos ne loops. Separador é|

Explicação:

#|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 bytes

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

Experimente online!

Explicação

/     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

Carvão , 14 bytes

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

Experimente online! Link é a versão detalhada do código. Usa _como separador. Nota: o cache de saída está desativado; portanto, não martele o servidor de Dennis!


3

MATL , 9 bytes

`G@QYrq]x

Experimente online!

Explicação

`        % 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

Perl 6 ,  50 41 38 36  26 bytes

{put $_//last for (($,$_),*⊎$_...*).map(*.pick)}

Tente

{eager ->{(++$).rand>.5??.put!!last}...*}

Tente

{eager ->{(++$).rand>.5??.put!!0}...0}

Tente

{eager ->{(++$).rand>.5&&.put}...!*}

Tente

.put while (++$/).rand>.5

(com -nargumento da linha de comando)

Tente


3

Python 3 , 55 bytes

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

Explicação

Para evitar a importação aleatória, explorei o fato de que o hash interno é aleatoriamente propagado toda vez que um processo python é iniciado (pelo menos no MacOS). Cada hash do último hash deve gerar uma série de números inteiros pseudo-aleatórios.

Se o hash é pseudo-aleatório o suficiente, o módulo com ié zero com probabilidade 1/i.

Notas

Estou um pouco incomodado com o hash redundante, mas sem uma atribuição de tempo de permanência ou condição no Python, estou um pouco preso.


Você sabe se o hash iterado sempre cobre todo o espaço de números aleatórios ou pode ficar preso em um ciclo? Atualmente, a maioria das linguagens de programação usa algoritmos aleatórios de hash para evitar pessoas causando intencionalmente colisões de hash, mas não tenho certeza de como as garantias de aleatoriedade dos algoritmos de hash se comparam com as de um PRNG.

É um ponto justo. E não tenho certeza, seria necessária alguma análise da implementação do hash Python para verificar (sem uma verificação mais exaustiva). Eu pensei que era uma solução divertido, mesmo se há uma chance que pode não ser 100% pseudo-aleatório = p
Kit Ham

I'm a little bothered...recursão?
Felipe Nardi Batista

3

C #

Este é o mesmo tamanho da resposta C # principal, mas:

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

Só queria salientar que alguma matemática pode produzir a probabilidade correta.

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

É equivalente a

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

E a função f (x) = 1 / x-1 é:

f (1) = 0

f (1/2) = 1

f (1/3) = 2

f (1/4) = 3

Portanto, 1/2 chance de ser arredondado para 0, 1/6 de chance de ser arredondado para 1 e 1 / (n + 1) (n + 2) uma chance de ser arredondado para n.

Talvez alguma outra linguagem possa tirar proveito disso.

EDIT: Corrigido meu erro

Pensei em algo para torná-lo menor.

Editar edição: eu estou apenas todos os tipos de errado. Puxou o Random para fora do loop, porque se ele for avaliado várias vezes, não funcionará.

Editar edição editar: me livrei da variável i. Vou parar de tentar diminuir agora. Não, menti. Livre-se de outro byte.



2

C, 41 bytes

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

Assume que randé semeado. Experimente online!


"Supõe que randé semeado." - Isso é uma suposição válida a ser feita? randé exigido pelo padrão para ter um valor fixo inicial de 1 por padrão e todas as implementações que conheço fazem exatamente isso. Se essa função fizer apenas o que o desafio pede quando combinado com outro código, acho que outro código precisa ser incluído na resposta e na contagem de bytes.
hvd 13/06

2

braingasm , 22 bytes

editar: Contagem de mesmos bytes, mas percebi que podia me infiltrar no novo Lrecurso de imitação de fita .

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

Usa 0como separador. Funciona assim:

,[>,]                   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 bytes

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

Experimente online!

Gerado o número de cópias como floor(1/p)-1com puniformemente escolhido a partir do intervalo de unidade. O número de cópias é nquando 1/p-1cai entre ne n+1, o que acontece quando 1/(n+2) < p < 1/(n+1). Isso acontece com probabilidade 1/(n+1)-1/(n+2)ou 1/((n+1)*(n+2). Esta é a probabilidade desejada de produzir ncópias: 1/2prob de 0, 1/6prob de 1, 1/12prob de 2, ...


Por que está form random import*no fundo?
CalculatorFeline

@CalculatorFeline O pedido não importa. A definição da função funciona de qualquer maneira.
Xnor

@CalculatorFeline Para cair para bytes por não escrever f=e colocando-o no cabeçalho TIO
Mr. Xcoder

Isso faz sentido.
CalculatorFeline

2

C ++, 97 96 57 bytes

Aqui minha primeira tentativa no codegolf :)

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

Salvei um byte usando for

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

Economizou 39 bytes, já que ninguém parece contar as inclusões

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

destroçado

#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());    
}

Você pode tomar a string como um argumento da linha de comando
Maliafo

Inclui são contados, a menos que você encontrar um compilador que inclui-los por padrão
Felipe Nardi Batista

2

F #, 161 bytes

Definitivamente não é o melhor idioma para o golfe, mas decidi tentar (além disso, não sei nada sobre F #, portanto, qualquer dica sobre como melhorar minha resposta será bem-vinda).

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

Executar com:

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

Grava uma nova linha como separador.



2

JS (ES6), 47 bytes

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

Diferentemente da outra resposta do ES6, ele usa bombas for loop e alert em vez de recursão. O separador que é impresso quando o programa para é indefinido.



1

Python, 75 bytes

A outra resposta do Python é mais curta, mas eu queria tentar de uma maneira diferente:

from random import*
f=lambda d=1,s=input():randint(0,d)and s+'!'+f(d+1)or''
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.