Losowa tablica bez powtórzeń


16

Odpowiadałem tutaj na jedno wyzwanie i to zadanie było częścią wyzwania. Mam 73 bajtowe rozwiązanie w javascript. Ale myślę, że to za dużo na prostą rzecz.

Wyzwanie

Jako dane wejściowe podano dwie liczby całkowite:

  • N długość oczekiwanej tablicy
  • R zakres interwału zaczyna się od jednego: 1..R nie0..R-1

Wyprowadzaj w każdym uruchomieniu programu / funkcji jedną inną tablicę długości N z wartościami 1..Rw taki sposób, że żadna wartość nie występuje więcej niż jeden raz.

Musisz użyć R-value w swoim kodzie.

Ograniczenia

Możesz założyć: 2 <= N <= R .

Naprawdę chciałbym zobaczyć rozwiązanie javascript krótsze niż moje 73 bajty.

Ale oczywiście jest otwarty na wszystkie języki!

Jeśli twój język nie może zwrócić tablicy, możesz wydrukować wszystkie liczby;)


2
Inna sprawa: nie sądzę, że chcesz, aby były one różne z każdym biegiem, ale po prostu jednolicie losowe? (W przeciwnym razie nie zadziałałoby R=N=1). Następnie zalecam stosowanie zakresów 0..Rjako alternatywy, ponieważ jest to bardziej naturalne dla wielu języków.
flawr

Zalecałbym uwzględnienie, aby każda permutacja była jednakowo prawdopodobna (przy założeniu idealnej losowości), w przeciwnym razie mogę to zrobićshuffle(0..N)
Nathan Merrill

Opublikowałem moją odpowiedź o nierównomiernej losowej jakości przed wprowadzeniem zmiany w regule.
Conor O'Brien

1
Mówisz, że rozwiązanie jest jednolicie losowe, ale new Datedaje niejednorodne wartości. Co więcej, uważam, że możesz grać w golfa new Date%r+1;)
Conor O'Brien

Czy tablica wyjściowa musi być liczbami całkowitymi? Wydaje się oczywiste, ale nie widzę tego wyraźnie stwierdzone
Charlie Wynn

Odpowiedzi:


16

Dyalog APL, 1 bajt

?

Po prostu wbudowany. Wypróbuj tutaj .


3
Przy takiej odpowiedzi musiałem przewinąć do tyłu, aby sprawdzić, czy jesteś OP
lbstr

2
@lbstr Teraz, kiedy o tym wspominasz, mój identyfikator jest dość podobny do OP.
lirtosiast

9

JavaScript (ES6), 68 66 bajtów

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

Wywoływany jako F(N)(R)(), gdzie Fjest przypisanie funkcji i N/R są wartościami.

Prosiłeś o mniej niż 73 bajty w Js;)

EDYCJA: Odpowiedź @ C5H8NNaO4 działa w ramach faktu, że reguły nie określają wartości, muszą być jednolite w poprzek 1..R. Biorąc to pod uwagę, oto wersja działa w 63 bajtach (nazywana jako F(R)(N)):

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

Człowieku, to imponujące !! +1
usunięto

@WashingtonGuedes Thanks =) Właśnie ogoliłem kolejne 2 bajty.
Mwr247,

7

Oktawa, 22 19 9 bajtów

@randperm

randperm(r,n)robi dokładnie to, co jest wymagane. Zauważ, że to nie działa (przynajmniej nie w starszych wersjach) w Matlabie.


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

1
randpermz dwoma wejściami działa w najnowszych wersjach Matlaba. Jest też randsample, ale zajmuje więcej bajtów, chyba że możesz się go pozbyć @(...)(myślę, że to dozwolone)
Luis Mendo

Och, mogę użyć @randperm=)
flawr

5

TI-84 BASIC OS 4.0, 12 bajtów

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

TI-84 + CSE (2013) i CE (2015) są zasadniczo tym samym ograniczonym dialektem BASIC co TI-84 +, ale jest kilka nowych funkcji. Jednym z nich jest trzeci argument randIntNoRep.


1
Szczerze mówiąc, to głupie, że od samego początku nie zawierały tej funkcji.
SuperJedi224

Natychmiast pomyślałem o TI-Basic, kiedy zobaczyłem to wyzwanie :)
Timtech

5

MATL , 2 bajty

Zr

Dane wejściowe to: najpierw R, a następnie N.

Wypróbuj online!

Wyjaśnienie

Funkcja Zrpobiera dwa dane wejściowe (w tym przypadku domyślnie) i wykonuje losowe próbkowanie bez zamiany. Pierwsze dane wejściowe Rokreślają, że populacja jest [1,2,...,R]; a drugie dane wejściowe Nwskazują liczbę próbek do pobrania z populacji.



4

Pyth, 6 bajtów

<.SSQE

Wypróbuj tutaj!

Zasięg występuje w pierwszej linii, a długość w drugiej.

Wyjaśnienie

<.SSQE # Q = zakres, E = długość

   SQ # generuje zakres 1 ... Q
 .S # przetasuj listę
<E # weź pierwsze elementy E.

Niekonkurencyjna 5-bajtowa wersja

Ostatni dodatek do Pytha dodaje niejawne Qs na końcu programu, jeśli to konieczne. Możemy użyć tego tutaj poprzez odwrócenie formatu wejściowego, aby najpierw była długość, a potem zakres.

<.SSE

Wypróbuj tutaj!

Oto Ezakres, który zamieniamy w listę opartą na 1 S, tasujemy ją .Si bierzemy pierwsze Qelementy <. <oczekuje liczby całkowitej, która jest domyślnie dodana do znaku Q.


4

Reng v.2.1, 140 103 98 97 bajtów

Powinno to również działać we wcześniejszych wersjach.

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

Możesz spróbować tutaj! Dane wejściowe to maximum length, takie jak 10 3.

Jestem z tego bardzo dumny, nawet nie wiesz. Jeśli ktoś pobije mnie odpowiedzią Java, to sprawi, że mój dzień. Jeśli pobiję odpowiedź w Javie, pomyśl również o moim dniu.

Wyjaśnię to później, kiedy wyzdrowieję. Ogólnie jednak:

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

To generuje liczby losowe. Druga część sprawdza, czy są duplikaty, a jeśli tak, proces jest powtarzany. W przeciwnym razie wyniki są drukowane, a spacje łączą się z wynikami.

Oto kilka przykładów:

long gif


3

CJam, 8 bajtów

{,:)mr<}

Wypróbuj tutaj!

Jest to nienazwany blok, który oczekuje zakresu na górze stosu i długości na dole i pozostawia listę na stosie.

Wyjaśnienie

, zakres oparty na e # 0
:) e # inkrement każdy element listy, więc jest oparty na 1
mr e # przetasuj listę
<e # weź pierwszych n elementów

To jest jeden szczęśliwy program :)
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Byłbym szczęśliwszy, gdyby CJam miał wbudowany zakres dla 1-zakresów, więc nie potrzebowałbym tego przeklętego uśmiechu: P
Denker

2

Common Lisp, 90

52 tylko dla wyrażenia

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

Nie golfił

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

Podobnie jak inne odpowiedzi, jeśli nie liczę use-package i lambda , pozostałe wyrażenie to (coerce(subseq(shuffle(iota R :start 1))0 N)'vector)52 bajty.



2

𝔼𝕊𝕄𝕚𝕟, 10 znaków / 13 bajtów

Ѩŝ⩤⁽1í)ą-î

Try it here (Firefox only).

Wyjaśnienie

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

2

Bash + coreutils, 16

Myślę, że to jest oczywiste:

seq $2|shuf -n$1

Dane wejściowe Ni Rparametry wiersza polecenia.

Lub, jak wskazuje @rici, dla tego samego wyniku:

shuf -n$1 -i1-$2

Ideone.


1
lub shuf -n$1 -i1-$2(jednakowa długość).
rici

@rici bardzo miło. bardzo czyste :)
Cyfrowa trauma

1

PowerShell v2 +, 30 bajtów

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

Staje wejście $ni $rkonstruuje zakres 1..$r, że do rury Get-Randomz -Count z $n, który wybierze $nunikalne elementy z tego zakresu. Dane wyjściowe są pozostawiane w potoku jako niejawna tablica.


1

Poważnie, 5 bajtów

,,R╨J

Wypróbuj online!

Wyjaśnienie:

,,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 bajtów

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

Anonimowa funkcja zajmująca N najpierw, a R drugą.


1

Perl 6, 32 bajty

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

1

Python 3.5 - 54 53 bajty:

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

Korzysta z sample()funkcji modułu losowego, aby zwrócić tablicę o długości „a” składającej się z losowych, unikalnych elementów w zakresie 1 => c.


1

D, 29 bajtów (tylko wyrażenie)

Zakładając, że std.losowy i std.range zostały zaimportowane i że n i r są zdefiniowane jako zmienne, program można rozwiązać w jednym wyrażeniu:

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)

Podobnie jak w @ Mwr247 za odpowiedź , można nazwać go F(R)(N), Fbędąc wyrazem funkcji


0

Mathcad, 67 „bajtów”

tworzy wektor kolumny kolejnych liczb całkowitych z zakresu 1..R, łączy go z wektorem kolumny o długości R (jednolitych) liczb losowych, sortuje wynikową macierz Rx2 w kolumnie liczb losowych, a następnie wyodrębnia pierwsze n liczb z losowa kolumna liczb całkowitych.

enter image description here


Czy jest miejsce, w którym możemy to przetestować?
Conor O'Brien

Możesz pobrać wersje próbne Mathcad 15 i Mathcad Prime 3.1 (następca Mathcad 15). Oba testy trwają przez 30 dni, po których M15 przestaje działać, ale Prime 3.1 nadal działa, chociaż ze zmniejszoną funkcjonalnością (np. Bez programowania - więc powyższe nie będzie działać ... ale pętlę for można przepisać, aby użyć zmiennych zakresu utworzyć v poza instrukcją rozszerzającą)
Stuart Bruff


A jak liczyć te bajty?
Rɪᴋᴇʀ

Patrząc na to z perspektywy wprowadzania przez użytkownika i zrównując jedną operację wprowadzania Mathcada (zwykle klawiatura, kliknij pasek narzędzi, jeśli nie ma skrótu kbd) do znaku i interpretując to jako bajt. csort = 5 bajtów, ponieważ jest wpisany char-by-char, podobnie jak inne nazwy zmiennych / funkcji. Operator for to specjalna konstrukcja, która zajmuje 11 znaków (w tym 3 puste „symbole zastępcze” i 3 spacje), ale jest wprowadzana przez ctl-shft- #, stąd = 1 bajt (podobny do tokenów w niektórych językach). Wpisanie „(cytat) tworzy zrównoważone nawiasy (zwykle), więc liczy się jako 1 bajt. Indeksowanie v = 3 bajty (wpisz v [k).
Stuart Bruff,

0

Python, 56 (oczywisty sposób)

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)jest krótszy bajt
Mego

Uznałem, że to from random import*popsuło liczenie.
shooqie

0

Perl 5, 51 43 bajtów

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

Całkiem proste anonimowe podwodne, które generuje tablicę od 1 do R, a następnie dzieli z niej N losowych elementów w celu zwrócenia. Zadzwoń z ->(N, R).


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.