Sobre a série
Estarei executando uma pequena série de desafios de código-golfe que giram em torno do tema da aleatoriedade. Basicamente, este será um campo de golfe de 9 buracos , mas está espalhado por várias perguntas. Você pode participar de qualquer desafio individualmente, como se fosse uma pergunta normal.
No entanto, manterei uma tabela de líderes em todos os desafios. A série terá 9 desafios (por enquanto), um publicado a cada poucos dias. Todo usuário que participa dos nove desafios é elegível para ganhar a série inteira. A pontuação geral deles é a soma dos envios mais curtos em cada desafio (portanto, se você responder a um desafio duas vezes, apenas a melhor resposta será contada na pontuação). Se alguém ocupar o primeiro lugar nesta classificação geral por 28 dias , concederei a eles uma recompensa de 500 representantes .
Embora eu tenha várias idéias alinhadas para a série, os desafios futuros ainda não estão definidos. Se você tiver alguma sugestão, informe-me na postagem da sandbox relevante .
Buraco 1: embaralhar uma matriz
A primeira tarefa é bem simples: dada uma matriz não vazia de números inteiros, embaralhe-a aleatoriamente. Existem algumas regras, porém:
- Toda permutação possível deve ser retornada com a mesma probabilidade (para que o shuffle tenha uma distribuição uniforme). Você pode verificar se o seu algoritmo é uniforme / imparcial implementando-o em JavaScript no Will it Shuffle , que produzirá uma matriz de vieses - o resultado deve parecer tão uniforme quanto seus Fisher-Yates internos ou classificação (ordem aleatória) .
- Você não deve usar nenhum método interno ou de terceiros para embaralhar a matriz ou gerar uma permutação aleatória (ou enumerar todas as permutações). Em particular, a única função aleatória interna que você pode usar é obter um único número aleatório de cada vez . Você pode assumir que qualquer método de número aleatório interno é executado em O (1) e é perfeitamente uniforme durante o intervalo solicitado (em um sentido matemático - você pode ignorar detalhes da representação em ponto flutuante aqui). Se o seu idioma permitir que você obtenha uma lista de m números aleatórios de uma só vez, você poderá usar este recurso, desde que os números m sejam independentes um do outro e contados como O (m).
- Sua implementação não deve exceder uma complexidade de tempo de O (N) , em que N é o tamanho da matriz a ser embaralhada. Por exemplo, você não pode "classificar por números aleatórios".
- Você pode embaralhar a matriz no lugar ou criar uma nova matriz (nesse caso, a matriz antiga pode ser modificada da maneira que desejar).
Você pode escrever um programa completo ou uma função e receber entradas via STDIN, argumento de linha de comando, argumento de função ou prompt e produzir saída via valor de retorno ou imprimindo em STDOUT (ou alternativa mais próxima). Se você escrever uma função que embaralhe a matriz no lugar, não precisará retorná-la, é claro (desde que o seu idioma permita acessar a matriz modificada após o retorno da função).
A entrada e a saída podem estar em qualquer formato conveniente de lista ou sequência, mas devem suportar números inteiros arbitrários no intervalo -2 31 ≤ x <2 31 . Em princípio, seu código deve funcionar com matrizes de comprimento 2 a 31 , embora isso não precise necessariamente caber em sua memória ou ser concluído dentro de um período de tempo razoável. (Eu só não quero ver limites arbitrários de tamanho para loops de código rígido ou algo assim.)
Isso é código de golfe, então a submissão mais curta (em bytes) vence.
Entre os melhores
O trecho a seguir gerará uma tabela de classificação em todos os desafios da série.
Para garantir que suas respostas sejam exibidas, inicie todas as respostas com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(O idioma não é mostrado no momento, mas o snippet exige e o analisa, e eu posso adicionar um cabeçalho por idioma no futuro.)
/* 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>