Parada com 50% sem parada


8

Crie um programa que pare exatamente 50% do tempo. Seja original. A pergunta mais votada vence. Por exatamente, quero dizer que em cada corrida há 50% de chance de ela parar.


8
Quero dizer que deveria ter exatamente 50% de probabilidade de parar a cada corrida.
ike

3
Mas então não será Halt, Don't Halt, Halt, Don't Halt porque, com 50% de prob, você terá corridas.
Paul

5
Se o programa não parar, isso significa que ele dura para sempre? Com certeza parará quando eu desligar o PC. (A menos que seja de código NSA, então quem sabe ...)
Paul

7
Quem continua votando nessas perguntas ruins?
Gareth

4
Esta é uma boa pergunta. Somente aqueles que não entendem a probabilidade ficam confusos com isso. O título original talvez tenha sido um pouco enganador, mas não pior que o New York Times.
perfil completo de Keith Randall

Respostas:



13

Javascript

Alternativas parando e não parando. (pára na primeira corrida, não pára na segunda, ...)

var h = localStorage.halt;
while (h) localStorage.halt = false;
localStorage.halt = true;

@ Jan Oops, desculpe, corrigido. (Eu estou respondendo do meu telefone agora, então eu não posso test)
Doorknob

parece bom agora (eu ainda como a minha resposta melhor ;-))
John Dvorak

1
Não funciona no IE8 / FF3 (trolls compatibilidade)
Tyzoid

@ Tyzoid que usa FF3 de qualquer maneira? E funciona no IE8.
John Dvorak

Isso não se encaixa mais no desafio, porque é previsível.
O cara com o chapéu

13

Pitão

import random
p=.3078458
while random.random()>=p:p/=2

Cada vez que o loop é interrompido, a probabilidade diminui exponencialmente. A chance de nunca quebrar é o produto (1-p) (1-p / 2) (1-p / 4) ... que é ~ 1/2. (Comentário obrigatório sobre o ponto flutuante não ser exato.)


+1 para matemática. Isso criaria um bom problema de teste "qual é o comportamento desse código".
Primo

1
Não funciona Você não pode somar as probabilidades assim; a probabilidade real de parar é 1-3 / 4 * 7/8 * 15/16 ..., o que resulta em cerca de 42%.
User2357112 suporta Monica

1
bom, mas o comentário acima está correto: a probabilidade de não parar é P (não pára no primeiro) * P (não pára no segundo) * P (não no terceiro) * ... que tende a ~ 58%. Veja aqui para exato: wolframalpha.com/input/…
ejrb

2
começar com p=0.3078458para obter 50,00002% :)
ejrb

2
Foi mal. Probabilidade é difícil.
Keith Randall

4

GolfScript

2rand{.}do

Eu sei que este não é um desafio de , mas eu joguei de qualquer maneira. :)


Como alternativa, aqui está uma implementação do GolfScript da solução de Keith Randall :

2{2*.rand}do

Em teoria, isso terá exatamente uma probabilidade de 1/4 + 1/8 + 1/16 + ... = 1/2 de interrupção. Na prática, porém, sempre acabará a memória e a interrupção, porque o denominador fica cada vez mais longo.


4

Rubi

n = 2*rand(1...49)+1; divisors = (1...100).select{|x|n % x == 0}.count until divisors == 2
print n

Existem exatamente 24 números primos ímpares entre 0..100, o maior sendo 97. Esse algoritmo escolhe um número ímpar aleatório dentro do intervalo e se repete até encontrar um primo:

Esta implementação específica possui dois erros:

  • é utilizado um intervalo exclusivo, o que significa que 99 nunca é testado, o que significa que existem apenas 48 valores possíveis n, dos quais 24 são primos.
  • enquanto nera para ser redesenhado em cada iteração, apenas o teste primality é executado no circuito. Se a princípio não der certo, tentará novamente - mas com o mesmo número.

4

Tive vontade de jogar golfe:

Befunge - 5 caracteres

?><
@

(Não tenho certeza se isso realmente funciona, pois não tenho um compilador antes de mim)


3

BATER

#!/bin/bash
set -e
sed -i 's/true\;/false\;/' $0
while false; do echo -n ''; done;
sed -i 's/false\;/true\;/' $0

Apenas um script auto-modificado e divertido.

Nota: a string entre aspas vazia echo -n ''é apenas para maior clareza. Eles podem ser removidos sem perda de funcionalidade.


3

Geometry Dash 2.2 Editor Glitch - 2 objetos

insira a descrição da imagem aqui

Explicação:

O gatilho aleatório alterna aleatoriamente (desativa) o ID do grupo 1 ou 2 com 50% de chance.

O teclado roxo está no modo reverso (o que significa que, se o cubo tocá-lo, o cubo se move para trás, o que vai para a esquerda para todo o sempre.).

Como o bloco roxo possui o ID do grupo 2, ele tem 50% de chance de ser desativado, o que significa que o cubo pode passar por ele até o final do nível, o que será interrompido.

Como reproduzir isso:

O teclado roxo está no modo reverso e possui o ID do grupo 1.

insira a descrição da imagem aqui

Dentro do gatilho aleatório.

insira a descrição da imagem aqui



2

Solução um pouco ofuscada:

Haskell

import Control.Monad
import Control.Monad.Random         -- package MonadRandom
import Control.Monad.Trans.Maybe
import Data.Numbers.Primes          -- package primes

-- | Continue the computation with a given probability.
contWithProb :: (MonadRandom m, MonadPlus m) => Double -> m ()
contWithProb x = getRandomR (0, 1) >>= guard . (<= x)

loop :: MonadRandom m => MaybeT m ()
loop = contWithProb (pi^2/12) >> mapM_ (contWithProb . f) primes
  where
    f p = 1 - (fromIntegral p)^^(-2)

main = evalRandIO . runMaybeT $ loop

Pitão

A mesma solução expressa em Python:

import itertools as it
import random as rnd
from math import pi

# An infinite prime number generator
# Copied from http://stackoverflow.com/a/3796442/1333025
def primes():
    D = {  }
    yield 2
    for q in it.islice(it.count(3), 0, None, 2):
        p = D.pop(q, None)
        if p is None:
            D[q*q] = q
            yield q
        else:
            # old code here:
            # x = p + q
            # while x in D or not (x&1):
            #     x += p
            # changed into:
            x = q + 2*p
            while x in D:
                x += 2*p
            D[x] = p

def contWithProb(p):
    if rnd.random() >= p:
        raise Exception()

if __name__ == "__main__":
    rnd.seed()
    contWithProb(pi**2 / 12)
    for p in primes():
        contWithProb(1 - p**(-2))

Explicação

Esta solução utiliza o fato de que o produto infinito Π (1-p ^ (- 2)) converge para 6 / π ^ 2 . Isso ocorre porque ζ (2) = Π (1 / (1-p ^ (- 2))) converge para π ^ 2/6 .


2

INTERCAL , 59 bytes

DO %50 (1) NEXT
DO COME FROM COMING FROM
(1) PLEASE GIVE UP

Experimente online!

COME FROM COMING FROM faz um loop sem fim, mas há 50% de chance de pular para o final do programa.


1

TI-Basic

:Lbl 1:If round(rand):Pause:Goto 1

1
A sintaxe para round(é round(value,# of decimal places), e o segundo argumento é 9
Lirtosiast

1

C

int main() {
    char i;
    while(i&1);
}

@JanDvorak Shhhhh, não conte a todos!
meiamsome

Isso abusa do comportamento indefinido que os compiladores já quebram para otimizar o código . Portanto, para que isso tenha chances de funcionar, você não pode otimizar esse código (não que isso funcione mesmo assim, pois main, em , os registros são inicializados como 0 por razões de segurança).
Konrad Borowski


1

Perl

BEGIN {
    # Do the following block 50% of time.
    if (int rand 2) {
        # Create a function that doubles values.
        *double = sub {
            2 * shift;
        };
    }
}
double / 3 while 1; # Calculates double divided using /

Não como código de golfe, para evitar código ilegível (porque o que ele faz é mais importante). Declara aleatoriamente uma função durante a fase de compilação. Se for declarado, doubleobtém expressão regular como argumento. Se não for declarado, doubleé uma palavra de baralho, e Perl a divide por 3infinitamente. Isso abusa da análise de palavras de barras do Perl, para que o analisador analise o mesmo código de duas maneiras diferentes.


1

<> <, 5 bytes e um belo quadrado 2x2

x;
><

xenvia o ponteiro da instrução em uma direção aleatória; Se enviar para a esquerda ou direita, o IP será atingido; e terminar. Se subir ou descer, o IP ficará preso no ><loop infinito , sendo enviado para frente e para trás entre os dois.


ele não é chamado <><tho, ele é chamado ><>lol (a menos que há um chamado <><eu não ouvi de)
Sagitário

você também pode economizar 1 byte removendo o <(porque o ponteiro envolve); não será mais um quadrado 2x2, mas será bem jogado c:
Sagitário

1

Java

import java.io.*;

public class HaltNoHalt {
    public static void main(String[] args) throws Exception {
        RandomAccessFile f = new RandomAccessFile("HaltNoHalt.java", "rw");
        f.seek(372);
        int b = f.read();
        f.seek(372);
        f.write(b ^ 1);
        Runtime.getRuntime().exec("javac HaltNoHalt.java");

        while ((args.length & 1) == 1);
    }
}

Esta auto-modifica o código para alternar o == 1para == 0e volta, cada vez que ele é executado. Salve o código apenas com novas linhas ou o deslocamento estará errado.

O args.lengthé apenas para evitar otimizações do compilador.


0

Exatamente 50% do tempo?

OBJ-C

- (void)applicationDidFinishLaunching:(NSNotification*)aNotification {
    BOOL haltedLastRun = [(NSNumber*)[[NSUserDefaults standardUserDefaults] objectForKey:@"halted"] boolValue];
    if (!haltedLastRun) {
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"halted"];
        [[NSApplication sharedApplication] terminate:nil];
    }
}

0

Haskell

É executado por dois intervalos, cada um com 1 segundo de duração (escolhido porque 1 segundo é a unidade SI para o tempo). Pára dentro de 50% dos intervalos. Portanto, 50% dos segundos em execução não serão interrompidos, os outros 50% serão interrompidos. Funciona apenas no GHC.

import Control.Concurrent (threadDelay)
main = threadDelay 1990000

0

Shell Script

esse script clobber arquivos .md5sum nos diretórios atual e filho.

#!/bin/sh
echo *.md5sum|xargs -n1|head -n1|xargs test -e && exec rm *.md5sum
while ! find . -name '*.md5sum' -print0 |xargs -0r grep 00000000000000
do {
    find . -type f -print|sed -e 's!^\(.*\)$!md5sum "\1" > "\1".md5sum!e'
}
done

0

GTB

[@r;p;]

Eu sei que isso não é código-golfe, mas eu decidi jogar de qualquer maneira.


0

C ++

#include <fstream>
main () {
    int c;
    std::fstream fs;
    fs.open ("myfile.txt", std::fstream::in);
    fs>>c;
    fs.close ();
    fs.open ("myfile.txt", std::fstream::out);
    fs<<c+1;
    fs.close ();
    while (c%2);
    return 0;
}

Cada corrida será interrompida se a corrida anterior não o fizer.


0

Script de Comando do Windows

Esse script anexará o código a si mesmo, que alterna 'x' em cada execução.

call :last
if %x%==1 (
    echo>>%0 set x=0
    exit /b 0
) else (
    echo>>%0 set x=1
)
:nohalt
goto :nohalt
:last
set x=1
[newline here]

0

Java

import java.util.Random;

class Halt50 {
    public static void main(String[] args){
        if(new Random().nextInt(2)==0)for(;;);
    }
}


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.