# Random array without repetition

I was answering one challenge here and this task was part of the challenge. I've got a 73 bytes solution in javascript. But I think it is too much for a simple thing.

### Challenge

Given as input two integers:

• N the length of the expected array
• R the interval's range starting in one: 1..R, not 0..R-1

Output in each run of your program/function one different array of length N with values between 1..R in such a way no one value occurs more than once.

You must use R-value in your code.

### Restrictions

You can assume: 2 <= N <= R.

I really would like to see a javascript solution shorter than mine 73 bytes.

But of course, it is open to all languages!

If your language can not return an array, you can print all the numbers ;)

• Another thing: I do not think that you want them to be different with every run, but just uniformly random? (Otherwise it would not work for R=N=1) Then I recommend allowing the ranges 0..R as an alternative as this comes more natural to many languages. – flawr Mar 24 '16 at 16:32
• I'd recommending including that each permutation be equally likely (assuming perfect randomness), else I can do shuffle(0..N) – Nathan Merrill Mar 24 '16 at 16:33
• I posted my answer of non-uniform random quality before you made your rule change. – Conor O'Brien Mar 24 '16 at 16:35
• You say a uniformly random solution, but new Date yields non-uniform values. Further, I believe you can golf it to new Date%r+1 ;) – Conor O'Brien Mar 24 '16 at 16:44
• Does the output array need to be integers? Seems obvious, but I don't see it explicitly stated – Charlie Wynn Mar 25 '16 at 14:21

## Dyalog APL, 1 byte

?


Just a builtin. Try it here.

• With an answer like this, I had to scroll back up to see if you were the OP – lbstr Mar 25 '16 at 22:51
• @lbstr Now that you mention it, my identicon is quite similar to OP's. – lirtosiast Mar 25 '16 at 23:25

# JavaScript (ES6), 68 66 bytes

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


Called as F(N)(R)(), where F is the function assignment, and N/R are the values.

You asked for shorter than 73 bytes in Js ;)

EDIT: The answer by @C5H8NNaO4 works within the fact that the rules don't specify the values must be uniform across 1..R. Given that, here's a version works in 63 bytes (called as F(R)(N)):

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

• Man, this is impressive !! +1 – removed Mar 24 '16 at 21:09
• @WashingtonGuedes Thanks =) Just shaved off another 2 bytes. – Mwr247 Mar 24 '16 at 21:12

# Octave, 22 19 9 bytes

@randperm


randperm(r,n) does exactly what is requested. Note that this does not work (at least not in oldder versions) in Matlab.

• @(n,r)randperm(r,n) – Luis Mendo Mar 24 '16 at 17:33
• randperm with two inputs does work in recent Matlab versions. There's also randsample, but it takes more bytes, unless you can get rid of the @(...) (I think that's allowed) – Luis Mendo Mar 24 '16 at 19:14
• Oh I can use @randperm=) – flawr Mar 24 '16 at 19:24

## TI-84 BASIC OS 4.0, 12 bytes

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


The TI-84+ CSE (2013) and the CE (2015) are essentially the same limited BASIC dialect as the TI-84+, but there are a few new features. One of them is randIntNoRep's third argument.

• Frankly, it's kind of silly that they didn't include that feature from the beginning. – SuperJedi224 Mar 24 '16 at 19:46
• I immediately thought TI-Basic when I saw this challenge :) – Timtech Mar 24 '16 at 22:31

# MATL, 2 bytes

Zr


Inputs are: first R, then N.

Try it online!

### Explanation

The function Zr takes two inputs (implicitly in this case) and does a random sampling without replacement. The first input, R, specifies that the population is [1,2,...,R]; and the second input, N, indicates the number of samples to take from the population.

# J, 4 3 bytes

One byte saved thanks to Zgarb! (Crossed out four is still a regular four :D)

1+?


call like N (1+?) R, e.g., 3 (1+?) 10. This uses the "Roll" operator, and does exactly what is described, except under 0...n-1. If we were allowed to do this, then the answer would be 1 byte,

?


# Pyth, 6 bytes

<.SSQE


Try it here!

Range comes on the first line and the length on the second.

# Explanation

<.SSQE    # Q = range, E = length

SQ     # generate the range 1...Q
.S       # shuffle the list
<    E    # take the first E elements


## Non-competing 5-byte version

The lastest addition to Pyth adds implicit Qs at the end of the program if needed. We can use this here by reversing the input format, so the length comes first and then the range.

<.SSE


Try it here!

Here E is the range, which we turn into a 1-based list with S, shuffle it with .S and take the first Q elements with <. < expects an integer which is implicitly added with a Q.

# Reng v.2.1, 14010398 97 bytes

This should work in earlier versions, too.

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


You can try it here! Input is maximum length, such as 10 3.

I am so proud of this, you don't even know. If someone beats me with a Java answer, that will make my day. If I beat a Java answer, consider my day made as well.

I will explain it more later, once I recover. Generally, though:

## Seriously, 5 bytes

,,R╨J


Try it online!

Explanation:

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


# Clojure, 38 bytes

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


An anonymous function taking N first and R second.

# Perl 6, 32 bytes

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


# Python 3.5 - 54 53 bytes:

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


This uses the random module's sample() function to return an array with length "a" consisting of random, unique elements in the range 1 => c.

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


ES6, 72

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


Like in @Mwr247's answer, you can call it with F(R)(N), F being the function expression

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. • Is there a place we can test this? – Conor O'Brien Mar 24 '16 at 19:45
• 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 Mar 25 '16 at 0:04
• And how do you count these bytes? – Rɪᴋᴇʀ Mar 25 '16 at 15:39
• 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 Mar 25 '16 at 16:29

# 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 Mar 24 '16 at 18:19
• Huh, I did consider from random import*, must've screwed up the counting. – shooqie Mar 24 '16 at 18:31

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

# TI-84 BASIC, 21 bytes

Prompt R,N:randIntNoRep(1,R→A:N→dim(ʟA:ʟA

• One can no longer use Ans as input as per a recent meta post. – Conor O'Brien Mar 24 '16 at 19:04
• @CᴏɴᴏʀO'Bʀɪᴇɴ ...why not? – SuperJedi224 Mar 24 '16 at 19:05
• That was the consensus on meta. Vote on it if you disagree. – Conor O'Brien Mar 24 '16 at 19:07