Mischia un mazzo senza variabili locali [chiuso]


14

Lo scopo di questo puzzle è prendere un mazzo di 52 carte e mescolarlo in modo che ogni carta sia in una posizione casuale.

Dato:

  • Un array, deckdi 52 interi distinti che rappresentano le carte. Quando inizi, deckcontiene esattamente una di ogni carta in un ordine sconosciuto.
  • Una funzione, int rand(min, max)che restituisce un numero intero casuale tra ints mine max, compreso. Puoi presumere che questa funzione sia veramente casuale.
  • Una funzione void swap(x, y)che scambia due carte nel mazzo. Se chiami swap(x, y), le carte in posizioni xe ycambieranno posto.

Quando:

  • Il programma chiama shuffle()(o shuffle(deck)o deck.shuffle()comunque l'esecuzione della tua implementazione),

Poi:

  • deck dovrebbe contenere esattamente una di ogni carta in ordine perfettamente casuale.

La presa:

Non puoi dichiarare alcuna variabile. Chiama swape randquanto vuoi, ma non puoi dichiarare alcuna tua variabile. Ciò include i forcontatori di loop - anche quelli impliciti come in a foreach.

chiarimenti:

  • È possibile modificare i dettagli minori in base alla lingua scelta. Ad esempio, puoi scrivere swapper cambiare due numeri interi come riferimento. Le modifiche dovrebbero essere per rendere questo lavoro con la tua lingua, non per facilitare il puzzle.
  • deck può essere una variabile globale oppure puoi prenderla come parametro.
  • Puoi fare tutto quello che vuoi sul contenuto di deck, ma non puoi cambiarne la lunghezza.
  • Le tue carte possono essere numerate 0-51, 1-52 o qualsiasi altra cosa tu voglia.
  • Puoi scriverlo in qualsiasi lingua, ma senza barare con la shufflefunzione integrata della tua lingua .
  • Sì, potresti scrivere la stessa riga 52 volte. Nessuno sarà impressionato.
  • Il tempo di esecuzione non ha importanza, ma la vera casualità lo è.
  • Questo non è in realtà un codice golf, ma sentiti libero di minimizzare / offuscare il tuo codice.

Modifica: codice della caldaia e visualizzatore

Se hai utilizzato .NET o JavaScript, ecco alcuni codici di test che potresti trovare utili:

JavaScript:

C #:

Questo codice ordina e mescola il mazzo diverse migliaia di volte ed esegue alcuni test di sanità mentale di base: per ogni shuffle, verifica che ci siano esattamente 52 carte nel mazzo senza ripetizioni. Quindi il visualizzatore traccia la frequenza di ciascuna carta che finisce in ogni punto del mazzo, mostrando una mappa di calore in scala di grigi.

L'output del visualizzatore dovrebbe apparire come neve senza alcun motivo apparente. Ovviamente non può dimostrare la vera casualità, ma è un modo rapido e semplice per effettuare controlli a campione. Raccomando di usarlo o qualcosa del genere, perché alcuni errori nell'algoritmo di shuffling portano a schemi molto riconoscibili nell'output. Ecco un esempio dell'output di due implementazioni, una con un difetto comune:

Uscita del visualizzatore

La versione difettosa mescola parzialmente il mazzo, quindi potrebbe sembrare soddisfacente se si esamina l'array a mano. Il visualizzatore rende più semplice notare un motivo.


Molte lingue modellano le matrici come effettivamente infinite, permettendo così di usare $ deck [52] e successivi al posto delle variabili locali. Forse anche questo dovrebbe essere proibito.
Timwi

2
Le funzioni sono considerate variabili? i parametri di funzione sono considerati variabili?
zzzzBov

1
@zzzzBov - Quello che avevo in mente era che i parametri della funzione sarebbero stati considerati variabili, ma non l'ho specificato prima della risposta di @ mellamokb. So che può essere fatto senza parametri diversi da deckse stesso.
Justin Morgan,

1
@eBusiness - Questo è un problema per me, non per la domanda stessa. E stavo votando perché il rispondente ha trovato una scappatoia.
Justin Morgan,

1
@utente sconosciuto - Penso di aver capito. La risposta è fondamentalmente che puoi assumere qualunque implementazione swapdesideri, purché soddisfi il suo scopo fondamentale. Parte della mia ragione per fare swapun dato era che le persone potessero trattarlo come "magico" e concentrarsi sul problema principale senza doversi preoccupare che funzionasse nella loro lingua preferita. Puoi farlo o scrivere il tuo swap, dipende da te.
Justin Morgan,

Risposte:


9

JavaScript

Credo che questa sia la forma di soluzione prevista, uso la carta in posizione 0 per tenere traccia dei progressi, mescolando solo le carte che sono già state usate come contatore, questo raggiunge lo standard 52! permutazioni con una perfetta distribuzione uguale. La procedura è complicata dallo scambio XOR che non consente che un elemento venga scambiato da solo.

Modifica: ho creato un ordinamento che ordina ogni elemento in posizione appena prima che venga utilizzato, consentendo così a questo di funzionare con un array non ordinato. Ho anche abbandonato la chiamata ricorsiva a favore di un ciclo 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>")
}

Questo è esattamente quello che avevo in mente. Non appena provo questo, voterò e probabilmente accetterò.
Justin Morgan,

Sembra funzionare bene, anche se a un esame più attento non è esattamente lo stesso del mio. Accettato e presto pubblicherò la mia risposta.
Justin Morgan,

Questo è anche noto come algoritmo Knuth shuffle ( en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle ).
Bob,

14

Haskell

Ecco un'implementazione senza punti. Nessuna variabile, parametri formali o ricorsione esplicita. Ho usato lambdabot s' @pl( 'inutile') caratteristica refactoring un bel po'.

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]

Ecco la mia procedura di test per assicurarsi che i numeri siano stati distribuiti uniformemente:

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

Ecco l'algoritmo originale:

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 per Haskell. Ora devo imparare Haskell in modo da poterlo leggere. : P
Justin Morgan,

Come vengono memorizzati i progressi?
aaaaaaaaaaaa

8
Dubito che chiunque, tranne i programmatori di Haskell, dirà che il loro codice è inutile e ne sarà orgoglioso.
aaaaaaaaaaaa

4
Questo ((.) .) . (. (++))e questo (((.) . (,)) .)sono i miei preferiti. Wow lambdabot. Solo wow.
Dan Burton,

2
@eBusiness "point free" non è affatto lo stesso di "inutile".
Fredoverflow

6

J

Ignorare quel mazzo è una variabile, c'è l'ovvio ...

52 ? 52

Naturalmente, se vuoi davvero una funzione, c'è questo, che funzionerà anche se dimentichi di rimuovere i jolly (o provi a mescolare qualcosa di diverso dalle carte).

{~ (# ? #)

Così che...

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

Questo è probabilmente al di fuori dell'intenzione della domanda, che sarebbe quella di implementare il shuffle da rand ( ?). Potrei farlo più tardi quando non dovrei lavorare.

Spiegazione

Spiegazione di 52 ? 52:

  • x ? y è x oggetti unici casuali da y.

La spiegazione di {~ (# ? #)è più difficile a causa di forchette e ganci . Fondamentalmente, è lo stesso di shuffle =: 3 : '((# y) ? (# y)) { y', che ha un argomento implicito ( y).

  • # y indica la lunghezza di y
  • Questo dà 52? 52 come prima, che è una permutazione casuale di 0..51
  • x { y è l'elemento di y nell'indice x o (in questo caso) gli elementi negli indici in x.
  • Ciò ti consente di mescolare qualsiasi cosa sia passata, non solo numeri interi.

Vedi J Vocabulary per i dettagli degli operatori, sebbene la sintassi e la semantica siano un po 'complicate a causa della programmazione di grado e tacita.


+1: Lavorare su code-golf quando si suppone che
funzioni

1
Puoi spiegare cosa fa questo per i non vedenti? Di recente ho sentito che è stata descritta come un'esplosione in una fabbrica di emoticon ( codegolf.stackexchange.com/questions/1294/anagram-code-golf/… ), che suona bene.
Justin Morgan,

@Justin: spiegazione aggiunta.
Jesse Millikan,

Questo funziona anche in APL. La sintassi è la stessa, quindi non mi preoccuperò di aggiungere una nuova risposta ( {52?⍵}è una funzione anonima che prende 52 elementi casuali dal suo argomento, che qui sarebbe un elenco di 52 numeri interi)
Arc676

4

Pitone

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))

Che cosa [1:]significa? Questo si basa su un sotto-array di deck?
Justin Morgan,

Sì, [1:] indica il subarray dall'indice 1 alla fine dell'array. Quindi mescola in modo ricorsivo tutto tranne il primo elemento, lo assegna (copia) nello stesso posto nella matrice originale, quindi posiziona in modo casuale il primo elemento da qualche parte.
Keith Randall,

Molto intelligente. Penso che questa sia una delle soluzioni più belle qui, e usi correttamente l'algoritmo Fisher-Yates. +1. Questo è stato un bel modo per me di vedere la bellezza delle lingue che non conosco.
Justin Morgan,

2
Potrebbe piacerti il a, b = b, atrucco.
Ray,

3

Usando la rappresentazione fattadica

Nella rappresentazione fattadica di una permutazione un elemento i assume valori da 0 a Ni. Quindi una permutazione casuale è solo rand(0,i)per ogni Ni.

In J:

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

dove ? xè rand(0,x-1)ed |.>:i.52è52 51 ... 1

Poi, se aè il valore di esimo factoradic, facciamo lo scambio: swap(deck[i], deck[i+a]). L'elenco delle coppie da scambiare sono:

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

Lo swap che useremo funziona in questo modo:

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

Non è veramente "per riferimento" ma non ci sono funzioni reali in J.

Useremo la lunghezza del mazzo ( #deck) per evitare di usare una costante.

Programma completo in 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 #

Ecco la mia risposta basata sull'algoritmo Fisher-Yates . Dovresti darti un shuffle perfetto se il tuo generatore di numeri casuali è abbastanza buono.

Versione inglese:

  1. Scambia ripetutamente la carta deck[0]con quella a deck[v], dove si vtrova il valore nominale della carta a deck[0]. Ripeti fino al v == 0. Questo ordinerà parzialmente il mazzo, ma non importa. Ora sai che la carta 0 è nella parte anteriore del mazzo, il che significa che puoi rubare quello spazio nell'array e usarlo come contatore di loop. Questa è la chiave "cheat" per il problema delle variabili locali.
  2. Partendo dalla posizione 1 (la seconda carta nel mazzo), scambia la carta icon quella a rand(i, 51). Si noti che è necessario rand(i, 51), NON rand(1, 51) . Ciò non garantirà che ogni carta sia randomizzata.
  3. Riporta deck[0]a 0. Ora l'intero mazzo viene mischiato ad eccezione della prima carta, quindi scambia deck[0]con deck[rand(0, 51)]e il gioco è fatto.

Versione 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)]);
}

Versione 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));

... dove swap(a, b)swap deck[a]con deck[b].


2

Ruby, una riga

Questo è considerato barare? Dovrebbe essere il più casuale possibile.

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

(Il randmetodo di Ruby accetta solo un argomento e quindi genera un numero n tale che 0 <= argomento <argomento.)

Inoltre, simile alla soluzione Perl di Sogart, ma per quanto ne so non soffre del problema:

deck = deck.sort_by{rand}

L'ordinamento di Ruby è diverso dall'ordinamento: genera innanzitutto l'elenco di valori per ordinare l'array e solo successivamente lo ordina per loro. È più veloce quando è costoso scoprire la proprietà che stiamo ordinando, un po 'più lenta in tutti gli altri casi. È anche utile nel codice golf: P


Non lo chiamerei barare, di per sé, ma in deck[0..51]qualche modo evita la regola "nessuna variabile" usando una caratteristica del linguaggio. È giusto, penso solo che perda parte della sfida. :) Non conosco Ruby; puoi spiegare la (0..51).map{deck.delete_at(rand deck.length)}parte? Questo elimina le carte da deck?
Justin Morgan,

@JustinMorgan sì, 52 volte elimina una carta a caso decke la aggiunge all'elenco interno dei risultati che si mapsta accumulando. Poi, quando non c'è più niente decknel maprisultato viene copiato in deck. Fondamentalmente c'è un temporaneo, ma è una caratteristica del linguaggio piuttosto che una variabile esplicita :)
hobbs

deck.sort_by!{rand}è più corto.
Eric Duminil,

1

JavaScript

NOTA: questa soluzione non è tecnicamente corretta poiché utilizza un secondo parametro i, nella chiamata a shuffle, che conta come una variabile esterna.

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

Chiama con shuffle(deck,52)

Un esempio di funzionamento completo (ha dovuto modificare swapleggermente perché non esiste un riferimento pass-by di ints in 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);

Molto bene. Quello che avevo in mente era considerare i parametri shufflecome variabili, ma non l'ho specificato così +1. Bello anche l'uso della ricorsione.
Justin Morgan,

-1, non genera tutte le permutazioni, questo è ovvio perché l'elemento 51 non occuperà mai il suo posto originale e perché chiami abbastanza rand da generare 51! permutazioni dal possibile 52!
aaaaaaaaaaaa

2
@eBusiness: nelle specifiche originali, il mazzo è arbitrariamente ordinato, non necessariamente nell'ordine 1-52. L'ho usato solo perché era il più semplice.
mellamokb,

1
@eBusiness: ho modificato per consentire la possibilità di lasciare l'elemento nello stesso punto, usando deck[rand(0,i-1)]invece di deck[rand(0,i-2)]. Scambia anche fino in fondo i=0invece di fermarti a i=1. Questo aiuta?
mellamokb,

Sì, dovrebbe farlo, tranne per il fatto che ora infrangi la specifica di scambio XOR.
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] << " ";
}

Evita di scambiare elementi con se stessi, quindi deve chiamare due volte per essere casuale.


swap(deck[rand(1, 51)], (deck[0] - 51) / 100);Come swapsaprà dove mettere il secondo valore? Ti manca anche a ).
Justin Morgan,

Oops, grazie. Ho iniziato a spostare quella parte durante una revisione e devo essermi distratto prima di finirla: P
Matthew Leggi il

Il downvote non era da parte mia, BTW. Proverò quando posso.
Justin Morgan,

OK. Ho semplificato il test fornendo un programma completo.
Matteo Leggi il

1
Molto intelligente. Ho usato la mia soluzione deck[0], ma non come hai fatto tu.
Justin Morgan,

1

D

shuffle(int[] d){
    while(d.length){
        if([rand(0,d.length-1)!=0)swap(d[0],d[rand(1,d.length-1)]);
        d=d[1..$];
    }
}

1

Un'altra soluzione Perl, che in realtà produce output distribuiti uniformemente:

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

say join " ", shuffle_integers 1 .. 52;

Questa soluzione utilizza Perl rand, che restituisce un numero casuale x nell'intervallo 0 ≤ x <1. Aggiunge un tale numero casuale a ciascun numero intero nell'input, ordina i numeri in base alle loro parti frazionarie e infine rimuove nuovamente quelle parti frazionarie .

(Credo che l'uso delle variabili speciali $_, $ae $bcade nello spirito della sfida, dal momento che questi sono come Perl passa l'ingresso mape sort, e non sono utilizzati per altri scopi nel codice. In ogni caso, credo sono in realtà degli alias per i valori di ingresso, non copie indipendenti Questo non è in realtà un riordino sul posto, anche se,., sia mape sortcreano copie di input sullo stack).


1

Giava

Sono sorpreso che nessuno abbia dichiarato l'ovvio: (suppongo che swap (x, x) non faccia nulla.

    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));
    }

OK, ok, può essere più breve:

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

burlesco

Quello che stai effettivamente chiedendo è una permutazione casuale di un elenco di numeri interi? r@ci darà tutte le permutazioni e ne selezioniamo solo una casuale.

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

Dal momento che abbiamo bisogno della vera casualità, qualcosa che Burlesque non è in grado di fare perché Burlesque non ha funzionalità I / O che dovresti fornire una fonte di casualità tramite STDIN.

Questo è probabilmente qualcosa che risolverò nella versione successiva (ovvero generare un seme casuale all'avvio e spingerlo nello stack secondario o qualcosa del genere, ma lo stesso Burlesque Interpreter non ha I / O).


0

Javascript

Non sono sicuro che si tratti di "barare", ma la mia soluzione utilizza l'array locale nativo degli argomenti di una funzione. Ho incluso le mie funzioni fatte da me rand() swap()e filldeck(). Di nota interessante, questo dovrebbe funzionare con un mazzo di qualsiasi dimensione.

    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();

È un imbroglio, penso. Tuttavia, è un imbroglio molto intelligente, quindi un bel lavoro.
Justin Morgan,

0

Tcl , 32 byte

timeFunzione di abuso che serve a misurare quanto tempo è in esecuzione uno script, ma può anche fungere da meccanismo di loop senza dichiarare alcuna variabile.

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

Provalo online!


Ho ragione che questo esegue solo 52 scambi casuali? Questo non è abbastanza per un vero shuffle. L'ho provato alcune volte e ho contato in media 8 carte ancora nelle loro posizioni iniziali, e la probabilità di farlo con un mischiato vero è di circa 9x10 ^ -6 .
Justin Morgan,

@JustinMorgan: Puoi spiegarmi meglio il calcolo delle probabilità?
sergiol,

-1

perl - questo non è uno shuffle corretto come spiegato nei commenti!

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

Penso di non aver usato nulla come scambio, ecc. Era necessario come parte del problema?


4
Funzionerebbe se l'ordinamento per funzione casuale fosse un modo per produrre una distribuzione anche casuale. Tuttavia non lo è. -1
aaaaaaaaaaaa

e perché no? potresti darmi un link per leggere ???
sogart

2
La qualità del risultato varierà notevolmente a seconda dell'algoritmo di ordinamento, ma in quasi tutti i casi il risultato sarà molto lontano da una funzione casuale di uguale distribuzione. Ecco un articolo sull'argomento: sroucheray.org/blog/2009/11/…
aaaaaaaaaaaa

-1

JavaScript 4 righe

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))
}

Risposta originale che non era abbastanza casuale. Lo swap non è stato garantito per toccare ogni oggetto nel mazzo.

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

Non produce un vero shuffle casuale. Ecco un test del visualizzatore: jsfiddle.net/muk1bthm . Ho modificato shuffleleggermente il codice per adattarlo alla mia swapimplementazione, ma qui è testualmente: jsfiddle.net/m7km4u6g
Justin Morgan,

Per chiarire, il commento sopra si applica alla nuova versione, che non è ancora casuale.
Justin Morgan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.