О серии
Я проведу небольшую серию соревнований по коду-гольфу, посвященных теме случайности. В основном это будет поле для гольфа на 9 лунок , но оно будет разбито на несколько вопросов. Вы можете участвовать в любом вызове индивидуально, как если бы это был обычный вопрос.
Тем не менее, я буду поддерживать таблицу лидеров по всем задачам. Сериал будет проходить более 9 задач (пока), один раз в несколько дней. Каждый пользователь, участвующий во всех 9 соревнованиях, имеет право на победу во всей серии. Их общий балл - это сумма их самых коротких заявок на каждый вызов (поэтому, если вы ответите на вызов дважды, к баллу будет засчитан только лучший ответ). Если кто-то займет первое место в этом общем списке лидеров в течение 28 дней, я назначу ему награду в 500 представителей .
Несмотря на то, что у меня есть ряд идей для этой серии, будущие проблемы еще не заложены. Если у вас есть какие-либо предложения, пожалуйста, сообщите мне об этом в соответствующей песочнице .
Отверстие 1: перемешать массив
Первая задача довольно проста: при наличии непустого массива целых чисел перемешать его случайным образом. Есть несколько правил:
- Каждая возможная перестановка должна быть возвращена с одинаковой вероятностью (поэтому перемешивание должно иметь равномерное распределение). Вы можете проверить, является ли ваш алгоритм единообразным / беспристрастным, реализовав его в JavaScript на Will it Shuffle , который будет генерировать матрицу смещений - результат должен выглядеть так же равномерно, как и встроенные значения Fisher-Yates или sort (в произвольном порядке) .
- Вы не должны использовать какой-либо встроенный или сторонний метод для перемешивания массива или генерации случайной перестановки (или перечисления всех перестановок). В частности, единственная встроенная случайная функция, которую вы можете использовать, - это получение одного случайного числа за раз . Вы можете предположить, что любой встроенный метод случайных чисел работает в O (1) и является абсолютно равномерным в течение запрошенного интервала (в математическом смысле - вы можете игнорировать детали представления с плавающей точкой здесь). Если ваш язык позволяет вам получить список из m случайных чисел одновременно, вы можете использовать эту возможность при условии, что m номеров не зависят друг от друга, и вы считаете это как O (m).
- Ваша реализация не должна превышать временную сложность O (N) , где N - размер массива, который должен быть перетасован. Например, вы не можете "сортировать по случайным числам".
- Вы можете либо перемешать массив на месте, либо создать новый массив (в этом случае старый массив может быть изменен по вашему усмотрению).
Вы можете написать полную программу или функцию и получать ввод через STDIN, аргумент командной строки, аргумент функции или приглашение и производить вывод через возвращаемое значение или печатать в STDOUT (или ближайшую альтернативу). Если вы пишете функцию, которая перемешивает массив на месте, вам, конечно, не нужно возвращать его (при условии, что ваш язык позволяет вам получить доступ к измененному массиву после возврата из функции).
Вход и выход могут быть в любом удобном формате списка или строки, но должны поддерживать произвольные целые числа в диапазоне -2 31 ≤ x <2 31 . В принципе, ваш код должен работать для массивов длиной до 2 31 , хотя это не обязательно должно умещаться в вашей памяти или завершаться в течение разумного периода времени. (Я просто не хочу видеть произвольные ограничения размера для циклов жесткого кода или чего-то еще.)
Это код гольф, поэтому выигрывает самое короткое представление (в байтах).
Leaderboard
Следующий фрагмент создаст таблицу лидеров по всем задачам серии.
Чтобы убедиться, что ваши ответы отображаются, начните каждый ответ с заголовка, используя следующий шаблон уценки:
# Language Name, N bytes
где N
размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(Язык в настоящее время не отображается, но фрагмент требует и анализирует его, и я могу добавить таблицу лидеров по языкам в будущем.)
/* 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)
(причина ограничения по времени), либо просто.shuffle()
(причина ограничения встроенных функций), что, на мой взгляд, гораздо менее разумно, чем реализация Фишера-Йейтса или какой-то другой подходить.shuffle(array)
вместоnewArray=shuffle(array)
?Ответы:
Дьялог АПЛ,
2524 байтаСначала для 25-символьного решения:
i{⊃a[⍺⍵]←a[⍵⍺]}¨?i←⌽⍳⍴a←⎕
После некоторых преобразований эквивалентности выше:
мы можем избавиться от задания
i←
и сохранить персонажа:{⊃a[⍺⍵]←a[⍵⍺]}¨∘?⍨⌽⍳⍴a←⎕
источник
80386 машинный код,
4424 байтаHexdump кода:
Спасибо FUZxxl, который предложил использовать
rdrand
инструкцию.Вот исходный код (может быть скомпилирован Visual Studio):
Еще одна реализация Фишера-Йейтса. Большая часть игры в гольф была достигнута путем передачи параметров в регистрах.
источник
rdrand
для дерьма и хихиканья.Ява, 88
101Основной трюк Фишера-Йейтса делает свое дело. У меня такое ощущение, что он будет использоваться здесь довольно часто, поскольку его легко и быстро реализовать. Здесь есть какая-то петля / задание, но, честно говоря , в гольф не так уж много; это просто короткий от природы.
С некоторыми переносами строк:
Это перемешивает на месте, изменяя исходный массив
s[]
. Тестовая программа:источник
Math.random()
имеет размер, который является степенью двойки, так что это не соответствует спецификации.Python 2, 86 байт
Это функция, которая перемешивает массив на месте, не возвращая его, используя простую реализацию перемешивания Фишера-Йейтса . Получение случайных чисел из Python стоит дорого ...
Спасибо @xnor и @colevk за советы.
источник
while i:i-=1;...
?while
как правило, короче, чемfor
для такого рода вещи ...i=len(L)
и поместив декремент в начало цикла while.J,
4544 символаЭто было сложно.
Вот объяснение:
# y
: Подсчет изy
, то есть, количество элементов вy
.?@# y
: Случайное число, равномерно распределенное по диапазону от1
до(#y)-1
.x { y
: Элемент изy
индексаx
.(<<<x) { y
: Все элементы, кроме элемента с индексомx
вy
.x , y
:y
Добавляется кx
.x ({ , <^:3@[ { ]) y
: Элемент с индексомx
вy
, то все остальные элементы.(?@# ({ , <^:3@[ { ]) ]) y
Случайноy
, потом все остальные предметы.x {. y
: Первыеx
предметы взяты изy
.x }. y
: Первыеx
предметы выпали изy
.x ({. , }.) y
: Первыеx
предметы взяты изy
, затем первыеx
предметы выброшены изy
x ({. , (?@# ({ , <^:3@[ { ]) ])@}.) y
: Первыеx
элементы, взятые изy
, затем первыеx
элементы изy
обработанных, как в номере 7.x ({. , ?@#@}. ({ , <^:3@[ { ]) }.) y
То же самое с выпавшим дропом, чтобы спасти одного персонажа.u/ y
:u
вставлено между элементамиy
.< y
: вy
штучной упаковке .<"0 y
Каждый предмет вy
штучной упаковке .i. y
: целые числа от0
доy - 1
.i.@# y
: целые числа от0
до(#y) - 1
.(<"0@i.@# , <) y
: Целые из0
к(#y) - 1
каждой коробке , а затемy
в одном окне. Это необходимо, потому что массивы в J одинаковы. Коробка скрывает форму своего содержимого.x u&v y
: Как(v x) u (v y)
.> y
:y
открыл , то есть без своей коробки.x ({. , ?@#@}. ({ , <^:3@[ { ]) }.)&> y
фраза из числа 12 применяется к ее без коробки аргументы.({. , ?@#@}. ({ , <^:3@[ { ]) }.)&>/ y
фраза из числа 21 вставлена между пунктамиy
.({. , ?@#@}. ({ , <^:3@[ { ]) }.)&>/@(<"0@i.@# , <) y
Фраза из числа 22 применяется к результату фразы из числа 18 или равномерной перестановки предметовy
.источник
<@<@<@[
тоже загадка ... В ожидании объяснения. :)from
({
). И мне действительно нравится&>/
трюк, чтобы манипулировать списком. Я уверен, что мог бы использовать это пару раз раньше.Pyth, 25 байт
Проверьте это здесь.
Еще одна реализация Фишера-Йейтса. По сути, это то же самое, что и решение @ Sp3000 python, только в pyth.
Спасибо @Jakube за трюк с обменом
источник
Perl,
685644Как и во многих других решениях, здесь используется алгоритм Фишера-Йейтса .
С помощью комментария Nutki , 12 символов сохраняются при использовании
$_
вместо$i
и выполнении операций с индексами массива.44:
56:
Это мой первый Codegolf.
источник
@_[...]
качестве rvalue, как это. Может быть в гольф дальшеsub f{@_[$_,$j]=@_[$j=rand$_,--$_]for 1..@_}
.C
636160 байтПросто прямая реализация Фишера-Йейтса, которая сортирует данный массив на месте. Прекрасно компилируется и связывается с компилятором visual studio (vs2013, другие версии не тестировались) и компилятором Intel. Приятно выглядящая функция подписи есть
s(int array[], int length)
. Я законно впечатлен, я победил Python и Ruby.Это предполагает, что
srand()
вызывается, и rand () реализован правильно, но я считаю, что это правило учитывает это:Красиво отформатированная версия:
источник
s(a,m)*a{
, но я не уверен и тоже не хочу тестировать. Вы можете сделать-xor
swap, как вa[i]^=a[m]^=a[i]^=a[m]
. Это также позволяет избежать необходимости декларироватьt
.i==m
.s(a,m)int*a
для Visual Studio и компилятор Intel. У меня не установлены gcc или clang для тестирования, но я предполагаю, что они тоже будут жаловаться.t=a[i]
, вы можете переместитьi=rand()%m--
оператор внутрь как индекс массива.Октава,
8877 байтЕще одна реализация Фишера-Йейтса ... Должна быть довольно простой, если я добавлю обычные возвраты строк и интервал:
К сожалению, «конечные» ключевые слова действительно убивают счет в гольфе.Эй, я могу использовать «конец» вместо «endfor» и «endfunction»!источник
numel
вместоlenght
. В качестве бонуса ваша программа также будет работать с двумерными массивами или матрицами;)Ява 8, 77
Это лямбда, принимающая
int[]
и возвращающая пустоту. Моя первая попытка показалась мне не очень интересной, поэтому я решил сделать так, чтобы она была исключена.Тестовая программа:
источник
Math.random()
?Golflua, 37
Как запустить Golflua?
Входные данные предоставляются в виде таблицы в переменной X. Таблица перемешивается на месте.
Пример использования:
источник
R, 79 байт
Это простая реализация шаффла Фишера-Йейтса. Функция R
sample
рисует простую случайную выборку заданного размера из заданного вектора с равной вероятностью. Здесь мы рисуем случайную выборку размером 1 на каждой итерации из целых чиселi
, ...,n
. Как указано в вопросе, это можно предположить как O (1), поэтому во всей этой реализации должно быть O (N).источник
Матлаб, 67
Также реализует Фишер-Йейтс.
Я думал, что это слишком плохо, я не мог использовать
randperm
функцию Matlab . Но после некоторого возни, я подумал, что могу посмотреть на источник,randperm
чтобы увидеть, как это делается, и я был удивлен, увидев, что была только одна строка:[~,p] = sort(rand(1,n))
=)источник
Perl, 44
Еще один Perl в 44 символов. Пример использования:
источник
Mathematica,
82 90 8393 байтаПримечание. Эта вариация тасования Фишера-Йейтса на самом деле является решением Мартина Бюттнера, с некоторой обработкой кода алефальфой.
s
это входной массив. Ничего особенного, но иногда простые вещи самые неуловимые.источник
Do
здесь. Это корочеWhile
.Рубин, 57 байт
Вход (как лямбда-функция):
Выход:
источник
TI-BASIC, 46 байтов
Источник для подсчета байтов
источник
End
.К, 31 символ
Не такой короткий, как тот, который я выложил раньше (который был дисквалифицирован) ... о, хорошо.
Это основной случай Фишера-Йейтса. Это было построено с большой помощью из списка рассылки Kona .
источник
JavaScript (ES6), 66
Эта функция перемешивает массив на месте. Он также возвращает массив побочных продуктов, который НЕ является перемешанным выводом и не должен рассматриваться.
источник
MATL , 16 байт
Попробуйте онлайн!
Фишер-Йейтс в МАТЛ. Почти треть этой программы посвящена письму
H
, которая соответствует функции буфера обмена в MATL.В основном,
H
хранит неиспользуемые элементы из ввода, в то время как стек отслеживает перетасованный список.источник
Джапт, 12
Попытайся!
-10 (около половины;) благодаря @Shaggy!
Я давно хотел попробовать язык игры в гольф, и у переводчика Japt была хорошая документация и возможность опробовать вещи в браузере.
Ниже приведена стратегия, которую я выбрал:
источник
Javascript ES6, 69
Это Фишер-Йейтс.
PS: можно протестировать в Firefox
источник
Pyth, 27 байт
Проверьте это здесь
Это реализация инкрементального шаффла Фишера-Йейтса, упомянутого второго здесь .
источник
Хаскелл, 170
Другое решение Фишера-Йейтса, вдохновленное алгоритмом по адресу https://wiki.haskell.org/Random_shuffle .
s
это функция, которая имеет подпись:IOArray Int a -> IO [a]
источник
CJam - 30
Попробуйте это в http://cjam.aditsu.net/
Пример ввода:
[10 20 30 40 50]
Пример вывода:
3020401050
(добавитьp
в конце кода для красивой печати)Если коду разрешено принимать входные данные из стека (например, функции), то первые 2 символа можно удалить, уменьшив размер до 28.Объяснение:
Код длиннее, чем я ожидал, из-за отсутствия оператора «swap» для массивов
(будет реализовано позже: p)
источник
_
, O (N) (внутри петли O (N)). К сожалению, я не вижу способа обойти это в CJam.t
что убивает его, так как он не может изменить список и теперь должен создать копию.t
, я хотел бы улучшить ее в будущих версиях ..JavaScript (ES 6), 61
Вы можете проверить это здесь , просто добавив строку с надписью
shuffle = S
(только Firefox).источник
СТАТА, 161
Ожидается ввод в виде разделенных пробелами чисел. Я могу удалить заголовки и номера наблюдений из вывода, если хотите, но в противном случае это короче.
источник
_n
в этом?Java, 93 байта
Пример использования: http://ideone.com/RqSMnZ
источник
SQF, 91 байт
источник
%x
на%i
.Perl, 41 байт
Попробуйте онлайн!
источник