Matrice casuale senza ripetizione


16

Stavo rispondendo a una sfida qui e questo compito faceva parte della sfida. Ho una soluzione di 73 byte in javascript. Ma penso che sia troppo per una cosa semplice.

Sfida

Dato come input due numeri interi:

  • N la lunghezza dell'array previsto
  • Rl'intervallo dell'intervallo inizia in uno:, 1..Rno0..R-1

Emette in ogni esecuzione del tuo programma / funzione un diverso array di lunghezza Ncon valori 1..Rin modo tale che nessun valore si presenti più di una volta.

Devi usare R-valuenel tuo codice.

restrizioni

Si può assumere: 2 <= N <= R.

Mi piacerebbe davvero vedere una soluzione javascript più corta dei miei 73 byte.

Ma ovviamente è aperto a tutte le lingue!

Se la tua lingua non può restituire un array, puoi stampare tutti i numeri;)


2
Un'altra cosa: non penso che tu voglia che siano diversi ad ogni corsa, ma semplicemente uniformemente casuali? (Altrimenti non funzionerebbe per R=N=1) Quindi consiglio di lasciare le gamme 0..Rcome alternativa in quanto questo diventa più naturale in molte lingue.
flawr

Consiglierei che ogni permutazione sia ugualmente probabile (presupponendo una casualità perfetta), altrimenti posso fareshuffle(0..N)
Nathan Merrill

Ho pubblicato la mia risposta di qualità casuale non uniforme prima di apportare la modifica della regola.
Conor O'Brien,

1
Dici una soluzione uniformemente casuale, ma new Dateproduce valori non uniformi. Inoltre, credo che tu possa giocare a golf new Date%r+1;)
Conor O'Brien,

L'array di output deve essere numeri interi? Sembra ovvio, ma non lo vedo esplicitamente dichiarato
Charlie Wynn il

Risposte:


16

Dyalog APL, 1 byte

?

Solo un built-in. Provalo qui .


3
Con una risposta come questa, ho dovuto scorrere indietro per vedere se eri il PO
lbstr

2
@lbstr Ora che me lo dici, il mio identicon è abbastanza simile a quello di OP.
lirtosiast

9

JavaScript (ES6), 68 66 byte

n=>r=>G=(s=new Set)=>s.size<n?G(s.add(Math.random()*r+1|0)):[...s]

Chiamato come F(N)(R)(), dove si Ftrova l'assegnazione della funzione e N/ Rsono i valori.

Hai richiesto meno di 73 byte in Js;)

EDIT: la risposta di @ C5H8NNaO4 funziona nel fatto che le regole non specificano che i valori devono essere uniformi 1..R. Detto questo, ecco una versione che funziona in 63 byte (chiamata come F(R)(N)):

r=>G=(n,s=[])=>n--?G((s[n]=n+1,n),s):s.sort(a=>new Date/a%1-.5)

Amico, questo è impressionante !! +1
rimosso il

@WashingtonGuedes Thanks =) Appena rasato altri 2 byte.
Mwr247,

7

Ottava, 22 19 9 byte

@randperm

randperm(r,n)fa esattamente ciò che è richiesto. Nota che questo non funziona (almeno non nelle versioni precedenti) in Matlab.


1
@(n,r)randperm(r,n)
Luis Mendo,

1
randpermcon due input funziona nelle recenti versioni di Matlab. C'è anche randsample, ma ci vogliono più byte, a meno che tu non possa sbarazzarti del @(...)(penso che sia permesso)
Luis Mendo,

Oh, posso usare @randperm=)
flawr

5

TI-84 BASIC OS 4.0, 12 byte

Prompt N,R:randIntNoRep(1,R,N

La TI-84 + CSE (2013) e la CE (2015) sono essenzialmente lo stesso dialetto BASIC limitato della TI-84 +, ma ci sono alcune nuove funzionalità. Uno di questi è il terzo argomento di randIntNoRep.


1
Francamente, è un po 'sciocco che non abbiano incluso quella caratteristica fin dall'inizio.
SuperJedi224,

Ho subito pensato a TI-Basic quando ho visto questa sfida :)
Timtech,

5

MATL , 2 byte

Zr

Gli input sono: prima R, quindi N.

Provalo online!

Spiegazione

La funzione Zraccetta due input (implicitamente in questo caso) ed esegue un campionamento casuale senza sostituzione. Il primo input, Rspecifica che la popolazione è [1,2,...,R]; e il secondo input, Nindica il numero di campioni da prelevare dalla popolazione.



4

Pyth, 6 byte

<.SSQE

Provalo qui!

La distanza arriva sulla prima riga e la lunghezza sulla seconda.

Spiegazione

<.SSQE # Q = intervallo, E = lunghezza

   SQ # genera l'intervallo 1 ... Q
 .S # rimescola l'elenco
<E # prende i primi elementi E.

Versione a 5 byte non competitiva

L'ultima aggiunta a Pyth aggiunge Q, se necessario, impliciti alla fine del programma. Possiamo usarlo qui invertendo il formato di input, quindi la lunghezza viene prima e poi l'intervallo.

<.SSE

Provalo qui!

Ecco El'intervallo, che trasformiamo in un elenco basato su 1 S, lo mescoliamo con .Se prendiamo i primi Qelementi con <. <si aspetta un numero intero che viene aggiunto implicitamente con a Q.


4

Reng v.2.1, 140 103 98 97 byte

Questo dovrebbe funzionare anche nelle versioni precedenti.

v      v      $/$'l#y0#z>(:)):(ez+#z zt>a$;!
>i#ci#x>cu1+lxetv    j21\!q   yy#-1y($/^
>n?~v
^oW <

Puoi provarlo qui! L'input è maximum length, come ad esempio 10 3.

Sono così orgoglioso di questo, non lo sai nemmeno. Se qualcuno mi batte con una risposta Java, questo renderà la mia giornata. Se ho battuto una risposta Java, considera anche la mia giornata fatta.

Lo spiegherò più tardi, una volta guarito. In generale, però:

v         v      $/$r$
>i#bbi1+#x>:u1+lxet

Questo genera i numeri casuali. L'altra parte controlla se ci sono duplicati e, se ci sono, il processo viene ripetuto. Altrimenti, i risultati vengono stampati, con spazi che uniscono i risultati.

Ecco alcuni esempi:

long gif


3

CJam, 8 byte

{,:)mr<}

Provalo qui!

Questo è un blocco senza nome che prevede l'intervallo in cima alla pila e la lunghezza in fondo e lascia un elenco sulla pila.

Spiegazione

, intervallo basato su e # 0
:) e # inkrement ogni elemento dell'elenco in modo che sia basato su 1
mr e # rimescola l'elenco
<e # accetta i primi n elementi

Questo è un programma felice :)
Conor O'Brien,

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Sarei più felice se CJam avesse un built-in per intervalli basati su 1, quindi non avrei bisogno di questo smiley damm: P
Denker

2

Lisp comune, 90

52 solo per l'espressione

(use-package :alexandria)(lambda(R N)(coerce(subseq(shuffle(iota R :start 1))0 N)'vector))

Ungolfed

;; Well known library
(use-package :alexandria)

(lambda(R N)
  (coerce                   ; make a vector from a list 
    (subseq                 ; take the sublist from 0 to N
      (shuffle              ; shuffle a list
        (iota R :start 1))  ; build a list from 1 to R
    0 N)
    'vector))

Come altre risposte, se non conto use-package e lambda , l'espressione rimanente è (coerce(subseq(shuffle(iota R :start 1))0 N)'vector), per 52 byte.


2

Rubino, 27 23 byte

Funzione anonima, ragionevolmente breve e dolce.

-4 byte da @manatwork

->n,r{[*1..r].sample n}

->n,r{[*1..r].sample n}Utilizzare il markup del blocco di codice anziché il markup del codice incorporato, in modo che script come Code Golf UserScript Enhancement Pack possano inserire la dimensione del codice accanto ad esso.
arte

Va bene, ora è stato risolto.
Valore inchiostro

2

𝔼𝕊𝕄𝕚𝕟, 10 caratteri / 13 byte

Ѩŝ⩤⁽1í)ą-î

Try it here (Firefox only).

Spiegazione

           // implicit: î=input1, í=input2
  ⩤⁽1í)    // Inclusive range from 1 to í
Ѩŝ         // Shuffle resulting range
       ą-î // Get last îth items

2

Bash + coreutils, 16

Penso che questo sia autoesplicativo:

seq $2|shuf -n$1

Input Ne Rcome parametri della riga di comando.

O come sottolinea @rici, per lo stesso punteggio:

shuf -n$1 -i1-$2

Ideone.


1
o shuf -n$1 -i1-$2(stessa lunghezza, però).
rici,

@rici molto bello. molto pulito :)
Digital Trauma,

1

PowerShell v2 +, 30 byte

param($n,$r)1..$r|Random -c $n

Prende l'input $ne $r, costruisce un intervallo 1..$r, i tubi che Get-Randomcon una -Concia di $n, che selezionerà $nelementi unici dall'intervallo. L'output viene lasciato sulla pipeline come un array implicito.


1

Scherzi a parte, 5 byte

,,R╨J

Provalo online!

Spiegazione:

,,R╨J
,,R    push N, range(1, R+1)
   ╨   push a list containing all N-length permutations of range(1, R+1)
    J  select a random element from the list

1

Clojure, 38 byte

#(take %1(shuffle(map inc(range %2))))

Una funzione anonima che prende N per primo e R per secondo.


1

Perl 6, 32 byte

{(^$^a).permutations.pick[^$^b]}

1

Python 3.5 - 54 53 byte:

from random import*;lambda a,c:sample(range(1,c+1),a)

Questo utilizza la sample()funzione del modulo casuale per restituire un array con lunghezza "a" costituito da elementi casuali e unici nell'intervallo 1 => c.


1

D, 29 byte (solo espressione)

Supponendo che std.random e std.range siano stati importati e che n e r siano definiti come variabili, il programma può essere risolto nella singola espressione:

iota(1,r).randomCover.take(n)

1

ES6, 72

r=>n=>[...Array(-~r).keys()].sort(a=>new Date/a%1-.5).filter(a=>a&&n-->0)

Come nella risposta di @ Mwr247 , puoi chiamarlo F(R)(N), Fessendo l'espressione della funzione


0

Mathcad, 67 "byte"

crea un vettore di colonna di numeri interi consecutivi nell'intervallo 1..R, lo unisce a un vettore di colonna di lunghezza R di numeri casuali (uniformi), ordina la matrice Rx2 risultante sulla colonna di numeri casuali, quindi estrae i primi n numeri dal colonna casuale di numeri interi.

enter image description here


C'è un posto in cui possiamo provarlo?
Conor O'Brien,

Puoi scaricare le versioni di prova di Mathcad 15 e Mathcad Prime 3.1 (il successore di Mathcad 15). Entrambe le prove durano 30 giorni, dopodiché M15 smette di funzionare, ma Prime 3.1 funziona ancora, sebbene con funzionalità ridotta (ad es. Nessuna programmazione, quindi quanto sopra non funzionerà ... ma il ciclo for può essere riscritto per usare le variabili di intervallo per creare v al di fuori della dichiarazione di aumento)
Stuart Bruff

Le versioni di prova sono disponibili su: Matcad 15 - ptc.com/engineering-math-software/mathcad/free-trial ; Mathcad Prime 3.1 - ptc.com/engineering-math-software/mathcad/free-download
Stuart Bruff

E come si contano questi byte?
R

Osservandolo dal punto di vista dell'input dell'utente ed equiparando un'operazione di input di Mathcad (in genere tastiera, fare clic con il mouse sulla barra degli strumenti se non è presente un collegamento kbd) a un carattere e interpretarlo come un byte. csort = 5 byte come viene digitato carattere per carattere come lo sono altri nomi di variabili / funzioni. L'operatore for è un costrutto speciale che occupa 11 caratteri (inclusi 3 "segnaposto" vuoti e 3 spazi) ma è inserito da ctl-shft- #, quindi = 1 byte (simile ai token in alcune lingue). Digitando '(virgolette) si creano parentesi bilanciate (di solito), quindi conta come 1 byte. Indicizzazione v = 3 byte (tipo v [k).
Stuart Bruff,

0

Python, 56 (il modo ovvio)

lambda N,R:__import__('random').sample(range(1,R+1),k=N)

from random import*;lambda N,R:sample(range(1,R+1),k=N)è più corto di un byte
Mego

Huh, ho pensato from random import*, deve aver rovinato il conteggio.
Shooqie,

0

Perl 5, 51 43 byte

sub{@a=1..pop;map{splice@a,rand@a,1}1..pop}

Sottotitoli anonimi piuttosto semplici che generano un array da 1 a R e quindi uniscono N elementi casuali da restituire. Chiama con ->(N, R).


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.