Probabilidade 1 / N


29

Porque não existem desafios simples de simples o suficiente :

Crie um programa ou função opcionalmente sem nome que, dado (por qualquer meio) um número inteiro 1 ≤ N ≤ 10000, produz o valor True do seu idioma com uma probabilidade pseudo-aleatória de 1 / N, caso contrário, False.

Observe que o requisito de nomeação foi removido. Sinta-se livre para editar respostas e pontuações de acordo.

Alguns idiomas usam 1 (ou -1) e 0 para Verdadeiro e Falso, isso também é bom.

Exemplo:

Testes de entrada de exemplo:

4 -> True
4 -> False
4 -> False
4 -> False
4 -> False
4 -> True
4 -> False
4 -> False

Ou seja, dado 4; retorna True com 25% de chance e False com 75% de chance.




Como nem todas as línguas incorporam "pseudo-aleatoriedade", é possível obter uma semente como segundo argumento? (Eg Brainfuck)
— flawr

@flawr use current milissegundos ...
— Adám

11
Qual é o maior Nque temos que aceitar?
— Toby Speight

Respostas:


27

Modelos do MediaWiki com ParserFunctions , 48 bytes

{{#ifexpr:1>{{#time:U}} mod {{{n}}}|true|false}}

13
Escolha interessante do idioma :-)
— Adám

6
Quem diabos pensou que seria sensato adicionar funções não determinísticas aos modelos do MediaWiki !?
— user253751

4
@immibis: assim o não-determinismo ocorre a partir #time, provavelmente para atualizar a idade das pessoas que vivem, etc.
— Willem Van Onsem

15

Pitão, 3 bytes

!OQ

Experimente online

Inversão simples de escolha aleatória de 0 a entrada

Divertidamente no Pyth, não é possível criar uma função que faça isso sem, $porque as funções do Pyth são automaticamente memorizadas.



@LeakyNun Ah, claro, eu tinha esquecido de usar o tempo para uma função aleatória, isso é bastante inteligente.
— FryAmTheEggman

Não, eu apenas usei o tempo para remover a memória.
— Leaky Nun

11
Estou ciente, acho que simplesmente não escrevi bem: P Isso disse que eu não acho que funcionaria realmente como uma solução alternativa para a maioria dos envios, se fosse melhor do que um programa completo por algum motivo. Tomar o tempo como argumento provavelmente não é apenas permitido por padrão.
— FryAmTheEggman

11
@LeakyNun Eu acredito que esta questão é anterior ao Qpreenchimento no final, caso contrário eu teria respondido !O;)
— FryAmTheEggman

12

CJam, 5 bytes

Tem que ser rápido com esses ...

rimr!

Teste aqui.

Explicação

ri e# Read input and convert to integer N.
mr e# Get a uniformly random value in [0 1 ... N-1].
!  e# Logical NOT, turns 0 into 1 and everything else into 0.

11
" Tem que ser rápido com esses ... ", o que é uma razão para discordar do OP de que " não existem desafios simples de código-golfe " suficientes . Se o FGITW é um problema, o IMO é muito simples.
— Peter Taylor

12

TI-BASIC, 4 bytes usando tokens de um byte

not(int(Ansrand

Determina se a parte inteira da entrada multiplicada por um número aleatório em [0,1) é zero. Ansrand<1também funciona.


Como ... são quatro bytes?
— John Dvorak

3
@JanDvorak Os primeiros bytes não são (, o próximo é int (, o próximo é Ans, o próximo é rand. Em geral, calculadoras gráficas não usam ASCII como sua representação interna para programas.
— user253751

@immibis Em geral, os computadores também não usam ASCII. Isso pode ser questionável, existe uma meta discussão sobre isso?
— Kroltan

7
@Kroltan Yes; essa é a meta discussão e esta é a lista de tokens de um byte, que inclui todos os quatro que eu usei.
— lirtosiast

@ThomasKwa thanks!
— Kroltan

11

MATL, 5 bytes

Três versões diferentes desta, todas de comprimento 5.

iYr1=

que pega uma entrada ( i), gera um número inteiro aleatório entre 1 e esse número ( Yr) e vê se é igual a 1 ( 1=). Alternativamente,

li/r>

faça um 1 ( l, uma solução alternativa porque existe um erro ao fazer 1ino momento), pegue uma entrada ( i), divida para obter 1 / N ( /), faça um número aleatório entre 0 e 1 ( r) e veja se o aleatório número é menor que 1 / N. Ou,

ir*1<

take e input ( i) e multiplique por um número aleatório entre 0 e 1 ( r*) e veja se o resultado é menor que 1 ( 1<).

No Matlab, não no MATL, você pode executar esta função anônima

@(n)n*rand<1

por 12 bytes, usado por ans(5)exemplo, por exemplo.


10

JavaScript ES6, 15 bytes

-5 bytes graças ao Downgoat.

x=>1>new Date%x

Baseado nos usos da técnica desta resposta.


11
new Datetambém pode funcionar e pode salvar alguns bytes #
— Downgoat

@Downgoat Ah, certo, aleatoriedade da data!
— Conor O'Brien

10

Julia, 17 16 15 bytes

n->2>rand(1:n)

Essa é uma função que gera um número inteiro aleatório entre 1 e ntesta se é menor que 2. Haverá uma chance de 1 / n disso acontecer e, portanto, uma chance de 1 / n de retornar true.

Guardado 1 byte graças a Thomas Kwa!


9

Microscript II , 3 bytes

NR!

Lê um número inteiro n, gera um número inteiro aleatório entre 0e n-1(inclusive) e aplica uma negação booleana a esse valor.


8

Doce , 2 bytes

Hn

H significa Heisen-double

n significa não

O 'n' é passado com o sinalizador -i como entrada numérica. Os valores deixados na pilha são impressos na saída.

"Forma longa:

rand   # number between 0 and pop()
not    # cast to int, invert non-zero to zero, and zero to one

Eu acho que você precisaria contar -icomo um byte.
— lirtosiast

11
basicamente, a única maneira de passar a entrada numérica é com o sinalizador -i. Eu acho que apenas idiomas que lêem stdin não sofrem penalidade de especificação de entrada?
— Dale Johnson

Bem, se houvesse um sinalizador de entrada genérico ou você apenas usasse CLAs regulares para passar argumentos, isso definitivamente seria bom. Parece injusto que o tipo de dados esteja sendo especificado gratuitamente, no entanto.
— lirtosiast

2
@ThomasKwa Uma função escrita em uma linguagem dinâmica deve contar os bytes para especificar que o argumento é um número inteiro na documentação? Em lambda x: random.random()<1/x(não destruído) também é "especificado gratuitamente" que o argumento é um número.
— user253751

@immibis Hmm, esse é um bom argumento. Acho que tentar manter as regras para programas e funções iguais deve permitir isso, então. Vou fazer um post na meta.
— lirtosiast

7

Sério, 3 bytes

,JY

0é falsey e 1é verdade. Experimente online

Explicação:

,JY
,    get input
 J   push a random integer in range(0, input) ([0, ..., input-1])
  Y  logical not: push 0 if truthy else 1  

7

R, 30 22 bytes

código

cat(runif(1)<1/scan())          #new
f=function(N)cat(runif(1)<1/N)  #old

Ele gera um número a partir de uma distribuição uniforme (0 a 1) e deve ser avaliado como verdadeiro 1 / n das vezes.


6

Japonês, 6 bytes

1>U*Mr

Experimente online!

Mré equivalente a JS Math.random. O resto é bastante óbvio. Provavelmente eu poderia adicionar uma função numérica que gera uma flutuação aleatória entre 0 e o número. Quando isso acontece, dois bytes serão salvos:

1>Ur    // Doesn't currently work

Versão alternativa:

1>Ð %U

Ðé equivalente a new Date(, e o objeto Date, quando solicitado a converter em um número, se torna o carimbo de data / hora atual em milissegundos. Portanto, isso é inteiramente aleatório, a menos que seja executado várias vezes por ms.


6

Marbelous , 21 bytes

}0    # takes one input n
--    # decrements n
??    # random value from range 0..n (inclusive)
=0?0  # push right if not equal to 0, fall through otherwise | convert to zero
++    # increment | no-op
{0//  # output | push left

Eu tomei 0a ser Falsey e 1ser truthy, embora não há nenhuma razão real para que, vendo como Marbelous realmente não tem um caso. Mais Marbelousy seria produzido para{0 para verdadeiro e {>falso. Isso ficaria assim:

}0
--
??
=0{>
{0

Mas não tenho certeza se isso é válido.


Eu gostaria de uma meta discussão sobre isso. Versão curta da minha visão: gerar um valor para uma saída diferente equivale a ter tuplas de saída diferentes em outro idioma. Se (nil, 1) e (1, nil) podem ser seus valores de verdade e falsey em outro idioma, então {0 vs {> deve ser permitido no Marbelous. PS: sua versão {> não será encerrada porque você nunca preenche a outra saída.
— Sparr

@ Esparrá sairá por inatividade, não?
— overactor

Você está certo. Eu me sinto estúpido.
— Sparr

6

APL, 6 3 bytes

+=?

Este é um trem de funções que pega um número inteiro e retorna 1 ou 0 (verdadeiro / falso do APL). Geramos um número inteiro aleatório de 1 para a entrada usando e ?, em seguida, verificamos se a entrada é igual a esse número inteiro. Isso resulta em uma chance de 1 / entrada de verdade.

Economizou 3 bytes graças a Thomas Kwa!


@ThomasKwa Pensei em algum tipo de trem, mas isso realmente conta como uma "função nomeada" se atribuído? Eu acho que a parte "nomeada" está me jogando aqui, já que é atípica.
— Alex A.

@ThomasKwa A atribuição de trens (e funções derivadas) é completamente paralela a todas as outras atribuições.
— Adám

@NBZ o que você quer dizer com paralelo?
— lirtosiast

@ThomasKwa Equivalente; comportando-se como qualquer outra atribuição de função.
— Adám

Eu usaria em ⊢vez de '+' porque +significa Conjugar para números complexos. É claro que não importa aqui, e +é a função tradicional de identidade (não operacional), mas agora temos ⊢(o mesmo). Outras no-ops para escalares são: ⌷(materializar), ⊃(escolher), ⊂(incluir), ↑(dividir), ↓(misturar), ∪(exclusivo), ∊(alistar), ,(ravel), ⍪(tabela), ⌽(reverso), ⊖(reverso) primeiro) e ⍉(transpor). Alguns alteram o escalar em um vetor ou matriz.
— Adám

6

PlatyPar , 3 bytes

#?!

#?obtém um número aleatório [0,n)onde né inserido. !retorna truese o número anterior0 , caso contrário, ele retorna false.

Usando os recursos mais recentes que foram implementados (mas infelizmente não comprometidos) antes que essa pergunta fosse feita, posso reduzi-lo a 2 com ~! Experimente online !


5

Java, 43 bytes

boolean b(int a){return a*Math.random()<1;}

11
a->a*Math.random()<1é mais curto.
— TheNumberOne

Deve especificar "Java 7 ou anterior".
— corsiKa

@corsiKlauseHoHoHo Isso também funciona no Java 8
— #

11
Claro que sim - mas não é um jogo de golfe para o Java 8, que usaria lambdas para economizar espaço. Por essa lógica, todas as respostas Java também são respostas Groovy, mas o Groovy é sempre o mesmo ou menor, pois possui atalhos que o Java não possui.
— corsiKa

5

C, 24 bytes

f(n){return!(rand()%n);}

Revirei a edição do OP removendo os 4 primeiros caracteres. É bom ter bytes reduzidos, mas para mim, ter o returnsem o f(n)não faz nenhum sentido sintaticamente.
— Level River St

11
@insertusernamehere rand()%né uma maneira padrão de obter um número aleatório no intervalo 0..n-1. Você está correto, ele depende de nser muito menor do que RAND_MAXmas não há limite superior nmencionado na pergunta. Uma abordagem alternativa seria rejeitar e repetir todos os números de naté RAND_MAX, mas seria irremediavelmente ineficiente em pequena escala n.
— Level River St

5

> <>, 27 + 3 para -v = 30 bytes

Aqui está uma solução não uniforme onde eu modifique N a soma de 15876 escolhas aleatórias de 0 ou 1:

0"~":*>:?vr%0=n;
1-$1+$^-1x

N deve ser inserido na pilha com o sinalizador -v, a saída é 0 para falsey e 1 para verdade.

Uma solução muito mais inteligente e uniforme, que funciona por 1/2 ^ N:

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n;
1n;>
 

Para uma entrada 3, você tem 1/8 de chance de obter 1 e 7/8 de obter 0.

Explicação:

Anexo o quanto xfor necessário na quarta linha e os cerco com instruções para que haja apenas duas maneiras de sair x: a saída falsey ou a próxima x. Se tudo xfor na direção certa, o último encaminhará para a saída de verdade.

Por exemplo, para N = 5, o espaço de código final é o seguinte:

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n; > > > > >
1n;>x>x>x>x>x>
    ^ ^ ^ ^ ^

Embora seja verdade que você não pode obter uma distribuição perfeita para N arbitrário, ninguém mais pode usar um PRNG. Você pode percorrer um xa algumas vezes para obter um monte de bits aleatórios, montá-los em um int I e usar I% N como seu valor aleatório.
— Sparr

O @Sparr editou minha resposta, mas eu sinto que o uso de um grande número de iterações 'calculará a média' do número inteiro resultante, fazendo com que a saída tenda bastante (iterNum/2)%N. Eu não acho que usar um número menor também seria uma solução. Talvez eu não tenha entendido bem você, ou você teria alguma idéia para melhorar a solução?
— Aaron

em vez de adicionar 15000 bits, produza apenas 32 bits e concatene-os, fornecendo um número inteiro aleatório de 32 bits uniformemente distribuído. mod isso.
— Sparr

@ Parr que parece realmente melhor, mesmo que eu não tenha idéia do porquê;) Isso vai custar muito mais bytes (> <> é péssimo para operações de bytes e conversão de base), mas vou mudar minha resposta esta noite (CEST).
— Aaron #

você pode concatenar bits multiplicando por dois e adicionando: r = 0; para (0..32) r = r * 2 + randbit;
— Sparr

4

Mathematica, 18 16 bytes

#RandomReal[]<1&

Solução básica. O sem nome Functioncria um número aleatório em [0, 1), multiplica-o por seu argumento e verifica se ainda é menor que 1.


4

Python, 42 bytes

import random
lambda n:1>random.random()*n

Editar : a time.time()resposta foi removida devido à distribuição.


2
Pois randomvale a pena from random import*economizar random.. Não por timeenquanto.
— xnor

11
Os números aleatórios gerados pela divisão do módulo não são distribuídos uniformemente .
— Trang Oul

@TrangOul Esse é um bom ponto; para maior, no efeito pode ser perceptível. Eu acho que 1>time.time()%1*npoderia funcionar.
— lirtosiast

@TrangOul Presumo que você saiba a diferença entre randC e time.timePython ... Uma característica óbvia do último é que ele retorna o tempo atual , que é ilimitado, para que time.time()%ntenha uma distribuição uniforme (por períodos de tempo suficientemente longos) para qualquer n.
— user253751

4

TeaScript , 3 bytes

!N×

Experimente aqui.

Explicação

 N  maps to Math.rand which is a utility function that returns an integer
    between `arg1` and `arg2` or `0` and `arg1` if only one argument is
    provided.
  × is expanded to `(x)`, where `x` is initialised with the value provided
    in the input boxes; × represents byte '\xd7'
!   negate the result, 0 results in true, anything else false

11
Como sete caracteres somam 6 bytes? E o (R) um (ANT byte) char?
— Adám

@NBZ, haha! Acho que menti ... culpo a ressaca ... vou atualizar agora, pois vou mudar o mecanismo para um mais direto que acabei de perceber! Nesta versão atual, ®representa o caractere, '\xae'portanto, é apenas um byte. :)
— Dom Hastings

4

Fuzzy Octo Guacamole, 10 bytes

^-!_[0]1.|

Explicação:

^-!_[0]1.|

^          # Get input.
 -         # Decrement, so we can append <ToS> zeros and a 1 to the stack.
  !        # Set loop counter.
   _       # Pop, since we are done with the input.
    [      # Start loop
     0     # Push 0
      ]    # End for loop. We have pushed input-1 0s to the stack.
       1   # Push a single 1 to the stack.
        .  # Switch stacks
         | # Pick a random item from the inactive stack, which has n-1 falsy items and 1 truthy item, so the truthy probability is 1/n.
           # (implicit output)

3

Perl 6 ,  10   8 bytes

!(^*).pick
#  ^- The * is the argument

Este código cria um intervalo de 0 até, mas excluindo a entrada *. Então ele pické um aleatoriamente e !retorna True quando recebe a 0.

1>*.rand
# ^- The * is the argument

Isso pega a entrada *e a multiplica por um Num aleatório a partir de 0..^1então retorna True se fosse menor que 1.

# store it in a lexical code variable for ease of use
my &code = 1>*.rand;

die "never dies here" unless code 1;

for ^8 { say code 4 }
False
True
False
False
False
True
False
False

3

Prolog (SWI), 24 bytes

Código:

p(N):-X is 1/N,maybe(X).

talvez (+ P) é uma função que obtém sucesso com a probabilidade P e falha com a probabilidade 1-P

Exemplo:

p(4).
false

p(4).
false

p(4).
true

3

PowerShell, 25 bytes

!(Random -ma($args[0]--))

A Get-Randomfunção quando recebe um -Maparâmetro ximum nretorna um valor do intervalo [0,n). Aproveitamos isso ao subtrair 1 de nossa entrada $args[0], para que possamos indexar corretamente zero e obter um valor aleatório. Precisamente 1/nna época, esse valor será 0, portanto, quando Booleano - e não com !ele, ele retornará True. Os outros horários retornarão False.


3

J, 3 bytes

0=?

Este é um garfo monádico que leva um argumento à direita. Da mesma forma que APL,? gera um número inteiro aleatório; no entanto, as matrizes J são baseadas em zero. Então, comparamos com 0 em vez de com a entrada.



3

PHP, 22 bytes

<?=2>rand(1,$argv[1]);

Lê nna linha de comando, como:

$ php probability.php 4

Outputs ( falseé convertido para uma string vazia no PHP) ou 1(no caso de true).


3

C #, 56 45 bytes

Graças a, pinkfloydx33, são 45 agora.

bool b(int n){return new Random().Next(n)<1;}

56 bytes antigos

Gera um número inteiro positivo aleatório maior ou igual a 0 e menor que ne verifica se é menor que 1e retorna o resultado da comparação.

bool a(int n){Random r=new Random();return r.Next(n)<1;}

11
Bem-vindo ao PPCG! Infelizmente, esse envio não funciona, porque Random.Next(k)retorna um número inteiro kcomo esse 0 <= k < n. Alterando a condição para <1, estará correto. Além disso, o uso de uma expressão lambda pode diminuir o seu código.
— Mego

@Ego claro, obrigado por comentar. Eu fiz 0 < k <= ne deve ser como você disse. Eu vou corrigi-lo imediatamente.
— Ivaan

2
O uso var rsalva três. Ou, se for o c # 6, bool a(int n) => new Random().Next(n)<1;para 41. Embora não tenha certeza se a inicialização de uma nova Randomchamada por método funcionará corretamente na distribuição?
— precisa

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.