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]);

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.