Перемешать колоду без локальных переменных [закрыто]


14

Цель этой головоломки состоит в том, чтобы взять колоду из 52 карт и перемешать ее, чтобы каждая карта находилась в случайном положении.

Данный:

  • Массив deckиз 52 различных целых чисел, представляющих карты. При запуске deckсодержит ровно по одной каждой карточке в каком-то неизвестном порядке.
  • Функция, int rand(min, max)которая возвращает случайное целое число между целыми числами minи maxвключительно. Вы можете предположить, что эта функция действительно случайна.
  • Функция, void swap(x, y)которая меняет две карты в колоде. Если вы позвоните swap(x, y), карты на местах xи yпоменяются местами.

Когда:

  • Программа вызывает shuffle()(или, shuffle(deck)или как deck.shuffle()вам нравится запускать вашу реализацию),

Потом:

  • deck должен содержать ровно одну каждую карту в совершенно случайном порядке.

Поймать:

Вы не можете объявить какие-либо переменные. Вызовите swapи randсколько угодно, но вы не можете объявить свои собственные переменные. Это включает в себя forсчетчики циклов - даже неявные, как в foreach.

Разъяснения:

  • Вы можете изменить мелкие детали в соответствии с выбранным вами языком. Например, вы можете написать swapдля переключения двух целых чисел по ссылке. Изменения должны быть сделаны, чтобы это работало с вашим языком, а не чтобы облегчить задачу.
  • deck может быть глобальной переменной, или вы можете принять ее в качестве параметра.
  • Вы можете делать с содержимым все, что хотите deck, но не можете изменять его длину.
  • Ваши карты могут быть пронумерованы 0-51, 1-52 или как угодно.
  • Вы можете написать это на любом языке, но без обмана с помощью встроенной shuffleфункции вашего языка .
  • Да, вы можете написать одну и ту же строку 52 раза. Никто не будет впечатлен.
  • Время выполнения не имеет значения, но истинная случайность имеет значение.
  • Это на самом деле не гольф-код, но вы можете минимизировать / запутать ваш код.

Редактировать: код Boilerplate и визуализатор

Если вы использовали .NET или JavaScript, вот несколько тестовых кодов, которые вам могут пригодиться:

JavaScript:

C #:

Этот код сортирует и перетасовывает колоду несколько тысяч раз и выполняет некоторое базовое тестирование работоспособности: для каждого перемешивания он проверяет, что в колоде находится ровно 52 карты без повторов. Затем визуализатор отображает частоту каждой карты в каждом месте колоды, отображая тепловую карту в оттенках серого.

Вывод визуализатора должен выглядеть как снег без видимого рисунка. Очевидно, что это не может доказать истинную случайность, но это быстрый и простой способ выборочной проверки. Я рекомендую использовать его или что-то подобное, потому что определенные ошибки в алгоритме тасования приводят к очень узнаваемым паттернам в выходных данных. Вот пример вывода из двух реализаций, одна с общим недостатком:

Выход визуализатора

Неправильная версия частично перетасовывает колоду, поэтому может хорошо выглядеть, если вы изучили массив вручную. Визуализатор позволяет легче заметить шаблон.


Многие языки моделируют массивы как эффективно бесконечные, что позволяет использовать $ deck [52] и далее вместо локальных переменных. Возможно, это тоже должно быть запрещено.
Тимви

2
Функции считаются переменными? параметры функции считаются переменными?
zzzzBov

1
@zzzzBov - Я имел в виду, что параметры функции будут считаться переменными, но я не уточнил это до ответа @ mellamokb. Я знаю, что это может быть сделано без каких-либо параметров, кроме deckсебя.
Джастин Морган

1
@eBusiness - это проблема со мной, а не сам вопрос. И я голосовал, потому что ответчик нашел лазейку.
Джастин Морган

1
@ пользователь неизвестен - думаю, я понимаю. Ответ в основном заключается в том, что вы можете принять любую реализацию, которая swapвам нравится, при условии, что она выполняет свое основное назначение. Одна из причин, по которой я сделал что- swapто, было то, что люди могли относиться к нему как к «магии» и сосредоточиться на главной проблеме, не беспокоясь о том, чтобы она работала на выбранном ими языке. Вы можете сделать это или написать свой swap, это зависит от вас.
Джастин Морган,

Ответы:


9

JavaScript

Я считаю, что это предполагаемая форма решения, я использую карту в положении 0, чтобы отслеживать прогресс, только перетасовывая карты, которые уже использовались в качестве счетчика, это достигает стандартных 52! перестановки с идеально равным распределением. Процедура усложняется обменом XOR, не позволяющим заменить элемент самостоятельно.

Редактировать: я встроил сортировку, которая сортирует каждый элемент на месте непосредственно перед его использованием, что позволяет работать с несортированным массивом. Я также отбросил рекурсивный вызов в пользу цикла while.

deck=[]
for(a=0;a<52;a++){
    deck[a]=a
}
function swap(a,b){
    deck[a]=deck[b]^deck[a]
    deck[b]=deck[b]^deck[a]
    deck[a]=deck[b]^deck[a]
}
function rand(a,b){
    return Math.floor(Math.random()*(1+b-a))+a
}
function shuffle(){
    while(deck[0]!=0){ //Sort 0 into element 0
        swap(0,deck[0])
    }
    while(deck[0]<51){ //Run 51 times
        while(deck[deck[0]+1]!=deck[0]+1){ //Sort element deck[0]+1 into position deck[0]+1
            swap(deck[deck[0]+1],deck[0]+1)
        }
        swap(0,deck[0]+1) //Swap element deck[0]+1 into position 0, thus increasing the value of deck[0] by 1
        if(rand(0,deck[0]-1)){ //Swap the element at position deck[0] to a random position in the range 1 to deck[0]
            swap(deck[0],rand(1,deck[0]-1))
        }
    }
    if(rand(0,51)){ //Swap the element at position 0 to a random position
        swap(0,rand(1,51))
    }
}
for(c=0;c<100;c++){
    shuffle()
    document.write(deck+"<br>")
}

Это именно то, что я имел в виду. Как только я протестирую это, я проголосую и, вероятно, приму.
Джастин Морган

Кажется, работает нормально, хотя при ближайшем рассмотрении это не совсем так, как у меня. Принят, и я скоро выложу свой ответ.
Джастин Морган

Это также известно как алгоритм Кнута shuffle ( en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle ).
Боб

14

Haskell

Вот бессмысленная реализация. Нет переменных, формальных параметров или явной рекурсии. Я использовал lambdabot «s @pl(„бессмысленный“) рефакторинг функции совсем немного.

import Data.List
import Control.Applicative
import Control.Monad
import System.Random

shuffle :: [a] -> IO [a]
shuffle = liftM2 (<$>) ((fst .) . foldl' (uncurry ((. flip splitAt) . (.) .
          (`ap` snd) . (. fst) . flip flip tail . (ap .) . flip flip head .
          ((.) .) . (. (++)) . flip . (((.) . (,)) .) . flip (:))) . (,) [])
          (sequence . map (randomRIO . (,) 0 . subtract 1) . reverse .
          enumFromTo 1 . length)

main = print =<< shuffle [1..52]

Вот моя процедура тестирования, чтобы убедиться, что числа были распределены равномерно:

main = print . foldl' (zipWith (+)) (replicate 52 0)
       =<< replicateM 1000 (shuffle [1..52])

Вот оригинальный алгоритм:

shuffle :: [a] -> IO [a]
shuffle xs = shuffleWith xs <$>
             sequence [randomRIO (0, i - 1) | i <- reverse [1..length xs]]

shuffleWith :: [a] -> [Int] -> [a]
shuffleWith xs ns = fst $ foldl' f ([], xs) ns where
    f (a,b) n = (x:a, xs++ys) where
        (xs, x:ys) = splitAt n b

+1 для Хаскелла. Теперь я должен выучить Хаскель, чтобы я мог это прочитать. : P
Джастин Морган

Как сохраняется прогресс?
аааааааааааа

8
Я сомневаюсь, что кто-либо, кроме программистов на Haskell, скажет, что их код бессмысленен, и будет гордиться этим.
аааааааааааа

4
Это ((.) .) . (. (++))и это (((.) . (,)) .)мои любимые. Ух ты ламбдабот. Просто вау.
Дэн Бертон,

2
@eBusiness "point free" совсем не то же самое, что "бессмысленный".
fredoverflow

6

J

Игнорирование этой колоды является переменной, есть очевидное ...

52 ? 52

Конечно, если вам действительно нужна функция, она есть, которая будет работать, даже если вы забудете удалить джокеров (или попытаетесь перетасовать что-то, кроме карт).

{~ (# ? #)

И что...

shuffle =: {~ (# ? #)
deck =: i. 52
shuffle deck

Вероятно, это выходит за рамки вопроса, заключающегося в том, чтобы реализовать случайное перемешивание из rand ( ?). Я мог бы сделать это позже, когда я не должен работать.

объяснение

Объяснение 52 ? 52 :

  • x ? y х случайных уникальных предметов от у.

Объяснение {~ (# ? #)сложнее из-за вилок и крючков . По сути, это то же самое shuffle =: 3 : '((# y) ? (# y)) { y', что имеет один неявный аргумент (y ).

  • # y дает длину у
  • Это дает 52? 52, как и раньше, что является случайной перестановкой 0..51
  • x { y это элемент y в индексе x или (в данном случае) элементы в индексах в x.
  • Это позволяет вам перемешивать все, что передано, а не только целые числа.

Смотрите J Vocabulary для подробностей об операторах, хотя синтаксис и семантика довольно сложны из-за рангового и неявного программирования.


+1: Работаю над code-golf, когда должен работать .. lol Я тоже: P
mellamokb

1
Можете ли вы объяснить, что это делает для людей с нарушениями зрения? Недавно я слышал, что это описывается как взрыв на фабрике смайликов ( codegolf.stackexchange.com/questions/1294/anagram-code-golf/… ), что звучит примерно так.
Джастин Морган

@Justin: объяснение добавлено.
Джесси Милликен

Это работает и в APL. Синтаксис тот же, поэтому я не буду беспокоиться о добавлении нового ответа ( {52?⍵}это анонимная функция, которая берет 52 случайных элемента из своего аргумента, который здесь будет список из 52 целых чисел)
Arc676

4

питон

import random
def rand(x, y):
 return random.randrange(x, y+1)

def swap(deck, x, y):
 deck[x] ^= deck[y]
 deck[y] ^= deck[x]
 deck[x] ^= deck[y]

def shuffle(deck):
 if len(deck)>1:
  deck[1:]=shuffle(deck[1:])
  if rand(0,len(deck)-1)>0:swap(deck, 0, rand(1, len(deck)-1))
 return deck

print shuffle(range(52))

Что [1:]значит? Это рекурсивно для подмассива deck?
Джастин Морган

Да, [1:] означает подмассив от индекса 1 до конца массива. Таким образом, он рекурсивно перемешивает все, кроме первого элемента, присваивает (копирует) его обратно в то же место в исходном массиве, а затем случайным образом размещает первый элемент где-нибудь.
Кит Рэндалл

Очень умно. Я думаю, что это одно из самых красивых решений здесь, и оно правильно использует алгоритм Фишера-Йейтса. +1. Это был хороший способ увидеть красоту языков, с которыми я не знаком.
Джастин Морган

2
Вам может понравиться a, b = b, aтрюк.
Рэй

3

Использование факторического представления

В факторическом представлении перестановки элемент i принимает значения от 0 до Ni. Так что случайная перестановка только rand(0,i)для каждого Ni.

В J:

? |.>:i.52
2 39 20 26 ... 2 0 1 0 0 0

где ? xесть rand(0,x-1)и |.>:i.52есть52 51 ... 1

Затем, если aэто значение Ith factoradic, мы делаем обмен: swap(deck[i], deck[i+a]). Список пар для обмена:

(,. i.52) ,. (,. ((?|.>:i.52)+i.52))
0 33
1 20
2  3
...
49 50
50 50
51 51

Обмен, который мы будем использовать, работает следующим образом:

deck
24 51 14 18 ...
deck =: 0 1 swap deck
51 24 14 18 ...

Это не совсем «по ссылке», но в J. нет реальных функций.

Мы будем использовать length ( #deck), чтобы избежать использования константы.

Полная программа на J:

deck =: 52 ? 52                           NB. Initial random deck
swap =: 4 : 'deck =: (x { y) (|.x) } y'   NB. Given swap "function"
f =: 3 : 0                                NB. function that calls the swap for a pair
({.y) swap deck
}.y
)
f^:(#deck) (,.,.[:,.]+[:?[:|.>:) i.#deck

3

C #

Вот мой собственный ответ, основанный на алгоритме Фишера-Йейтса . Должен дать вам идеальную случайность, если ваш генератор случайных чисел достаточно хорош.

Английская версия:

  1. Неоднократно меняйте местами карту deck[0]с той deck[v], где vнаходится номинальная стоимость карты deck[0]. Повторять доv == 0 . Это будет частично сортировать колоду, но это не имеет значения. Теперь вы знаете, что карта 0 находится в передней части колоды, что означает, что вы можете украсть это пространство в массиве и использовать его в качестве счетчика циклов. Это ключевой «чит» для проблемы локальных переменных.
  2. Начиная с позиции 1 (вторая карта в колоде), поменяйте карту на iс той, что в rand(i, 51). Обратите внимание, что вам нужно rand(i, 51), а не rand(1, 51) . Это не гарантирует, что каждая карта рандомизирована.
  3. Установить deck[0]на 0. Теперь вся колода перемешивается для первой карты , за исключением, так свопа deck[0]с , deck[rand(0, 51)]и вы сделали.

Версия C #:

public static void shuffle(int[] deck)
{
    while (deck[0] > 0)
        swap(ref deck[0], ref deck[deck[0]]);

    for (deck[0] = 1; deck[0] < 52; deck[0]++)
        swap(ref deck[deck[0]], ref deck[rand(deck[0], 51)]);

    deck[0] = 0;
    swap(ref deck[0], ref deck[rand(0, 51)]);
}

Версия Javascript:

while (deck[0] > 0)
    swap(0, deck[0]);

for (deck[0] = 1; deck[0] < 52; deck[0]++)
    swap(deck[0], rand(deck[0], 52));

deck[0] = 0;
swap(0, rand(0, 52));

... где swap(a, b)обмен deck[a]с deck[b].


2

Рубин, одна строка

Это считается обманом? Это должно быть настолько случайным, насколько это возможно.

deck=(0..51).to_a # fill the deck
deck[0..51] = (0..51).map{deck.delete_at(rand deck.length)}

( randМетод Руби принимает только один аргумент, а затем генерирует число n такое, что 0 <= число <аргумент.)

Дополнительно - похоже на Perl-решение sogart, но, насколько я знаю, оно не страдает от проблемы:

deck = deck.sort_by{rand}

Сортировка Ruby sort_by отличается от sort - сначала она генерирует список значений, по которым сортируется массив, и только затем сортирует его по ним. Быстрее найти свойство, по которому мы сортируем, быстрее, во всех остальных случаях - немного медленнее. Это также полезно в коде гольф: P


Я бы не назвал это мошенничеством, как таковым, но deck[0..51]в некоторой степени игнорирует правило «без переменных», используя особенность языка. Это справедливо, я просто думаю, что это теряет некоторые проблемы. :) Я не знаю Руби; можешь объяснить (0..51).map{deck.delete_at(rand deck.length)}часть? Это удаляет карты из deck?
Джастин Морган

@JustinMorgan да, 52 раза он удаляет случайную карту deckи добавляет ее во внутренний список результатов, который mapнакапливается. Тогда , когда не осталось ничего в deckв mapрезультате получает копируется deck. По сути, это временный объект, но это языковая функция, а не явная переменная :)
hobbs

deck.sort_by!{rand}короче
Эрик

1

JavaScript

ПРИМЕЧАНИЕ. Технически это решение некорректно, поскольку iв вызове используется второй параметр shuffle, который считается внешней переменной.

function shuffle(deck, i) {
    if (i <= 0)
        return;
    else {
        swap(deck[rand(0,i-1)], deck[i-1]);
        shuffle(deck, i - 1);
    }
}

Позвонить с shuffle(deck,52)

Полный рабочий пример (пришлось swapнемного изменить, потому что в JavaScript нет передачи по ссылке):

function rand(min, max) { return Math.floor(Math.random()*(max-min+1)+min); }
function swap(deck, i, j) {
    var t=deck[i];
    deck[i] = deck[j];
    deck[j] = t;
}

function shuffle(deck, i) {
    if (i <= 0)
        return;
    else {
        swap(deck, rand(0,i-1), i-1);
        shuffle(deck, i - 1);
    }
}

// create deck
var deck=[];
for(i=0;i<52;i++)deck[i]=i;
document.writeln(deck);
shuffle(deck,52);
document.writeln(deck);

Отлично сработано. То, что я имел в виду, рассматривал параметры shuffleкак переменные, но я не указал это так +1. Хорошее использование рекурсии тоже.
Джастин Морган

-1, не генерирует все перестановки, это очевидно, потому что элемент 51 никогда не займет свое первоначальное место, и потому что вы вызываете rand достаточно для генерации 51! перестановки из возможных 52!
аааааааааааа

2
@eBusiness: В оригинальной спецификации колода упорядочена произвольно, не обязательно в порядке 1-52. Я просто использовал это, потому что это было проще всего.
mellamokb

1
@eBusiness: я изменил, чтобы позволить возможность оставить элемент в том же месте, используя deck[rand(0,i-1)]вместо deck[rand(0,i-2)]. Также поменяйте местами весь путь i=0вместо того, чтобы останавливаться на i=1. Это помогает?
мелламокб

Да, это должно быть сделано, за исключением того, что теперь вы нарушаете спецификацию XOR swap.
aaaaaaaaaaaa

1

C ++

#include <cstdlib>
#include <ctime>
#include <iostream>

int deck[52];

void swap(int a, int b) {
    deck[a] ^= deck[b];
    deck[b] ^= deck[a];
    deck[a] ^= deck[b];
}

int r(int a, int b) {
    return a + (rand() % (b - a + 1));
}

void s(int *deck) {
    swap(1, r(2, 51));
    deck[0] *= 100;

    for(deck[0] += 2; (deck[0] % 100) < 51; deck[0]++) {
        swap(deck[0] % 100,
          r(0, 1) ? r(1, (deck[0] % 100) - 1) : r((deck[0] % 100) + 1, 51));
    }
    swap(51, r(1, 50)); 

    deck[0] = (deck[0] - 51) / 100;
    swap(r(1, 51), 0);
}

int main(int a, char** c)
{
    srand(time(0));

    for (int i = 0; i < 52; i++)
        deck[i] = i;

    s(deck);
    s(deck);

    for (int i = 0; i < 52; i++)
        std::cout << deck[i] << " ";
}

Избегает обмена элементами между собой, поэтому должен вызываться дважды, чтобы быть случайным.


swap(deck[rand(1, 51)], (deck[0] - 51) / 100);Как swapузнать, где поставить второе значение? Вы также пропускаете ).
Джастин Морган

Ой, спасибо. Я начал перемещать эту часть во время пересмотра и, должно быть, отвлекся, прежде чем закончить: P
Мэтью Рид

Даунвейт не от меня, кстати. Я проверю, когда смогу.
Джастин Морган

OK. Я упростил тестирование, предоставив полную программу.
Мэтью Прочитал

1
Очень умно. Мое собственное решение используется deck[0], но не так, как вы.
Джастин Морган


1

Другое решение Perl, которое фактически производит равномерно распределенный вывод:

sub shuffle_integers {
    map int, sort {$a-int $a <=> $b-int $b} map $_+rand, @_;
}

say join " ", shuffle_integers 1 .. 52;

Это решение использует Perl rand, который возвращает случайное число x в диапазоне 0 ≤ x <1. Он добавляет такое случайное число к каждому целому числу на входе, сортирует числа по дробным частям и, наконец, удаляет эти дробные части снова ,

(Я считаю , что использование специальных переменных $_, $aи $bпадает в духе вызов, так как те , как Perl проходит вход в mapи sort, и они не используются для других целей , в коде. В любом случае, я считаю , они на самом деле псевдонимы для входных значений, а не независимые копии Это фактически не перетасовка на месте, хотя,. , как mapи sortсоздавать копии входа в стеке).


1

Джава

Я удивлен, что никто не указал очевидное: (Я предполагаю, что swap (x, x) ничего не делает.

    static void shuffle(){
        swap(1,rand(0,1));
        swap(2,rand(0,2));
        swap(3,rand(0,3));
        swap(4,rand(0,4));
        swap(5,rand(0,5));
        swap(6,rand(0,6));
        swap(7,rand(0,7));
        swap(8,rand(0,8));
        swap(9,rand(0,9));
        swap(10,rand(0,10));
        swap(11,rand(0,11));
        swap(12,rand(0,12));
        swap(13,rand(0,13));
        swap(14,rand(0,14));
        swap(15,rand(0,15));
        swap(16,rand(0,16));
        swap(17,rand(0,17));
        swap(18,rand(0,18));
        swap(19,rand(0,19));
        swap(20,rand(0,20));
        swap(21,rand(0,21));
        swap(22,rand(0,22));
        swap(23,rand(0,23));
        swap(24,rand(0,24));
        swap(25,rand(0,25));
        swap(26,rand(0,26));
        swap(27,rand(0,27));
        swap(28,rand(0,28));
        swap(29,rand(0,29));
        swap(30,rand(0,30));
        swap(31,rand(0,31));
        swap(32,rand(0,32));
        swap(33,rand(0,33));
        swap(34,rand(0,34));
        swap(35,rand(0,35));
        swap(36,rand(0,36));
        swap(37,rand(0,37));
        swap(38,rand(0,38));
        swap(39,rand(0,39));
        swap(40,rand(0,40));
        swap(41,rand(0,41));
        swap(42,rand(0,42));
        swap(43,rand(0,43));
        swap(44,rand(0,44));
        swap(45,rand(0,45));
        swap(46,rand(0,46));
        swap(47,rand(0,47));
        swap(48,rand(0,48));
        swap(49,rand(0,49));
        swap(50,rand(0,50));
        swap(51,rand(0,51));
    }

ОК, хорошо, это может быть короче:

package stackexchange;

import java.util.Arrays;

public class ShuffleDry1
{
    static int[] deck = new int[52];

    static void swap(int i, int j){
        if( deck[i]!=deck[j] ){
            deck[i] ^= deck[j];
            deck[j] ^= deck[i];
            deck[i] ^= deck[j];
        }
    }

    static int rand(int min, int max){
        return (int)Math.floor(Math.random()*(max-min+1))+min;
    }

    static void initialize(){
        for( int i=0 ; i<deck.length ; i++ ){
            deck[i] = i;
            swap(i,rand(0,i));
        }
    }

    static void shuffle(){
        while( deck[0]!=0 ) swap(0,deck[0]);
        for( deck[0]=52; deck[0]-->1 ; ) swap(deck[0],rand(deck[0],51));
        swap(0,rand(0,51));
    }

    public static void main(String[] args) {
        initialize();
        System.out.println("init: " + Arrays.toString(deck));
        shuffle();
        System.out.println("rand: " + Arrays.toString(deck));
    }

}

1

бурлеск

Что вы на самом деле просите, так это случайную перестановку списка целых чисел? r@даст нам все перестановки, и мы просто выберем случайную.

blsq ) {1 2 3}r@sp
1 2 3
2 1 3
3 2 1
2 3 1
3 1 2
1 3 2
blsq ) {1 2 3}r@3!!BS
2 3 1

Поскольку нам нужна настоящая случайность, то, что Бурлеск не в состоянии сделать, потому что Бурлеск не имеет функциональных возможностей ввода / вывода, вам нужно было бы предоставить какой-то источник случайности через STDIN.

Это, вероятно, что-то, что я исправлю в более поздней версии (то есть создаю случайное начальное число при запуске и помещаю его во вторичный стек или что-то в этом роде, но сам Burlesque Interpreter не имеет ввода-вывода).


0

Javascript

Я не уверен, что это «обман», но мое решение использует собственный локальный массив аргументов функции. Я включил свои самодельные функции rand() swap()и filldeck(). Интересно отметить, что это должно работать с колодой любого размера.

    var deck = [];

    function shuffle(){
        main(deck.length);
    }

    function main(){
        arguments[0] && swap( arguments[0]-=1, rand(0, deck.length-1) ), main(arguments[0]);
    }

        function rand(min, max){
            return Math.floor( Math.random()*(max-min+1) )+min;
        }

        function swap(x, y){
            var _x = deck[x], _y = deck[y];
            deck[x] = _y, deck[y] = _x;
        }


        function filldeck(dL){
            for(var i=0; i<dL; i++){
                var ran = rand(1,dL);
                while( deck.indexOf(ran) >= 0 ){
                    ran = rand(1,dL);
                }
                deck[i] = ran;
            }
        }

    filldeck(52);
    shuffle();

Это обман, я думаю. Тем не менее, это очень умный обман, такая хорошая работа.
Джастин Морган

0

Tcl , 32 байта

Злоупотребления time функцией, которая служит для измерения того, сколько времени затрачивается на выполнение сценария, но также может служить циклическим механизмом без объявления каких-либо переменных.

time {lswap $D [rand] [rand]} 52

Попробуйте онлайн!


Я прав, что это выполняет только 52 случайных перестановки? Этого недостаточно для настоящей случайности. Я запустил его несколько раз и насчитал в среднем 8 карт, которые все еще находятся на своих начальных позициях, и вероятность этого при истинном перемешивании составляет около 9x10 ^ -6 .
Джастин Морган,

@JustinMorgan: Не могли бы вы объяснить, как лучше рассчитать вероятность?
sergiol

-1

Perl - это не правильное перемешивание, как описано в комментариях!

my @deck = (0..51);
@deck = sort {rand() <=> rand()} @deck;
print join("\n",@deck);

Я думаю, что я ничего не использовал в качестве подкачки и т. Д. Это было необходимо как часть проблемы?


4
Это сработало бы, если бы сортировка по случайной функции была способом получения равномерного случайного распределения. Однако это не так. -1
аааааааааааа

а почему нет? не могли бы вы дать мне ссылку для чтения ???
Согарт

2
Качество результата будет сильно различаться в зависимости от алгоритма сортировки, но почти во всех случаях результат будет очень далек от случайной функции с равным распределением. Вот статья на эту тему: sroucheray.org/blog/2009/11/…
aaaaaaaaaaaa

-1

JavaScript 4 строки

function shuffle() {
  while(deck[0]!=0)swap(deck[0],rand(1,51))
  while(deck[0]++!=104)swap(deck[0]%51+1,rand(1,51))
  deck[0]=0
  swap(0,rand(0,51))
}

Оригинальный ответ, который не был достаточно случайным. Своп не гарантировал прикосновения к каждому предмету в колоде.

// shuffle without locals
function shuffle() {
  deck.map(function(){swap(deck[rand(0,51)],deck[rand(0,51)])});
}

Не производит настоящий случайный случайный порядок. Вот тест визуализатора: jsfiddle.net/muk1bthm . Я shuffleнемного изменил ваш код, чтобы он соответствовал моей swapреализации, но здесь он дословно: jsfiddle.net/m7km4u6g
Джастин Морган

Чтобы уточнить, приведенный выше комментарий относится к новой версии, которая все еще не случайна.
Джастин Морган
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.