-3
\$\begingroup\$

Goal:

Write a piece of code that produces a array containing all integer values in a set range in random order (upper and lower bounds included).
Use any language you like, but use as little built-in functions as possible (ie PHP's array_shuffle should be avoided)

Rules:

  • All ints in the range must be used once, and only once
  • The range can be negative, or positive
  • When using JavaScript: ECMAScript6 features are to be avoided
  • If you choose to write a function the function(params){ and closing } needn't be counted. Bonus points for clever argument validation/normalization if you do write a function
  • Aliases like m = Math; or Array.prototype.p = [].push; will be counted, using closures/functions, passing Math as an argument will be counted as <argName>=Math;

Benchmark:

As a starting point or target: here's a snippet that meets all of the criteria apart from the randomness. It's approx. 50 bytes long (depending on v's value). That would be a nice target to hit:

for(l=3,a=[v=12],i=v>0?-1:1;(v+=i)!=l+i;)a.push(v)

Caveats: if l is bigger than v, the code fails.

\$\endgroup\$
  • \$\begingroup\$ @MartinBüttner: sorry, first post. Didn't realize language-specific challenges are discouraged. Would expanding the question to the entire ECMAScript family be desirable? Also: Sure, this is code-golf. It's not a question of "how should I write this?" :-) \$\endgroup\$ – Elias Van Ootegem Oct 3 '14 at 10:41
  • \$\begingroup\$ @MartinBüttner: Done. \$\endgroup\$ – Elias Van Ootegem Oct 3 '14 at 11:58
  • 3
    \$\begingroup\$ Why the hate against ecmascript? With other languages allowed, Javascript won't win anyway. \$\endgroup\$ – Ingo Bürk Oct 3 '14 at 12:21
  • 2
    \$\begingroup\$ Rules 3,4,5 don't make sense. \$\endgroup\$ – edc65 Oct 3 '14 at 13:29
  • \$\begingroup\$ @edc65: Those rules stem from the initial question, which was JavaScript specific. I edited that part out, because it was pointed out that language-specific questions are discouraged \$\endgroup\$ – Elias Van Ootegem Oct 3 '14 at 14:46
1
\$\begingroup\$

APL, 18

{(⍺⌊⍵)-1-?⍨1+|⍺-⍵}

Takes upper/lower bounds as left/right argument. Works for any bounds, also reversed bounds. Can be shortened to 13 characters if the assumption l<=u can be made:

{⍺-1-?⍨⍵-⍺-1}

Try

\$\endgroup\$
0
\$\begingroup\$

GolfScript (26 bytes)

~)1$-:x,\{+}+%{;x.*rand}$`

Online demo

Could be slightly shorter but at the cost of worse randomisation. By picking random numbers up to the square of the size of the range I come close enough IMO to avoiding collisions.

\$\endgroup\$
0
\$\begingroup\$

JavaScript, 73 bytes

for(i=l,s=[];i<=u;)s[i-l]=i++;s.sort(function(){return Math.random()<.5})

Assumes l and u have the lower and upper bounds resp. and l<=u

\$\endgroup\$
0
\$\begingroup\$

PYTHON, 21

list(set(range(l,u+1)))

  • assumes l <= u

I believe set uses the hash value of the arguments for the order of this list it generates. This generates kind-of random ordering, for example with l, u = 30, 50, I get [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 30, 31]. I'd say this still counts though.

\$\endgroup\$
0
\$\begingroup\$

J (11 (or 9))

f=:>.-?~@>:@|@-

This defines a dyadic function, the arguments of which define the start and end of the range. The order of the arguments doesn't matter. (Does this give me bonus points?)

As per the rules, I'm not counting f=: as this is part of the function definition (i.e., what would be function f(params){...}. An anonymous function would be (>.-?~@>:@|@-), where the () can be disregarded according to that rule.

If I can assume the left argument to be the upper bound, and the right argument to be the lower bound, it can be shortened to 9:

g=:[-?~@>:@-

Or, as an anonymous function, ([-?~@>:@-).

Test:

   f=:>.-?~@>:@|@-
   g=:[-?~@>:@-
   _5 f 10
_1 2 0 _2 _5 3 _4 _3 1 9 4 10 5 7 6 8
   2 f 10
2 10 5 3 8 4 9 7 6
   10 f 2
2 9 4 5 6 10 3 7 8
   10 f _5
_3 9 4 3 2 6 _2 1 5 8 7 _1 _4 10 _5 0
   10 g 2
2 3 4 7 9 5 6 10 8
   10 g _5
1 2 7 4 3 _4 5 8 6 9 _1 10 0 _5 _2 _3
\$\endgroup\$
  • \$\begingroup\$ _5 === -5 ? Also, not sure if that is a valid way of providing input to the program. \$\endgroup\$ – Optimizer Oct 3 '14 at 14:03
  • \$\begingroup\$ @Optimizer: yes, _5 is the J representation of -5. (That's necessary, because arrays are written as 0 1 2 3. So [0,1,-2,3] would be written as 0 1 _2 3, whereas 0 1 -2 3 means (0 1)-(2 3), i.e. _2 _2.) As for providing input, it's just a function. a F b is J for F(a,b). There are more people who have submitted functions, and there are even people who just assume preset variables. \$\endgroup\$ – marinus Oct 3 '14 at 14:42
  • \$\begingroup\$ I agree, but both of the other assumptions add extra bytes to the code, while you take the benefit of having the input already present. For instance, I can assume that both integers are already on stack in my CJam answer and get rid of two more bytes making the final answer only 10 bytes. \$\endgroup\$ – Optimizer Oct 3 '14 at 14:45
  • \$\begingroup\$ @Optimizer: according to the rules, you can define a function, and you don't have to count the function definition boilerplate. I'm not that familiar with CJam, but in Golfscript you can do {...}:f;, if I'm not mistaken, and you wouldn't have to count the {}:f; part. So if CJam works the same way, you could do that and be within the rules. \$\endgroup\$ – marinus Oct 3 '14 at 15:06
  • \$\begingroup\$ Hmm, that rule needs to be more clear that it is for all languages and not just JS. \$\endgroup\$ – Optimizer Oct 3 '14 at 15:10
0
\$\begingroup\$

CJam, 12 (or 10) bytes

Aannnd, if other languages are allowed, here is an answer in CJam

{$~1$-),f+mr`}:F;

This creates a function F , thus not counting the { and }:F;.

Example Usage:

{$~1$-),f+mr`}:F;
[7 -2]F

Output:

[1 -2 6 2 -1 5 7 0 3 4]

If I assume that first integer is always less than the second integer, then the code comes down to 10 bytes:

{1$-),f+mr`}:F;

Example usage:

{1$-),f+mr`}:F;
-2 7F

Output:

[1 -2 6 2 -1 5 7 0 3 4]

Try it online here

\$\endgroup\$
0
\$\begingroup\$

Perl - 19

sort{rand>.5}$l..$v

Assuming $l and $v are already defined. If you wanted to make it a function:

sub random_array {
    sort{rand>.5}$_[0].._$[1]
}

You can try it with:

perl -E'$,=",";$l=1; $v=15; say sort{rand>.5}$l..$v'

or

perl -E'say random_array(0,5);sub random_array{sort{rand>.5}$_[0]..$_[1]}'
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.