A propos de la série
Je vais lancer une petite série de défis de code-golf autour du thème du hasard. Ce sera essentiellement un parcours de golf de 9 trous , mais divisé en plusieurs questions. Vous pouvez participer à n'importe quel défi individuellement, comme s'il s'agissait d'une question normale.
Cependant, je maintiendrai un classement dans tous les défis. La série se déroulera sur 9 défis (pour le moment), un posté tous les deux ou trois jours. Chaque utilisateur qui participe aux 9 défis est éligible pour gagner la série complète. Leur score global est la somme des soumissions les plus courtes sur chaque défi (donc si vous répondez deux fois à un défi, seule la meilleure réponse compte pour le score). Si quelqu'un occupe la première place de ce classement général pendant 28 jours, je lui attribuerai une prime de 500 reps .
Bien que de nombreuses idées soient en préparation pour la série, les défis à venir ne sont pas encore figés. Si vous avez des suggestions, veuillez me le faire savoir sur le message du bac à sable correspondant .
Trou 1: Mélangez un tableau
La première tâche est assez simple: mélangez-le aléatoirement avec un tableau d'entiers non vide. Il y a quelques règles cependant:
- Toutes les permutations possibles doivent être retournées avec la même probabilité (le brassage devrait donc avoir une distribution uniforme). Vous pouvez vérifier si votre algorithme est uniforme / non biaisé en l'implémentant en JavaScript dans Will it Shuffle , ce qui produira une matrice des biais - le résultat devrait être aussi uniforme que celui intégré dans Fisher-Yates ou être trié (ordre aléatoire) .
- Vous ne devez utiliser aucune méthode intégrée ou tierce partie pour mélanger le tableau ou générer une permutation aléatoire (ou énumérer toutes les permutations). En particulier, la seule fonction aléatoire intégrée que vous pouvez utiliser consiste à obtenir un seul nombre aléatoire à la fois . Vous pouvez supposer que toute méthode de nombre aléatoire intégrée s'exécute en O (1) et est parfaitement uniforme sur l'intervalle demandé (au sens mathématique - vous pouvez ignorer les détails de la représentation en virgule flottante ici). Si votre langue vous permet d’obtenir simultanément une liste de m nombres aléatoires, vous pouvez utiliser cette fonction, à condition que les m nombres soient indépendants les uns des autres et que vous les comptiez comme O (m).
- Votre implémentation ne doit pas dépasser une complexité temporelle de O (N) , où N est la taille de la matrice à mélanger. Par exemple, vous ne pouvez pas "trier par nombres aléatoires".
- Vous pouvez soit mélanger le tableau à la place, soit créer un nouveau tableau (auquel cas l'ancien tableau peut être modifié à votre guise).
Vous pouvez écrire un programme complet ou une fonction et effectuer une entrée via STDIN, un argument de ligne de commande, un argument de fonction ou une invite et produire une sortie via une valeur de retour ou en imprimant sur STDOUT (ou son alternative la plus proche). Si vous écrivez une fonction qui mélange le tableau en place, vous n'avez évidemment pas besoin de la renvoyer (à condition que votre langue vous permette d'accéder au tableau modifié après le retour de la fonction).
Les entrées et les sorties peuvent se présenter sous n'importe quelle liste ou format de chaîne, mais doivent prendre en charge des entiers quelconques compris dans la plage -2 31 ≤ x <2 31 . En principe, votre code devrait fonctionner pour les tableaux d'une longueur maximale de 2 à 31 , bien que cela ne doive pas nécessairement être enregistré dans votre mémoire ou terminé dans un délai raisonnable. (Je ne veux tout simplement pas voir des limites de taille arbitraires pour les boucles en code fixe ou quelque chose du genre.)
C'est le code de golf, donc la soumission la plus courte (en octets) gagne.
Classement
L'extrait suivant générera un classement pour tous les défis de la série.
Pour vous assurer que vos réponses apparaissent, commencez chaque réponse par un titre, en utilisant le modèle Markdown suivant:
# Language Name, N bytes
où N
est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores en les effaçant. Par exemple:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(La langue n'est pas affichée pour le moment, mais l'extrait de code nécessite une analyse syntaxique. Il se peut que j'ajoute un classement par langue ultérieurement.)
/* Configuration */
var QUESTION_IDs = [45302, 45447, 46991, 49394, 51222, 66319, 89621, 120472]; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!.FjwQBrX2KXuFkv6p2lChi_RjzM19";
/* App */
var answers = [], page = 1, currentQ = -1;
function answersUrl(index) {
return "https://api.stackexchange.com/2.2/questions/" + QUESTION_IDs.join(";") + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}
function getAnswers() {
$.ajax({
url: answersUrl(page++),
method: "get",
dataType: "jsonp",
crossDomain: true,
success: function (data) {
answers.push.apply(answers, data.items);
if (data.has_more) getAnswers();
else process();
}
});
}
getAnswers();
var SIZE_REG = /\d+(?=[^\d&]*(?:<(?:s>((?!>).)*<\/s>|((?!>).)+>)[^\d&]*)*$)/;
var NUMBER_REG = /\d+/;
var LANGUAGE_REG = /^#*\s*([^\n,]+)(?=,)/;//
function shouldHaveHeading(a) {
var pass = false;
var lines = a.body_markdown.split("\n");
try {
pass |= /^#/.test(a.body_markdown);
pass |= ["-", "="]
.indexOf(lines[1][0]) > -1;
pass &= LANGUAGE_REG.test(a.body_markdown);
} catch (ex) {}
return pass;
}
function shouldHaveScore(a) {
var pass = false;
try {
pass |= SIZE_REG.test(a.body_markdown.split("\n")[0]);
} catch (ex) {}
if (!pass) console.log(a);
return pass;
}
function getAuthorName(a) {
return a.owner.display_name;
}
function getAuthorId(a) {
return a.owner.user_id;
}
function process() {
answers = answers.filter(shouldHaveScore)
.filter(shouldHaveHeading);
answers.sort(function (a, b) {
var aB = +(a.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0],
bB = +(b.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0];
return aB - bB
});
var users = {};
answers.forEach(function (a) {
var headline = a.body_markdown.split("\n")[0];
var question = QUESTION_IDs.indexOf(a.question_id);
var size = parseInt((headline.match(SIZE_REG)||[0])[0]);
var language = headline.match(LANGUAGE_REG)[1];
var user = getAuthorName(a);
var userId = getAuthorId(a);
if (!users[userId]) users[userId] = {name: user, nAnswer: 0, answers: []};
if (!users[userId].answers[question]) {
users[userId].answers[question] = {size: Infinity};
users[userId].nAnswer++;
}
if (users[userId].answers[question].size > size) {
users[userId].answers[question] = {size: size, link: a.share_link}
}
});
var sortedUsers = [];
for (var userId in users)
if (users.hasOwnProperty(userId)) {
var user = users[userId];
user.score = 0;
user.completedAll = true;
for (var i = 0; i < QUESTION_IDs.length; ++i) {
if (user.answers[i])
user.score += user.answers[i].size;
else
user.completedAll = false;
}
sortedUsers.push(user);
}
sortedUsers.sort(function (a, b) {
if (a.nAnswer > b.nAnswer) return -1;
if (b.nAnswer > a.nAnswer) return 1;
return a.score - b.score;
});
var place = 1;
for (var i = 0; i < sortedUsers.length; ++i) {
var user = sortedUsers[i];
var row = '<tr><td>'+ place++ +'.</td><td>'+user.name+'</td>';
for (var j = 0; j < QUESTION_IDs.length; ++j) {
var answer = user.answers[j];
if (answer)
row += '<td><a href="'+answer.link+'">'+answer.size+'</a></td>';
else
row += '<td class="missing"></td>';
}
row += '<td></td>';
if (user.completedAll)
row += '<td class="total">'+user.score+'</td>';
else
row += '<td class="total missing">'+user.score+'</td>';
row += '</tr>';
$("#users").append(row);
}
}
body { text-align: left !important}
#leaderboard {
width: 500px;
}
#answer-list {
padding: 10px;
width: 290px;
float: left;
}
#language-list {
padding: 10px;
width: 290px;
float: left;
}
table thead {
font-weight: bold;
}
table td {
padding: 5px;
}
td.total {
font-weight: bold;
text-align: right;
}
td.missing {
background: #bbbbbb;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="leaderboard">
<h2>Leaderboard</h2>
<p>
Missing scores are shown as grey cells. A grey total indicates that the user has not participated in all challenges and is not eligible for the overall victory yet.
</p>
<table class="_user-list">
<thead>
<tr><td></td><td>User</td>
<td><a href="https://codegolf.stackexchange.com/q/45302/8478">#1</a></td>
<td><a href="https://codegolf.stackexchange.com/q/45447/8478">#2</a></td>
<td><a href="https://codegolf.stackexchange.com/q/46991/8478">#3</a></td>
<td><a href="https://codegolf.stackexchange.com/q/49394/8478">#4</a></td>
<td><a href="https://codegolf.stackexchange.com/q/51222/8478">#5</a></td>
<td><a href="https://codegolf.stackexchange.com/q/66319/8478">#6</a></td>
<td><a href="https://codegolf.stackexchange.com/q/89621/8478">#7</a></td>
<td><a href="https://codegolf.stackexchange.com/q/120472/8478">#8</a></td>
<td></td><td>Total</td>
</tr>
</thead>
<tbody id="users">
</tbody>
</table>
</div>
<table style="display: none">
<tbody id="answer-template">
<tr><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>
<table style="display: none">
<tbody id="language-template">
<tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
</tbody>
</table>