อาร์เรย์แบบสุ่มโดยไม่ต้องทำซ้ำ


16

ฉันกำลังตอบคำถามท้าทายหนึ่งที่นี่และงานนี้เป็นส่วนหนึ่งของความท้าทาย ฉันมีวิธีแก้ปัญหา 73 ไบต์ในจาวาสคริปต์ แต่ฉันคิดว่ามันมากเกินไปสำหรับสิ่งที่ง่าย

ท้าทาย

รับเป็นอินพุตจำนวนเต็มสองจำนวน:

  • N ความยาวของอาร์เรย์ที่คาดหวัง
  • Rช่วงของช่วงเวลาเริ่มต้นในหนึ่ง: 1..Rไม่0..R-1

เอาต์พุตในการรันแต่ละครั้งของโปรแกรม / ฟังก์ชันของคุณหนึ่งอาร์เรย์ที่Nมีความยาวต่างกันโดยมีค่าอยู่ระหว่างกัน1..Rในลักษณะที่ไม่มีค่าใดเกิดขึ้นมากกว่าหนึ่งครั้ง

คุณต้องใช้R-valueในรหัสของคุณ

ข้อ จำกัด

2 <= N <= Rคุณสามารถสันนิษฐานได้ว่า:

ฉันอยากเห็นโซลูชันจาวาสคริปต์สั้นกว่าของฉัน 73 ไบต์

แต่แน่นอนมันเปิดทุกภาษา!

หากภาษาของคุณไม่สามารถส่งกลับอาร์เรย์คุณสามารถพิมพ์ตัวเลขทั้งหมด)


2
อีกสิ่งหนึ่ง: ฉันไม่คิดว่าคุณต้องการให้พวกเขาแตกต่างจากการวิ่งทุกครั้ง แต่แค่สุ่มอย่างสม่ำเสมอ? (ไม่อย่างนั้นมันจะใช้ไม่ได้R=N=1) จากนั้นฉันแนะนำให้อนุญาตช่วงต่างๆ0..Rเป็นทางเลือกเนื่องจากเป็นเรื่องปกติสำหรับหลายภาษา
ข้อบกพร่อง

ฉันขอแนะนำให้รวมถึงว่าการเปลี่ยนแปลงแต่ละครั้งมีแนวโน้มเท่ากัน (สมมติว่าเป็นการสุ่มสมบูรณ์แบบ) อย่างอื่นที่ฉันทำได้shuffle(0..N)
นาธานเมอร์ริลล์

ฉันโพสต์คำตอบของฉันเกี่ยวกับคุณภาพแบบสุ่มที่ไม่สม่ำเสมอก่อนที่คุณจะเปลี่ยนแปลงกฎของคุณ
Conor O'Brien

1
คุณพูดว่าวิธีการสุ่มอย่างสม่ำเสมอ แต่new Dateให้ค่าที่ไม่สม่ำเสมอ ยิ่งกว่านั้นฉันเชื่อว่าคุณสามารถตีมันได้ที่new Date%r+1)
Conor O'Brien

อาร์เรย์เอาต์พุตจำเป็นต้องเป็นจำนวนเต็มหรือไม่? ดูเหมือนชัดเจน แต่ฉันไม่เห็นมันชัดเจน
Charlie Wynn

คำตอบ:


16

Dyalog APL, 1 ไบต์

?

เพียงแค่ในตัว ลองมันนี่


3
ด้วยคำตอบเช่นนี้ฉันต้องเลื่อนกลับขึ้นมาเพื่อดูว่าคุณเป็น OP
lbstr

2
@lbstr ตอนนี้คุณพูดถึงมันแล้ว identicon ของฉันค่อนข้างคล้ายกับของ OP
lirtosiast

9

JavaScript (ES6), 68 66 ไบต์

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

เรียกได้ว่าเป็น F(N)(R)()โดยที่Fฟังก์ชั่นได้รับมอบหมายและN/ Rเป็นค่า

คุณขอให้น้อยกว่า 73 ไบต์ใน Js;)

แก้ไข: คำตอบโดย @ C5H8NNaO4 1..Rทำงานภายในความจริงที่ว่ากฎระเบียบที่ไม่ได้ระบุค่าที่จะต้องมีความสม่ำเสมอทั้ง รับได้ที่นี่เป็นรุ่นที่ทำงานใน 63 ไบต์ (เรียกว่าF(R)(N)):

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

ผู้ชายนี่มันน่าประทับใจ !! +1
นำออก

@WashingtonGuedes ขอบคุณ =) เพิ่งลบไปอีก 2 ไบต์
Mwr247

7

คู่, 22 19 9 ไบต์

@randperm

randperm(r,n)ทำตามที่ขอ โปรดทราบว่าสิ่งนี้ไม่ทำงาน (อย่างน้อยไม่ได้อยู่ในรุ่นที่เก่ากว่า) ใน Matlab


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

1
randpermด้วยสองอินพุตจะทำงานในเวอร์ชัน Matlab ล่าสุด นอกจากนี้ยังมีrandsampleแต่ต้องใช้เวลามากขึ้นเว้นแต่คุณจะสามารถกำจัด@(...)(ฉันคิดว่าได้รับอนุญาต)
Luis Mendo

โอ้ฉันสามารถใช้@randperm=)
ข้อบกพร่อง

5

TI-84 BASIC OS 4.0, 12 ไบต์

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

TI-84 + CSE (2013) และ CE (2015) เป็นภาษาพื้นฐานที่ จำกัด เช่นเดียวกับ TI-84 + แต่มีคุณสมบัติใหม่ไม่กี่ หนึ่งในนั้นคืออาร์กิวเมนต์ที่สามของ randIntNoRep


1
ตรงไปตรงมามันช่างโง่เขลาที่พวกเขาไม่ได้รวมคุณสมบัตินั้นไว้ตั้งแต่ต้น
SuperJedi224

ฉันทันทีคิดว่า TI-Basic เมื่อฉันเห็นความท้าทายนี้ :)
Timtech

5

MATL , 2 ไบต์

Zr

ปัจจัยการผลิตเป็นครั้งแรกแล้วRN

ลองออนไลน์!

คำอธิบาย

ฟังก์ชั่นZrรับสองอินพุต (โดยนัยในกรณีนี้) และทำการสุ่มตัวอย่างแบบไม่มีการแทนที่ อินพุตแรกR,, ระบุว่าประชากรคือ[1,2,...,R]; และอินพุตที่สองNระบุจำนวนตัวอย่างที่จะรับจากประชากร


4

เจ 4 3 ไบต์

บันทึกหนึ่งไบต์ต้องขอบคุณ Zgarb! ( ตัดกันสี่ยังคงเป็นสี่ปกติ: D )

1+?

เรียกเหมือนเช่นN (1+?) R 3 (1+?) 10นี้ใช้ "Roll" 0...n-1ผู้ประกอบการและไม่ตรงกับสิ่งที่อธิบายยกเว้นภายใต้ ถ้าเราได้รับอนุญาตให้ทำสิ่งนี้คำตอบก็คือ 1 ไบต์

?


@tac Ah, gotcah
Conor O'Brien

4

Pyth, 6 ไบต์

<.SSQE

ลองที่นี่!

ช่วงมาในบรรทัดแรกและความยาวในสอง

คำอธิบาย

<.SSQE # Q = พิสัย E = ความยาว

   SQ # สร้างช่วง 1 ... Q
 .S # สุ่มรายการ
<E # ใช้องค์ประกอบ E แรก

รุ่น 5 ไบต์ที่ไม่ได้แข่งขัน

การเพิ่มล่าสุดไปยัง Pyth จะเพิ่มQs โดยนัยเมื่อสิ้นสุดโปรแกรมหากจำเป็น เราสามารถใช้สิ่งนี้ที่นี่โดยย้อนกลับรูปแบบการป้อนข้อมูลดังนั้นความยาวจึงมาก่อนแล้วจึงเป็นช่วง

<.SSE

ลองที่นี่!

นี่Eคือช่วงที่เรากลายเป็นรายการที่ 1 ตามที่มีSสับด้วย.Sและใช้ครั้งแรกองค์ประกอบที่มีQ คาดว่าจำนวนเต็มซึ่งจะมีการเพิ่มโดยปริยายด้วยหนึ่ง<<Q


4

Reng v.2.1, 140 103 98 97 ไบต์

สิ่งนี้น่าจะใช้ได้ในเวอร์ชั่นก่อนหน้าเช่นกัน

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

คุณสามารถลองได้ที่นี่! ท่านเป็นเช่นmaximum length10 3

ฉันภูมิใจในสิ่งนี้มากคุณไม่รู้ด้วยซ้ำ หากมีคนชนะฉันด้วยคำตอบ Java นั่นจะทำให้วันของฉัน ถ้าฉันชนะคำตอบ Java ให้พิจารณาวันของฉันทำเช่นกัน

ฉันจะอธิบายเพิ่มเติมในภายหลังเมื่อฉันฟื้นตัว โดยทั่วไปแล้ว:

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

สิ่งนี้จะสร้างตัวเลขสุ่ม ส่วนอื่นจะตรวจสอบว่ามีรายการที่ซ้ำกันหรือไม่และหากมีกระบวนการนี้จะเกิดขึ้นซ้ำ อย่างอื่นผลลัพธ์จะถูกพิมพ์พร้อมช่องว่างที่เข้าร่วมผลลัพธ์

นี่คือตัวอย่างบางส่วน:

long gif


3

CJam, 8 ไบต์

{,:)mr<}

ลองที่นี่!

นี่คือบล็อกที่ไม่มีชื่อซึ่งคาดว่าช่วงบนสุดของสแต็กและความยาวที่ด้านล่างและออกจากรายการบนสแต็ก

คำอธิบาย

, ช่วงที่อิงกับ # 0
:) e # inkrement แต่ละองค์ประกอบของรายการเพื่อให้เป็นไปตาม 1
m e # สลับรายการ
<e # รับองค์ประกอบ n แรก

นี่เป็นหนึ่งในโปรแกรมที่มีความสุข :)
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴฉันจะมีความสุขมากขึ้นถ้า CJam มี builtin สำหรับช่วงที่ใช้ 1 ดังนั้นฉันจะไม่ต้องการรอยยิ้มนี้ damm: P
Denker

2

เสียงกระเพื่อมสามัญ 90

52สำหรับการแสดงออกเท่านั้น

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

เช่นเดียวกับคำตอบอื่น ๆ ถ้าฉันไม่นับแพ็คเกจใช้และแลมบ์ดานิพจน์ที่เหลืออยู่คือ(coerce(subseq(shuffle(iota R :start 1))0 N)'vector)52 ไบต์


2

Ruby, 27 23 ไบต์

ฟังก์ชั่นไม่ระบุชื่อสั้นและหวานพอสมควร

-4 ไบต์จาก @manatwork

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

->n,r{[*1..r].sample n}โปรดใช้รหัสบล็อกมาร์กอัปแทนรหัสมาร์กอัปดังนั้นสคริปต์เช่นCode Golf UserScript Enhancement Packสามารถแทรกขนาดรหัสข้างๆ
ผลิตด้วยฝีมือ

เอาล่ะมันคงที่แล้ว
มูลค่าหมึก


2

Bash + coreutils, 16

ฉันคิดว่านี่เป็นคำอธิบายตัวเอง:

seq $2|shuf -n$1

อินพุตNและRเป็นพารามิเตอร์บรรทัดคำสั่ง

หรือเป็น @rici คะแนนสำหรับคะแนนเดียวกัน:

shuf -n$1 -i1-$2

Ideone


1
หรือshuf -n$1 -i1-$2(ความยาวเท่ากัน)
rici

@rici ดีมาก สะอาดมาก :)
บาดเจ็บทางดิจิตอล

1

PowerShell v2 +, 30 ไบต์

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

รับอินพุต$nและ$rสร้างช่วง1..$rไปป์ที่ไปGet-Randomด้วย-Count $nซึ่งจะเลือก$nองค์ประกอบที่ไม่ซ้ำกันจากช่วง เอาต์พุตถูกทิ้งไว้บนไพพ์ไลน์เป็นอาร์เรย์โดยนัย



1

Clojure, 38 ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อรับ N ก่อนและ R วินาที



1

Python 3.5 - 54 53 ไบต์:

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

นี้ใช้โมดูลแบบสุ่มของsample()ฟังก์ชั่นที่จะกลับอาร์เรย์ที่มีความยาว "เป็น" 1 => cประกอบด้วยสุ่มองค์ประกอบที่ไม่ซ้ำกันในช่วง


1

D, 29 bytes (expression only)

Assuming that std.random and std.range have been imported and that n and r are defined as variables, the program can be solved in the single expression:

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


0

Mathcad, 67 "bytes"

creates a column vector of consecutive integers in range 1..R, joins it to a column vector of length R of (uniform) random numbers, sorts the resulting Rx2 matrix on the random number column, and then extracts the first n numbers from the randomized column of integers.

enter image description here


Is there a place we can test this?
Conor O'Brien

You can download trial versions of Mathcad 15 and Mathcad Prime 3.1 (the successor to Mathcad 15). Both trials run for 30 days, after which M15 stops working, but Prime 3.1 still runs, albeit with reduced functionality (eg, no programming - so the above won't work ... but the for loop can be rewritten to use range variables to create v outside of the augment statement)
Stuart Bruff


And how do you count these bytes?
Rɪᴋᴇʀ

By looking at it from a user input perspective and equating one Mathcad input operation (keyboard usually, mouse-click on toolbar if no kbd shortcut) to a character and interpreting this as a byte. csort = 5 bytes as it's typed char-by-char as are other variable/function names. The for operator is a special construct that occupies 11 characters (including 3 blank "placeholders" and 3 spaces) but is entered by ctl-shft-#, hence = 1 byte (similar to tokens in some languages). Typing ' (quote)creates balanced parentheses (usually) so counts as 1 byte. Indexing v = 3 bytes (type v[k).
Stuart Bruff

0

Python, 56 (the obvious way)

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) is shorter by a byte
Mego

Huh, I did consider from random import*, must've screwed up the counting.
shooqie

0

Perl 5, 51 43 bytes

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

Pretty straightforward anonymous sub that generates an array from 1 to R and then splices N random elements from it to return. Call with ->(N, R).


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.