Introdução
Neste desafio, você recebe uma lista de números de pontos flutuantes não negativos, desenhados independentemente de alguma distribuição de probabilidade. Sua tarefa é inferir essa distribuição a partir dos números. Para viabilizar o desafio, você tem apenas cinco distribuições para escolher.
U
, a distribuição uniforme no intervalo [0,1].T
, a distribuição triangular no intervalo [0,1] com o modo c = 1/2.B
, a distribuição beta no intervalo [0,1] com os parâmetros α = β = 1/2.E
, a distribuição exponencial no intervalo [0, ∞) com taxa λ = 2.G
, a distribuição gama no intervalo [0, ∞) com os parâmetros k = 3 e θ = 1/6.
Observe que todas as distribuições acima têm média exatamente 1/2.
A tarefa
Sua entrada é uma matriz de números de ponto flutuante não negativo, com comprimento entre 75 e 100 inclusive. Sua saída deve ser uma das letras UTBEG
, com base em qual das distribuições acima você acha que os números são sorteados.
Regras e Pontuação
Você pode dar um programa completo ou uma função. As brechas padrão não são permitidas.
Em este repositório , há cinco arquivos de texto, uma para cada distribuição, cada um exatamente 100 linhas longas. Cada linha contém uma lista delimitada por vírgula de 75 a 100 carros alegóricos, desenhados independentemente da distribuição e truncados para 7 dígitos após o ponto decimal. Você pode modificar os delimitadores para corresponder ao formato de matriz nativa do seu idioma. Para se qualificar como resposta, seu programa deve classificar corretamente pelo menos 50 listas de cada arquivo . A pontuação de uma resposta válida é contagem de bytes + número total de listas classificadas incorretamente . A pontuação mais baixa vence.
Respostas:
Julia,
6062 bytes +252 erros =8264Isto é bastante simples. A variação para as distribuições é principalmente diferente - é 1/4 para exponencial, 1/8 para beta, 1/12 para gama e uniforme e 1/24 para triangular. Como tal, se usarmos variação (aqui feita usando
std
o desvio padrão, a raiz quadrada da variação) para determinar a distribuição provável, precisamos apenas fazer mais para distinguir gama de uniforme; para isso, procuramos um valor maior que 1 (usandoany(k.>1)
) - ou seja, fazemos a verificação tanto exponencial quanto gama, pois isso melhora o desempenho geral.Para salvar um byte, a indexação da sequência
"EGTBU"
é feita em vez de a avaliação direta de uma sequência dentro dos condicionais.Para testar, salve os arquivos txt em um diretório (mantendo os nomes como estão) e execute o Julia REPL nesse diretório. Em seguida, anexe a função a um nome como
e use o código a seguir para automatizar o teste (isso será lido no arquivo, convertido em uma matriz de matrizes, use a função e a saída para cada incompatibilidade):
A saída consistirá em linhas contendo o caso que não corresponde, a distribuição correta -> a distribuição determinada e a variação calculada (por exemplo,
13 G->E 0.35008999281668357
significa que a 13ª linha em G.txt, que deve ser uma distribuição gama, é determinada como exponencial distribuição, com o desvio padrão de 0,35008999 ...)Depois de cada arquivo, ele também gera o número de incompatibilidades para esse arquivo e, no final, também exibe o total de incompatibilidades (e deve ler 2 se executado como acima). Aliás, ele deve ter 1 incompatibilidade para G.txt e 1 incompatibilidade para U.txt
fonte
R,
202 192 184 182 182 162154 bytes + 0 errosIsso é baseado na fórmula bayesiana P (D = d | X = x) = P (X = x | D = d) * P (D = d) / P (X = x), onde D é a distribuição e X é a amostra aleatória. Escolhemos d de modo que P (D = d | X = x) seja o maior dos 5.
Suponho que um plano anterior (ie P (D = di) = 1/5 para i em [1,5]), o que significa que P (D = d) no numerador seja o mesmo em todos os casos (e o denominador seria seja o mesmo em todos os casos, de qualquer maneira), para que possamos jogar fora tudo, exceto P (x = X | D = d), que (exceto a distribuição triangular) simplifica as funções nativas em R.
ungolfed:
Observe que a versão sem golf não é exatamente equivalente à versão com golf, porque se livrar do denominador evita o caso de Inf / Inf, que ocorre se você permitir que a distribuição beta ultrapasse o intervalo fechado [0,1] em vez de (0, 1) - como fazem os dados da amostra. Uma instrução if adicional lidaria com isso, mas como é apenas para fins ilustrativos, provavelmente não vale a pena adicionar a complexidade que não está no coração do algoritmo.
Obrigado @Alex A. pelas reduções adicionais de código. Especialmente para qual.max!
fonte
{
e a antes do fechamento}
e o aliasprod
, por exemploP=prod
, executandoP(dunif(x))
, etc. A função não precisa de um nome para ser um envio válido, para que você possa removerp=
. Além disso, excelente trabalho. :)which.max(c(u,r,b,e,g))
no lugar dec(u,r,b,e,g)==max(c(u,r,b,e,g))
.function(x){c("U","T","B","E","G")[which.max(lapply(list(dunif(x),sapply(x,function(y)max(0,2-4*abs(.5-y))),dbeta(x,.5,.5),dexp(x,2),dgamma(x,3,6)),prod))]}
CJam, 76
O código-fonte tem 43 bytes e classifica incorretamente 33 listas.
Verificação
Idéia
É fácil diferenciar a distribuição exponencial e gama das demais, pois são as únicas distribuições que assumem valores maiores que 1 .
Para decidir entre gama , exponencial e outras, vamos dar uma olhada no segundo valor mais alto da amostra.
Se estiver em [1.5, ∞) , supomos gama .
Se estiver em [1, 1.5) , supomos exponencial .
Se estiver em [0, 1) , temos três possibilidades restantes.
As demais distribuições podem ser diferenciadas pela porcentagem de valores amostrais próximos da média ( 0,5 ).
Dividimos o comprimento da amostra pela contagem de valores que se enquadram em (0,3; 0,7) e examinamos o quociente resultante.
Se estiver em (1, 2] , supomos triangular .
Se estiver em (2, 3] , achamos uniforme .
Se estiver em (3, ∞) , supomos beta .
Código
fonte
Matlab,
428328 bytes + 33 classificados incorretamenteEste programa está basicamente comparando o CDF real com um estimado, considerando os dados, e calculando a distância média entre os dois: acho que a imagem explica mais:
Os dados mostrados nesta imagem aqui mostram claramente que pertencem à distribuição turquesa, pois é muito próxima dessa, portanto é basicamente o que meu programa está fazendo. Provavelmente pode ser jogado um pouco mais. Para mim, esse foi, antes de tudo, um desafio conceitual, não muito disputado.
Essa abordagem também é independente dos pdfs escolhidos, funcionaria para qualquer conjunto de distribuições.
O código a seguir (não protegido) deve mostrar como isso é feito. A versão golfada está abaixo.
Versão totalmente golfe:
fonte
Perl, 119 bytes + 8 classificações incorretas = 127
Fiz uma pequena árvore de decisão em três recursos:
Invocado com
perl -F, -lane -e '...'
. Não tenho certeza se devo adicionar uma penalidade para os parâmetros não padrão. Se as vírgulas fossem espaços, acho que poderia ter escapado sem o -F,A saída ligeiramente formatada (sem o sinalizador -l) é:
fonte
Python, 318 bytes + 35 classificações incorretas
Idéia: a distribuição é calculada com base no valor-p do teste de Kolmogorov-Smirnov.
Teste
fonte