Zufälliges Array ohne Wiederholung


16

Ich habe hier eine Herausforderung beantwortet und diese Aufgabe war Teil der Herausforderung. Ich habe eine 73-Byte-Lösung in Javascript. Aber ich denke, es ist zu viel für eine einfache Sache.

Herausforderung

Als Eingabe zwei Ganzzahlen gegeben:

  • N die Länge des erwarteten Arrays
  • RDer Intervallbereich beginnt mit eins:, 1..Rnicht0..R-1

Geben Sie in jedem Lauf Ihres Programms / Ihrer Funktion ein anderes Array von Längen Nmit Werten aus, zwischen denen 1..Rkein Wert mehr als einmal vorkommt.

Sie müssen R-valuein Ihrem Code verwenden.

Beschränkungen

Sie können davon ausgehen: 2 <= N <= R.

Ich würde wirklich gerne eine Javascript-Lösung sehen, die kürzer als meine 73 Bytes ist.

Aber natürlich ist es offen für alle Sprachen!

Wenn Ihre Sprache kein Array zurückgeben kann, können Sie alle Zahlen ausdrucken;)


2
Eine andere Sache: Ich glaube nicht, dass Sie wollen, dass sie bei jedem Lauf anders sind, sondern nur einheitlich zufällig? (Sonst würde es nicht funktionieren R=N=1) Dann empfehle ich, die Bereiche 0..Rals Alternative zuzulassen, da dies für viele Sprachen natürlicher ist.
Fehler

Ich würde empfehlen, dass jede Permutation gleich wahrscheinlich ist (unter der Annahme einer vollkommenen Zufälligkeit), sonst kann ich es tunshuffle(0..N)
Nathan Merrill

Ich habe meine Antwort mit ungleichmäßiger zufälliger Qualität veröffentlicht, bevor Sie Ihre Regel geändert haben.
Conor O'Brien

1
Sie sagen eine gleichmäßig zufällige Lösung, new Dateliefern aber ungleichmäßige Werte. Des Weiteren glaube ich, dass Sie Golf spielen können new Date%r+1;)
Conor O'Brien

Muss das Ausgabearray Ganzzahlen sein? Scheint offensichtlich, aber ich sehe es nicht explizit angegeben
Charlie Wynn

Antworten:



9

JavaScript (ES6), 68 66 Bytes

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

Aufgerufen als F(N)(R)(), wo Fist die Funktionszuordnung und N/R sind die Werte.

Du hast in Js nach weniger als 73 Bytes gefragt;)

BEARBEITEN: Die Antwort von @ C5H8NNaO4 funktioniert innerhalb der Tatsache, dass die Regeln keine einheitlichen Werte angeben müssen 1..R. Vorausgesetzt, hier ist eine Version arbeitet in 63 Bytes (genannt als F(R)(N)):

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

Mann, das ist beeindruckend !! +1
entfernt

@WashingtonGuedes Danke =) Nur noch 2 Bytes rasiert.
Mwr247

7

Oktave, 22 19 9 Bytes

@randperm

randperm(r,n)macht genau das, was verlangt wird. Beachten Sie, dass dies in Matlab nicht funktioniert (zumindest nicht in älteren Versionen).


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

1
randpermmit zwei Eingängen funktioniert in neueren Matlab-Versionen. Es gibt auch randsample, aber es dauert mehr Bytes, es sei denn, Sie können loswerden @(...)(ich denke, das ist erlaubt)
Luis Mendo

Oh, ich kann @randperm=)
Fehler

5

TI-84 BASIC OS 4.0, 12 Byte

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

Der TI-84 + CSE (2013) und der CE (2015) sind im Wesentlichen derselbe eingeschränkte BASIC-Dialekt wie der TI-84 +, es gibt jedoch einige neue Funktionen. Eines davon ist das dritte Argument von randIntNoRep.


1
Ehrlich gesagt ist es irgendwie albern, dass sie dieses Feature von Anfang an nicht aufgenommen haben.
SuperJedi224

Ich dachte sofort an TI-Basic, als ich diese Herausforderung sah :)
Timtech

5

MATL , 2 Bytes

Zr

Eingaben sind: zuerst R, dann N.

Probieren Sie es online!

Erläuterung

Die Funktion Zrnimmt zwei Eingaben (implizit in diesem Fall) und führt eine ersatzlose Zufallsstichprobe durch. Die erste Eingabe Rgibt an, dass die Grundgesamtheit ist [1,2,...,R]. und die zweite Eingabe Ngibt die Anzahl der Proben an, die aus der Grundgesamtheit entnommen werden sollen.



4

Pyth, 6 Bytes

<.SSQE

Probieren Sie es hier aus!

Die Reichweite steht in der ersten Zeile und die Länge in der zweiten.

Erläuterung

<.SSQE # Q = Bereich, E = Länge

   SQ # erzeugt den Bereich 1 ... Q
 .S # Liste mischen
<E # nimm die ersten E-Elemente

Nicht konkurrierende 5-Byte-Version

Die letzte Ergänzung zu Pyth fügt bei Bedarf implizite Qs am Ende des Programms hinzu. Wir können dies hier verwenden, indem wir das Eingabeformat umkehren, sodass die Länge und dann der Bereich an erster Stelle stehen.

<.SSE

Probieren Sie es hier aus!

Hier Eist der Bereich, mit dem wir eine 1-basierte Liste Serstellen, mit mischen .Sund die ersten QElemente mit nehmen <. <erwartet eine ganze Zahl, die implizit mit a addiert wird Q.


4

Reng v.2.1, 140 103 98 97 Bytes

Dies sollte auch in früheren Versionen funktionieren.

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

Sie können es hier ausprobieren! Eingabe ist maximum length, wie z 10 3.

Darauf bin ich so stolz, dass du es nicht mal weißt. Wenn mich jemand mit einer Java-Antwort schlägt, ist das mein Tag. Wenn ich eine Java-Antwort verpasse, denke ich auch an meinen Tag.

Ich werde es später erklären, sobald ich mich erholt habe. Im Allgemeinen jedoch:

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

Dies erzeugt die Zufallszahlen. Der andere Teil prüft, ob Duplikate vorhanden sind, und wiederholt den Vorgang, falls vorhanden. Andernfalls werden die Ergebnisse mit Leerzeichen gedruckt.

Hier sind einige Beispiele:

langes gif


3

CJam, 8 Bytes

{,:)mr<}

Probieren Sie es hier aus!

Dies ist ein unbenannter Block, der den Bereich oben auf dem Stapel und die Länge unten erwartet und eine Liste auf dem Stapel hinterlässt.

Erläuterung

, e # 0-basierter Bereich
:) e # inkrementiere jedes Element der Liste so, dass es auf 1 basiert
mr e # mische die Liste
<e # nimm die ersten n Elemente

Dies ist ein glückliches Programm :)
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Ich wäre glücklicher, wenn CJam eine integrierte Funktion für 1-basierte Bereiche hätte, daher würde ich dieses verdammte Smiley nicht benötigen: P
Denker

2

Common Lisp, 90

52 nur für den Ausdruck

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

Wenn ich use-package und lambda nicht mitzähle , lautet der verbleibende Ausdruck wie bei anderen Antworten (coerce(subseq(shuffle(iota R :start 1))0 N)'vector)52 Byte.


2

Rubin, 27 23 Bytes

Anonyme Funktion, einigermaßen kurz und bündig.

-4 Bytes von @manatwork

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

->n,r{[*1..r].sample n}Verwenden Sie Code Block Markup anstelle von Inline Code Markup, damit Skripte wie Code Golf UserScript Enhancement Pack die Codegröße daneben einfügen können.
Manatwork

In Ordnung, es ist jetzt behoben.
Wert Tinte

2

𝔼𝕊𝕄𝕚𝕟 10 Zeichen / 13 Byte

Ѩŝ⩤⁽1í)ą-î

Try it here (Firefox only).

Erläuterung

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

2

Bash + Coreutils, 16

Ich halte das für selbsterklärend:

seq $2|shuf -n$1

Eingabe Nund Rals Befehlszeilenparameter.

Oder wie @rici bei gleicher Punktzahl feststellt:

shuf -n$1 -i1-$2

Ideone.


1
oder shuf -n$1 -i1-$2(gleiche Länge).
rici

@rici sehr nett. sehr sauber :)
Digital Trauma

1

PowerShell v2 +, 30 Byte

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

Übernimmt Eingaben $nund erstellt $reinen Bereich 1..$r, leitet diese Get-Randommit einer -CAnzahl von weiter $n, wodurch $neindeutige Elemente aus dem Bereich ausgewählt werden. Die Ausgabe wird als implizites Array in der Pipeline belassen.


1

Im Ernst, 5 Bytes

,,R╨J

Probieren Sie es online!

Erläuterung:

,,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 Bytes

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

Eine anonyme Funktion, die N als erstes und R als zweites nimmt.


1

Perl 6, 32 Bytes

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

1

Python 3.5 - 54 53 Bytes:

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

Dies verwendet die sample()Funktion des Zufallsmoduls, um ein Array mit der Länge "a" zurückzugeben, das aus zufälligen, eindeutigen Elementen im Bereich besteht 1 => c.


1

D, 29 Bytes (nur Ausdruck)

Unter der Annahme, dass std.random und std.range importiert wurden und dass n und r als Variablen definiert sind, kann das Programm in dem einzelnen Ausdruck gelöst werden:

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)

Wie in @ Mwr247 die Antwort , können Sie es mit nennen F(R)(N), Fwobei die Funktion Ausdruck


0

Mathcad, 67 "Bytes"

Erstellt einen Spaltenvektor aus aufeinanderfolgenden ganzen Zahlen im Bereich 1..R., verknüpft ihn mit einem Spaltenvektor der Länge R aus (einheitlichen) Zufallszahlen, sortiert die resultierende Rx2-Matrix in der Zufallszahlenspalte und extrahiert dann die ersten n Zahlen aus der randomisierte Spalte von ganzen Zahlen.

Bildbeschreibung hier eingeben


Gibt es einen Ort, an dem wir das testen können?
Conor O'Brien

Sie können Testversionen von Mathcad 15 und Mathcad Prime 3.1 (dem Nachfolger von Mathcad 15) herunterladen. Beide Versuche dauern 30 Tage. Danach funktioniert M15 nicht mehr, Prime 3.1 wird jedoch weiterhin ausgeführt, wenn auch mit eingeschränkter Funktionalität (z. B. ohne Programmierung). Das oben Genannte wird also nicht funktionieren. Die for-Schleife kann jedoch zur Verwendung von Bereichsvariablen umgeschrieben werden (v außerhalb der Augment-Anweisung zu erstellen)
Stuart Bruff


Und wie zählt man diese Bytes?
25.

Betrachten Sie es aus der Perspektive einer Benutzereingabe und setzen Sie eine Mathcad-Eingabeoperation (Tastatur in der Regel Mausklick auf die Symbolleiste, wenn keine KBD-Verknüpfung vorhanden ist) einem Zeichen gleich und interpretieren Sie dies als Byte. csort = 5 Byte, da es char-by-char geschrieben wird, ebenso wie andere Variablen- / Funktionsnamen. Der Operator for ist ein spezielles Konstrukt, das 11 Zeichen (einschließlich 3 leerer "Platzhalter" und 3 Leerzeichen) belegt, jedoch mit der Tastenkombination ctl-shft- # eingegeben wird, also = 1 Byte (in einigen Sprachen ähnlich wie Token). Wenn Sie '(Anführungszeichen) eingeben, werden (normalerweise) ausgeglichene Klammern erstellt. Dies entspricht 1 Byte. Indizierung von v = 3 Bytes (Typ v [k).
Stuart Bruff

0

Python, 56 (der offensichtliche Weg)

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)ist um ein Byte kürzer
Mego

Huh, ich habe überlegt from random import*, muss die Zählung vermasselt haben.
Shooqie

0

Perl 5, 51 43 Bytes

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

Ziemlich einfaches anonymes Unterelement, das ein Array von 1 bis R generiert und dann N zufällige Elemente daraus zusammenfügt, um zurückzukehren. Mit anrufen ->(N, R).


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.