introduction
Dans ce défi, vous obtenez une liste de nombres à virgule flottante non négatifs tirés indépendamment d'une certaine distribution de probabilité. Votre tâche consiste à déduire cette distribution à partir des chiffres. Pour que le défi soit réalisable, vous n'avez que cinq distributions parmi lesquelles choisir.
U
, la distribution uniforme sur l'intervalle [0,1].T
, la distribution triangulaire sur l'intervalle [0,1] avec le mode c = 1/2.B
, la distribution bêta sur l'intervalle [0,1] avec les paramètres α = β = 1/2.E
, la distribution exponentielle sur l'intervalle [0, ∞) de taux λ = 2.G
, la distribution gamma sur l'intervalle [0, ∞) avec les paramètres k = 3 et θ = 1/6.
Notez que toutes les distributions ci-dessus ont une moyenne exacte de 1/2.
La tâche
Votre entrée est un tableau de nombres à virgule flottante non négatifs, d'une longueur comprise entre 75 et 100 inclus. Votre sortie doit être l'une des lettres UTBEG
, en fonction de laquelle des distributions ci-dessus vous pensez que les nombres sont tirés.
Règles et notation
Vous pouvez donner soit un programme complet soit une fonction. Les failles standard ne sont pas autorisées.
Dans ce référentiel , il y a cinq fichiers texte, un pour chaque distribution, chacun d'une longueur exacte de 100 lignes. Chaque ligne contient une liste délimitée par des virgules de 75 à 100 flottants dessinés indépendamment de la distribution et tronqués à 7 chiffres après la virgule décimale. Vous pouvez modifier les délimiteurs pour qu'ils correspondent au format de tableau natif de votre langue. Pour être considéré comme une réponse, votre programme doit classer correctement au moins 50 listes de chaque fichier . Le score d'une réponse valide est le nombre d'octets + le nombre total de listes mal classées . Le score le plus bas l'emporte.
Réponses:
Julia,
6062 octets +252 erreurs =8264C'est assez simple. La variance pour les distributions est généralement différente - c'est 1/4 pour exponentielle, 1/8 pour beta, 1/12 pour gamma et uniforme, et 1/24 pour triangulaire. En tant que tel, si nous utilisons la variance (ici fait en utilisant
std
pour l'écart type, la racine carrée de la variance) pour déterminer la distribution probable, nous n'avons qu'à faire plus pour distinguer le gamma de l'uniforme; pour cela, nous recherchons une valeur supérieure à 1 (en utilisantany(k.>1)
) - cela dit, nous vérifions à la fois l'exponentielle et le gamma, car cela améliore les performances globales.Pour enregistrer un octet, l'indexation de la chaîne
"EGTBU"
est effectuée au lieu d'évaluer directement une chaîne dans les conditions.Pour les tests, enregistrez les fichiers txt dans un répertoire (en conservant les noms tels quels) et exécutez Julia REPL dans ce répertoire. Ensuite, associez la fonction à un nom comme
et utilisez le code suivant pour automatiser le test (il lira le fichier, le convertira en un tableau de tableaux, utilisera la fonction et affichera pour chaque incompatibilité):
La sortie consistera en lignes contenant le cas qui ne correspond pas, la distribution correcte -> la distribution déterminée et la variance calculée (par exemple,
13 G->E 0.35008999281668357
signifie que la 13e ligne dans G.txt, qui devrait être une distribution gamma, est déterminée comme étant exponentielle distribution, l'écart-type étant de 0,35008999 ...)Après chaque fichier, il affiche également le nombre de non-correspondances pour ce fichier, puis à la fin, il affiche également le total des non-correspondances (et il devrait lire 2 s'il est exécuté comme ci-dessus). Soit dit en passant, il devrait avoir 1 non-correspondance pour G.txt et 1 non-correspondance pour U.txt
la source
R,
202192184182162154154octets + 0 erreurCeci est basé sur la formule bayésienne P (D = d | X = x) = P (X = x | D = d) * P (D = d) / P (X = x), où D est la distribution et X est l'échantillon aléatoire. Nous prenons le d tel que P (D = d | X = x) est le plus grand des 5.
Je suppose un a priori plat (c'est-à-dire P (D = di) = 1/5 pour i dans [1,5]), ce qui signifie que P (D = d) dans le numérateur est le même dans tous les cas (et le dénominateur serait être le même dans tous les cas de toute façon), donc nous pouvons tout jouer au golf sauf le P (x = X | D = d), qui (à l'exception de la distribution triangulaire) se simplifie en fonctions natives dans R.
non golfé:
Notez que la version non golfée n'est pas exactement équivalente à la version golfée car se débarrasser du dénominateur évite le cas d'Inf / Inf qui se produit si vous autorisez la distribution bêta à dépasser l'intervalle fermé [0,1] au lieu de (0, 1) - comme le font les données de l'échantillon. Une instruction if supplémentaire gérerait cela, mais comme c'est à des fins d'illustration uniquement, cela ne vaut probablement pas la peine d'ajouter la complexité qui n'est pas au cœur de l'algorithme.
Merci @Alex A. pour les réductions de code supplémentaires. Surtout pour quel.max!
la source
{
et celui avant la fermeture}
, et l'aliasingprod
, par exempleP=prod
, puis le faireP(dunif(x))
, etc. La fonction n'a pas besoin d'un nom pour être une soumission valide, vous pouvez donc supprimerp=
. Aussi, excellent travail. :)which.max(c(u,r,b,e,g))
à la place 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
Le code source fait 43 octets de long et classe mal 33 listes.
Vérification
Idée
Il est facile de différencier la distribution exponentielle et gamma des autres, car ce sont les seules distributions qui prennent des valeurs supérieures à 1 .
Pour décider entre gamma , exponentielle et autres, nous examinons la deuxième valeur la plus élevée de l'échantillon.
Si elle se situe dans [1.5, ∞) , on devine gamma .
Si elle se situe dans [1, 1.5) , nous supposons exponentielle .
S'il se situe dans [0, 1) , il nous reste trois possibilités.
Les distributions restantes peuvent être différenciées par le pourcentage de valeurs d'échantillon proches de la moyenne ( 0,5 ).
Nous divisons la longueur de l'échantillon par le nombre de valeurs qui tombent dans (0,3, 0,7) et examinons le quotient résultant.
S'il se trouve dans (1, 2] , nous devinons triangulaire .
Si elle se trouve dans (2, 3] , on devine uniforme .
Si elle se trouve dans (3, ∞) , nous devinons beta .
Code
la source
Matlab,
428328 octets + 33 mal classésCe programme compare essentiellement le CDF réel avec un estimé compte tenu des données, puis calcule la distance moyenne entre ces deux: je pense que l'image explique plus:
Les données montrées dans cette image ici montrent assez clairement qu'elle appartient à la distribution turquoise, car elle est assez proche de celle-ci, c'est donc essentiellement ce que fait mon programme. Il peut probablement être joué un peu plus. Pour moi, c'était d'abord un défi conceptuel, pas très golfique.
Cette approche est également indépendante des fichiers PDF choisis, elle fonctionnerait pour n'importe quel ensemble de distributions.
Le code (non golfé) suivant devrait montrer comment cela est fait. La version golfée est ci-dessous.
Version entièrement golfée:
la source
Perl, 119 octets + 8 erreurs de classification = 127
J'ai fait un petit arbre de décision sur trois fonctionnalités:
Appelé avec
perl -F, -lane -e '...'
. Je ne sais pas si je devrais ajouter une pénalité pour les paramètres non standard. Si les virgules étaient des espaces, je suppose que j'aurais pu m'enfuir sans le -F,La sortie légèrement formatée (sans l'indicateur -l) est:
la source
Python, 318 octets + 35 erreurs de classification
Idée: la distribution est supposée basée sur la valeur de p du test de Kolmogorov-Smirnov.
Tester
la source