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 arrayR
the interval's range starting in one:1..R
, not0..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 ;)
24 Answers 24
-
3\$\begingroup\$ With an answer like this, I had to scroll back up to see if you were the OP \$\endgroup\$lbstr– lbstr2016年03月25日 22:51:38 +00:00Commented Mar 25, 2016 at 22:51
-
2\$\begingroup\$ @lbstr Now that you mention it, my identicon is quite similar to OP's. \$\endgroup\$lirtosiast– lirtosiast2016年03月25日 23:25:36 +00:00Commented Mar 25, 2016 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)
-
\$\begingroup\$ Man, this is impressive !! +1 \$\endgroup\$removed– removed2016年03月24日 21:09:22 +00:00Commented Mar 24, 2016 at 21:09
-
\$\begingroup\$ @WashingtonGuedes Thanks =) Just shaved off another 2 bytes. \$\endgroup\$Mwr247– Mwr2472016年03月24日 21:12:05 +00:00Commented Mar 24, 2016 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.
-
1\$\begingroup\$
@(n,r)randperm(r,n)
\$\endgroup\$Luis Mendo– Luis Mendo2016年03月24日 17:33:33 +00:00Commented Mar 24, 2016 at 17:33 -
1\$\begingroup\$
randperm
with two inputs does work in recent Matlab versions. There's alsorandsample
, but it takes more bytes, unless you can get rid of the@(...)
(I think that's allowed) \$\endgroup\$Luis Mendo– Luis Mendo2016年03月24日 19:14:42 +00:00Commented Mar 24, 2016 at 19:14 -
\$\begingroup\$ Oh I can use
@randperm
=) \$\endgroup\$flawr– flawr2016年03月24日 19:24:02 +00:00Commented Mar 24, 2016 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.
-
1\$\begingroup\$ Frankly, it's kind of silly that they didn't include that feature from the beginning. \$\endgroup\$SuperJedi224– SuperJedi2242016年03月24日 19:46:04 +00:00Commented Mar 24, 2016 at 19:46
-
\$\begingroup\$ I immediately thought TI-Basic when I saw this challenge :) \$\endgroup\$Timtech– Timtech2016年03月24日 22:31:59 +00:00Commented Mar 24, 2016 at 22:31
MATL, 2 bytes
Zr
Inputs are: first R
, then N
.
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,
?
-
1\$\begingroup\$ Don't break the link chain, man! \$\endgroup\$cat– cat2016年03月24日 20:35:27 +00:00Commented Mar 24, 2016 at 20:35
-
\$\begingroup\$ @tac Ah, gotcah \$\endgroup\$Conor O'Brien– Conor O'Brien2016年03月24日 20:47:42 +00:00Commented Mar 24, 2016 at 20:47
Pyth, 6 bytes
<.SSQE
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 Q
s 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
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, (削除) 140 (削除ここまで) (削除) 103 (削除ここまで) (削除) 98 (削除ここまで) 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:
v v $/$r$
>i#bbi1+#x>:u1+lxet
This generates the random numbers. The other part checks if there are duplicates, and, if there are, the process is repeated. Else, the results are printed, with spaces joining the results.
Here are some examples:
CJam, 8 bytes
{,:)mr<}
This is an unnamed block which expect the range on top of the stack and the length at the bottom and leaves a list on the stack.
Explanation
, e# 0-based range :) e# inkrement each element of the list so its 1-based mr e# shuffle the list < e# take the first n elements
-
\$\begingroup\$ This is one happy program :) \$\endgroup\$Conor O'Brien– Conor O'Brien2016年03月24日 20:52:37 +00:00Commented Mar 24, 2016 at 20:52
-
1\$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ I would be happier if CJam had a builtin for 1-based ranges, so I wouldn't need this damm smileyface :P \$\endgroup\$Denker– Denker2016年03月24日 20:57:28 +00:00Commented Mar 24, 2016 at 20:57
Common Lisp, 90
52 for the expression only
(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))
Like other answers, if I don't count use-package and lambda, the remaining expression is (coerce(subseq(shuffle(iota R :start 1))0 N)'vector)
, for 52 bytes.
Ruby, (削除) 27 (削除ここまで) 23 bytes
Anonymous function, reasonably short and sweet.
-4 bytes from @manatwork
->n,r{[*1..r].sample n}
-
\$\begingroup\$
->n,r{[*1..r].sample n}
Please use code block markup instead of inline code markup, so scripts like Code Golf UserScript Enhancement Pack can insert the code size beside it. \$\endgroup\$manatwork– manatwork2016年03月25日 08:46:48 +00:00Commented Mar 25, 2016 at 8:46 -
\$\begingroup\$ All right, it's fixed now. \$\endgroup\$Value Ink– Value Ink2016年03月25日 16:55:36 +00:00Commented Mar 25, 2016 at 16:55
ESMin, 10 chars / 13 bytes
Ѩŝ⩤(1í)ą-î
Explanation
// implicit: î=input1, í=input2
⩤(1í) // Inclusive range from 1 to í
Ѩŝ // Shuffle resulting range
ą-î // Get last îth items
Bash + coreutils, 16
I think this is self-explanatory:
seq 2ドル|shuf -n1ドル
Input N
and R
as command-line parameters.
Or as @rici points out, for the same score:
shuf -n1ドル -i1-2ドル
-
1\$\begingroup\$ or
shuf -n1ドル -i1-2ドル
(same length, though). \$\endgroup\$rici– rici2016年03月26日 03:15:58 +00:00Commented Mar 26, 2016 at 3:15 -
\$\begingroup\$ @rici very nice. very clean :) \$\endgroup\$Digital Trauma– Digital Trauma2016年03月26日 03:51:08 +00:00Commented Mar 26, 2016 at 3:51
PowerShell v2+, 30 bytes
param($n,$r)1..$r|Random -c $n
Takes input $n
and $r
, constructs a range 1..$r
, pipes that to Get-Random
with a -C
ount of $n
, which will select $n
unique elements from the range. Output is left on the pipeline as an implicit array.
Seriously, 5 bytes
,,R╨J
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
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.
-
\$\begingroup\$ Is there a place we can test this? \$\endgroup\$Conor O'Brien– Conor O'Brien2016年03月24日 19:45:53 +00:00Commented Mar 24, 2016 at 19:45
-
\$\begingroup\$ 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) \$\endgroup\$Stuart Bruff– Stuart Bruff2016年03月25日 00:04:33 +00:00Commented Mar 25, 2016 at 0:04
-
\$\begingroup\$ Trial versions are at: Matcad 15 - ptc.com/engineering-math-software/mathcad/free-trial ; Mathcad Prime 3.1 - ptc.com/engineering-math-software/mathcad/free-download \$\endgroup\$Stuart Bruff– Stuart Bruff2016年03月25日 00:04:46 +00:00Commented Mar 25, 2016 at 0:04
-
\$\begingroup\$ And how do you count these bytes? \$\endgroup\$Riker– Riker2016年03月25日 15:39:14 +00:00Commented Mar 25, 2016 at 15:39
-
\$\begingroup\$ 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). \$\endgroup\$Stuart Bruff– Stuart Bruff2016年03月25日 16:29:52 +00:00Commented Mar 25, 2016 at 16:29
Python, 56 (the obvious way)
lambda N,R:__import__('random').sample(range(1,R+1),k=N)
-
\$\begingroup\$
from random import*;lambda N,R:sample(range(1,R+1),k=N)
is shorter by a byte \$\endgroup\$user45941– user459412016年03月24日 18:19:07 +00:00Commented Mar 24, 2016 at 18:19 -
\$\begingroup\$ Huh, I did consider
from random import*
, must've screwed up the counting. \$\endgroup\$shooqie– shooqie2016年03月24日 18:31:32 +00:00Commented Mar 24, 2016 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
-
\$\begingroup\$ One can no longer use
Ans
as input as per a recent meta post. \$\endgroup\$Conor O'Brien– Conor O'Brien2016年03月24日 19:04:27 +00:00Commented Mar 24, 2016 at 19:04 -
\$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ ...why not? \$\endgroup\$SuperJedi224– SuperJedi2242016年03月24日 19:05:55 +00:00Commented Mar 24, 2016 at 19:05
-
\$\begingroup\$ That was the consensus on meta. Vote on it if you disagree. \$\endgroup\$Conor O'Brien– Conor O'Brien2016年03月24日 19:07:44 +00:00Commented Mar 24, 2016 at 19:07
R=N=1
) Then I recommend allowing the ranges0..R
as an alternative as this comes more natural to many languages. \$\endgroup\$shuffle(0..N)
\$\endgroup\$new Date
yields non-uniform values. Further, I believe you can golf it tonew Date%r+1
;) \$\endgroup\$