Über die Serie
Ich werde eine kleine Reihe von Code-Golf-Herausforderungen durchführen, die sich um das Thema Zufälligkeit drehen. Dies wird im Grunde ein 9-Loch- Golfplatz sein , der sich jedoch über mehrere Fragen erstreckt. Sie können an jeder Herausforderung einzeln teilnehmen, als wäre es eine normale Frage.
Ich werde jedoch über alle Herausforderungen hinweg eine Rangliste führen. Die Serie wird (vorerst) über 9 Herausforderungen laufen, die alle paar Tage veröffentlicht werden. Jeder Benutzer, der an allen 9 Herausforderungen teilnimmt, hat Anspruch auf den Gewinn der gesamten Serie. Ihre Gesamtpunktzahl ist die Summe ihrer kürzesten Einsendungen bei jeder Herausforderung. Wenn Sie also zweimal auf eine Herausforderung antworten, wird nur die bessere Antwort für die Punktzahl gewertet. Wenn jemand 28 Tage lang den ersten Platz in dieser Rangliste belegt, werde ich ihm eine Prämie von 500 Wiederholungen gewähren .
Obwohl ich eine Menge Ideen für die Serie habe, sind die zukünftigen Herausforderungen noch nicht in Stein gemeißelt. Wenn Sie Vorschläge haben, teilen Sie mir dies bitte auf dem entsprechenden Sandbox-Post mit .
Loch 1: Mische ein Array
Die erste Aufgabe ist ziemlich einfach: Wenn Sie ein nicht leeres Array von Ganzzahlen haben, mischen Sie es nach dem Zufallsprinzip. Es gibt jedoch ein paar Regeln:
- Jede mögliche Permutation muss mit der gleichen Wahrscheinlichkeit zurückgeführt werden (so die Shuffle eine gleichmäßige Verteilung haben soll). Sie können überprüfen, ob Ihr Algorithmus einheitlich / unparteiisch ist, indem Sie ihn in JavaScript auf Will it Shuffle implementieren. Dadurch wird eine Matrix der Verzerrungen erstellt. Das Ergebnis sollte so einheitlich aussehen wie die eingebauten Fisher-Yates oder die Sortierung (zufällige Reihenfolge) .
- Sie dürfen keine integrierte Methode oder Methode eines Drittanbieters verwenden, um das Array zu mischen oder eine zufällige Permutation zu generieren (oder alle Permutationen aufzulisten). Insbesondere integrierte in dem einzigen Zufallsfunktion können Sie eine einzelne Zufallszahl zu einer Zeit bekommen . Sie können davon ausgehen, dass eine integrierte Zufallszahlenmethode in O (1) ausgeführt wird und über das angeforderte Intervall vollkommen einheitlich ist (mathematisch gesehen - Sie können hier Details der Gleitkommadarstellung ignorieren). Wenn Sie in Ihrer Sprache eine Liste mit m Zufallszahlen auf einmal erhalten können, können Sie diese Funktion verwenden, vorausgesetzt, die m Zahlen sind unabhängig voneinander und Sie zählen sie als O (m).
- Ihre Implementierung darf eine zeitliche Komplexität von O (N) nicht überschreiten , wobei N die Größe des zu mischenden Arrays ist. Beispielsweise können Sie nicht nach Zufallszahlen sortieren.
- Sie können das Array entweder an Ort und Stelle mischen oder ein neues Array erstellen (in diesem Fall kann das alte Array geändert werden, wie Sie möchten).
Sie können ein vollständiges Programm oder eine Funktion schreiben und Eingaben über STDIN, Befehlszeilenargument, Funktionsargument oder Eingabeaufforderung vornehmen und Ausgaben über Rückgabewerte oder durch Drucken an STDOUT (oder die nächstgelegene Alternative) erzeugen. Wenn Sie eine Funktion schreiben, die das Array an Ort und Stelle mischt, müssen Sie sie natürlich nicht zurückgeben (vorausgesetzt, Sie können in Ihrer Sprache nach der Rückkehr der Funktion auf das geänderte Array zugreifen).
Die Ein- und Ausgabe kann in einem beliebigen Listen- oder Zeichenfolgeformat erfolgen, muss jedoch beliebige Ganzzahlen im Bereich -2 31 ≤ x <2 31 unterstützen . Grundsätzlich sollte Ihr Code für Arrays mit einer Länge von bis zu 2 31 funktionieren, obwohl dies nicht unbedingt in Ihren Speicher passen oder innerhalb eines angemessenen Zeitraums vervollständigt werden muss. (Ich möchte einfach keine willkürlichen Größenbeschränkungen für Hardcode-Schleifen oder ähnliches sehen.)
Dies ist Codegolf, daher gewinnt die kürzeste Übermittlung (in Bytes).
Bestenliste
Das folgende Snippet generiert eine Rangliste für alle Herausforderungen der Serie.
Um sicherzustellen, dass Ihre Antworten angezeigt werden, beginnen Sie jede Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:
# Language Name, N bytes
Wo N
ist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(Die Sprache wird derzeit nicht angezeigt, das Snippet erfordert sie jedoch und analysiert sie. In Zukunft werde ich möglicherweise eine Bestenliste nach Sprachen hinzufügen.)
/* 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>
sortby(random)
(der Grund für die zeitliche Beschränkung) oder einfach.shuffle()
(der Grund für die eingebaute Beschränkung) lautet, was meiner Meinung nach weitaus weniger klug ist, als Fisher-Yates oder eine andere zu implementieren Ansatz.shuffle(array)
anstatt schreibennewArray=shuffle(array)
?Antworten:
Dyalog APL,
2524 BytesZuerst für die 25-stellige Lösung:
i{⊃a[⍺⍵]←a[⍵⍺]}¨?i←⌽⍳⍴a←⎕
Nach einigen Äquivalenztransformationen auf dem oben genannten:
wir können die Aufgabe loswerden
i←
und einen Charakter speichern:{⊃a[⍺⍵]←a[⍵⍺]}¨∘?⍨⌽⍳⍴a←⎕
quelle
80386 Maschinencode,
4424 BytesHexdump des Codes:
Vielen Dank an FUZxxl, der vorgeschlagen hat, die
rdrand
Anweisung zu verwenden.Hier ist der Quellcode (kann von Visual Studio kompiliert werden):
Eine weitere Implementierung von Fisher-Yates. Der Großteil des Golfspiels wurde durch Übergabe von Parametern in Registern erzielt.
quelle
rdrand
für Scheiße und Kichern verwendet haben.Java 88,
101Ein einfaches Fisher-Yates-Shuffle erledigt den Trick. Ich habe das Gefühl, dass es hier ziemlich häufig verwendet wird, da es schnell und einfach zu implementieren ist. Hier drängen sich einige Loops / Aufgaben, aber es gibt ehrlich gesagt nicht zu viel zum Golfen. es ist von Natur aus nur kurz.
Mit einigen Zeilenumbrüchen:
Dadurch wird das ursprüngliche Array geändert
s[]
. Testprogramm:quelle
Math.random()
hat eine Größe, die eine Potenz von zwei ist, sodass die Spezifikation nicht erfüllt wird.Python 2, 86 Bytes
Dies ist eine Funktion, die das Array an Ort und Stelle mischt, ohne es zurückzugeben, wobei eine einfache Implementierung des Fisher-Yates-Shuffle verwendet wird . Zufallszahlen von Python zu bekommen ist teuer ...
Vielen Dank an @xnor und @colevk für Tipps.
quelle
while i:i-=1;...
?while
in der Regel kürzer ist alsfor
für diese Art von Dingen ...i=len(L)
indem Sie das Dekrement an den Anfang der while-Schleife setzen.J,
4544 ZeichenDas war eine knifflige Sache.
Hier ist eine Erklärung:
# y
: Die tally dery
, dass die Anzahl der Elemente in isty
.?@# y
: Eine Zufallszahl, die gleichmäßig über den Bereich von1
bis verteilt ist(#y)-1
.x { y
: Der Artikel aus demy
Indexx
.(<<<x) { y
: Alle Artikel mit Ausnahme des Artikels bei Indexx
iny
.x , y
:y
angehängt anx
.x ({ , <^:3@[ { ]) y
: Das Element bei Indexx
iny
, dann alle anderen Elemente.(?@# ({ , <^:3@[ { ]) ]) y
Ein zufälliger davony
, dann alle anderen Gegenstände.x {. y
: Die erstenx
Artikel entnommen ausy
.x }. y
: Die erstenx
Gegenstände fielen ausy
.x ({. , }.) y
: Die erstenx
Elemente genommen ausy
, dann werden die erstenx
Artikel fiel ausy
x ({. , (?@# ({ , <^:3@[ { ]) ])@}.) y
: Die erstenx
Elemente genommen ausy
, dann die erstenx
Elemente ausy
wie in Ziffer 7 verarbeitet.x ({. , ?@#@}. ({ , <^:3@[ { ]) }.) y
: Dasselbe mit dem Drop- In, um ein Zeichen zu speichern.u/ y
: zwischen den Elementen vonu
eingefügty
.< y
:y
boxed .<"0 y
: Jeder Gegenstand iny
Schachtel .i. y
: ganze Zahlen von0
bisy - 1
.i.@# y
: ganze Zahlen von0
bis(#y) - 1
.(<"0@i.@# , <) y
: Ganzzahlen von0
bis zu(#y) - 1
jeder Box und danny
in einer einzelnen Box. Dies ist erforderlich, da Arrays in J einheitlich sind. Eine Box verbirgt die Form ihres Inhalts.x u&v y
: wie(v x) u (v y)
.> y
:y
geöffnet , das heißt, ohne seine Box.x ({. , ?@#@}. ({ , <^:3@[ { ]) }.)&> y
Die Phrase aus Nummer 12 galt für die Argumente ohne Box.({. , ?@#@}. ({ , <^:3@[ { ]) }.)&>/ y
die Phrase von Nr. 21 eingefügt zwischen Einzelteilen vony
.({. , ?@#@}. ({ , <^:3@[ { ]) }.)&>/@(<"0@i.@# , <) y
die Phrase von Nummer 22 wird auf das Ergebnis der Phrase von Nummer 18 angewendet, oder eine einheitliche Permutation der Gegenstände vony
.quelle
<@<@<@[
ist auch ein Rätsel ... Warten auf Erklärung. :)from
({
). And I really like the&>/
trick to manipulate a list. I'm sure I could have used it a couple times before.Pyth, 25 bytes
Test it here.
Yet another Fisher-Yates implementation. Is essentially the same as @Sp3000 python solution, just in pyth.
Thanks to @Jakube for the swapping trick
quelle
Perl,
685644Like many other solutions, this uses the Fisher-Yates algorithm.
Using nutki's comment, 12 characters are saved by using
$_
instead of$i
and performing the operations in the array indices.44:
56:
This is my first codegolf.
quelle
@_[...]
as rvalue like that. Can be golfed further intosub f{@_[$_,$j]=@_[$j=rand$_,--$_]for 1..@_}
.C,
636160 bytesJust a straight implementation of Fischer-Yates that sorts the given array in place. Compiles and links perfectly fine with the visual studio compiler (vs2013, haven't tested the other versions) and the Intel Compiler. Nice looking function signature is
s(int array[], int length)
. I'm legitimately impressed I beat Python and Ruby.This does assume
srand()
is called and rand() is implemented properly, but I believe this rule allows for that:Nicely formatted version:
quelle
s(a,m)*a{
, but I'm not sure and don't want to test either. You might want to do axor
-swap, like ina[i]^=a[m]^=a[i]^=a[m]
. This also avoids the need to declaret
.i==m
.s(a,m)int*a
for visual studio and the intel compiler. Don't have gcc or clang installed to test, but I assume they will also complain.t=a[i]
, you can then move thei=rand()%m--
statement inside as the array index.Octave,
8877 bytesYet another Fisher-Yates implementation... Should be fairly straightforward if I add the usual line returns and spacing:
The "end" keywords really kill the golf score here, unfortunately.Hey, I can use "end" instead of "endfor" and "endfunction"!quelle
numel
instead oflenght
. As a bonus your program would also work with 2-D arrays aka matrices ;)Java 8, 77
It's a lambda taking
int[]
and returning void. My first attempt seemed not very interesting, so I decided to have it exit by throwing an exception.Test program:
quelle
Math.random()
?Golflua, 37
How to run Golflua?
The input is provided as a table in the variable X. The table is shuffled in place.
Example usage:
quelle
R, 79 bytes
This is a straightforward implementation of the Fisher-Yates shuffle. The R function
sample
draws a simple random sample of a given size from a given vector with equal probability. Here we're drawing a random sample of size 1 at each iteration from the integersi
, ...,n
. As stated in the question, this can be assumed to be O(1), so in all this implementation should be O(N).quelle
Matlab, 67
Also implementing Fisher-Yates.
I thought it was too bad I could not use Matlab's
randperm
function. But after some fiddling around, I thought I may look at the source ofrandperm
to see how it is done, and I was astonished to see that there was just one line:[~,p] = sort(rand(1,n))
=)quelle
Perl, 44
Another perl in 44 characters. Example use:
quelle
Mathematica,
82 90 8393 bytesNote: This variation the Fisher-Yates shuffle is actually Martin Büttner's solution, with some code paring by alephalpha.
s
is the input array. Nothing fancy-smancy, but sometimes the simple things are the most elusive.quelle
Do
here. It's shorter thanWhile
.Ruby, 57 bytes
Input (as lambda function):
Output:
quelle
TI-BASIC, 46 bytes
Source for byte count
quelle
End
.K, 31 chars
Not quite as short as the one I put up before (which got disqualified)...oh well.
It's a basic Fisher-Yates shuffle. This was built with lots of help from the Kona mailing list.
quelle
JavaScript (ES6), 66
This function shuffles the array in place. It also returns a byproduct array that is NOT the shuffled output and must not be considered.
quelle
MATL, 16 bytes
Try it online!
Fisher-Yates in MATL. Almost a third of this program is devoted to the letter
H
, which corresponds to the clipboard function in MATL.Basically,
H
stores the unused items from the input, while the stack keeps track of the shuffled list.quelle
Japt, 12
Try it!
-10 (about half ;) thanks to @Shaggy!
I have been wanting to try out a golfing language, and the Japt interpreter had good documentation and a way to try things out in the browser.
Below is the strategy I took:
quelle
Javascript ES6, 69
It's Fisher–Yates.
PS: Can be tested in Firefox
quelle
Pyth, 27 bytes
Test it here
This is an implementation of the incremental Fisher-Yates shuffle, mentioned second here.
quelle
Haskell, 170
Another Fisher-Yates solution inspired by the algorithm at https://wiki.haskell.org/Random_shuffle.
s
is a function which has signature:IOArray Int a -> IO [a]
quelle
CJam - 30
Try it at http://cjam.aditsu.net/
Example input:
[10 20 30 40 50]
Example output:
3020401050
(add ap
at the end of the code for pretty printing)If the code is allowed to take the input from the stack (like a function), then the first 2 characters can be removed, reducing the size to 28.Explanation:
The code is longer than I hoped, due to the lack of a "swap" operator for arrays
(to be implemented later :p)
quelle
_
is O(N) (inside an O(N) loop). Unfortunately, I don't see a way to work around that in CJam.t
that kills it, as it can't mutate the list and now must create a copy.t
, I'd like to improve it in future versions..JavaScript (ES 6), 61
You can test it here by just adding a line that says
shuffle = S
(Firefox only).quelle
STATA, 161
Expects input as space separated numbers. I can remove the headers and observation numbers from the output if you would like, but otherwise this is shorter.
quelle
_n
in this?Java, 93 bytes
Example usage: http://ideone.com/RqSMnZ
quelle
SQF, 91 bytes
quelle
%x
with%i
.Perl, 41 bytes
Try it online!
quelle