4
\$\begingroup\$

Challenge

Task

Given a number N, output 2 NxN squares; each line of each square is a random permutation of [0, N); the squares are separated by a newline

Rules

  • Produce a randomised list of length N, separated by space
  • Repeat this N*2 times
  • Separate each output with a newline, with 2 newlines at the midpoint
  • The value of n must be "obvious", you can get it via stdin; argument; whatever, but there must be a distinct value somewhere, so the value of n can't just be scattered across your program.

Example

Given n = 4, the output could be:

1 2 0 3
2 3 1 0
2 0 3 1
2 0 3 1

0 3 2 1
3 1 0 2
0 1 3 2
0 2 1 3

Lowest number of bytes wins

\$\endgroup\$
  • \$\begingroup\$ Do columns need to be aligned? - it matters for n>9 \$\endgroup\$ – Digital Trauma Mar 12 '15 at 0:58
  • \$\begingroup\$ nah, i wouldn't worry \$\endgroup\$ – LordAro Mar 12 '15 at 1:05
  • \$\begingroup\$ Is it not a code-golf question (I mean code-golf tagged) ? \$\endgroup\$ – kuldeep.kamboj Mar 12 '15 at 6:03
  • \$\begingroup\$ Does the function need to be able to output all random permutation? \$\endgroup\$ – dwana Mar 12 '15 at 10:15
  • 2
    \$\begingroup\$ I should think so, otherwise you could just hardcode it to output "1 2 3 4" and call it random ( xkcd.com/221 ) \$\endgroup\$ – LordAro Mar 12 '15 at 12:50

18 Answers 18

9
\$\begingroup\$

J, 9 7 bytes

Thanks to @randomra for shaving off two characters:

?~2&,]

Previously I had:

?~($~2&,)

These are functions, you can apply them to an argument directly or store them in a variable and then use them:

   (?~2&,$]) 5
1 0 4 2 3
2 4 0 3 1
2 3 1 0 4
2 3 0 1 4
3 0 1 4 2

1 4 0 2 3
2 1 4 3 0
2 3 1 0 4
2 3 1 4 0
0 1 2 3 4

   f=.?~2&,$]
   f 5
4 2 3 0 1
3 4 1 0 2
3 4 0 2 1
1 2 4 3 0
2 0 4 1 3

2 1 3 0 4
1 3 4 2 0
2 4 1 3 0
3 2 1 0 4
3 0 4 2 1
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ ?~2&,$] saves 2 bytes. \$\endgroup\$ – randomra Mar 12 '15 at 4:12
4
\$\begingroup\$

Pyth, 13

V2VQjdoOQUQ)k

Pretty simple program, I believe it follows the spec.

Try it online here

Explanation:

                   : Q = eval(input)
V2                 : Do the next part twice
  VQ       )       : Do the stuff before the ) Q times
    jd             : Join the resulting list on spaces
      oOQUQ        : order range(Q) by random_int( from 0 to Q )
            k      : print nothing (pyth auto-pads each print with a newline)
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

R, 73 71 66 62 54

I feel there should be a better way, but at the moment

n=5;for(i in 1:(n*2))cat(sample(n)-1,rep('\n',1+!i-n))

Edit: Replace rank(runif(1:n))-1 with sample(1:n)-1. Used rep instead of if. Thanks to Alex A for a few more.

Test run

> n=5;for(i in 1:(n*2))cat(sample(n)-1,rep('\n',1+!i-n))
0 3 1 2 4 
0 1 4 2 3 
2 3 4 0 1 
4 1 0 2 3 
1 0 3 4 2 

4 3 1 0 2 
3 0 1 2 4 
4 2 3 1 0 
4 2 1 0 3 
3 1 0 2 4 
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can save a byte by doing n=scan();for(i in 1:(2*n)) rather than assigning n inside for(). \$\endgroup\$ – Alex A. Mar 12 '15 at 14:19
  • \$\begingroup\$ You can save another 2 bytes by doing sample(n) rather than sample(1:n) since they're equivalent. \$\endgroup\$ – Alex A. Mar 12 '15 at 14:20
  • \$\begingroup\$ And what is 1+!i-n doing? \$\endgroup\$ – Alex A. Mar 12 '15 at 14:25
  • \$\begingroup\$ @AlexA. It was the shortest way I could think of doing 1 except when i == n, so it is equivalent to 1+(i==n) . I also got rid of the vector constructor in the cat \$\endgroup\$ – MickyT Mar 12 '15 at 17:52
  • \$\begingroup\$ Ah, okay. Clever. Right now you're hard-coding n but doesn't it still need to come from input? Or does simply defining it like that constitute "obvious" per the OP's rules? (It is obvious...) \$\endgroup\$ – Alex A. Mar 12 '15 at 18:22
2
\$\begingroup\$

CJam, 22 bytes

l~{_{_,mrS*N@}*N\}2*;;

Input via STDIN. I feel like there must be a much way to do this.

Test it here.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Bash+coreutils, 61

Input as a command-line arg.

seq -f"((%g))&&echo \`seq 0 $[$1-1]|shuf\`||echo" -$1 $1|bash
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Clip, 29

[zjm[ Jm[ jkwRRzwS}Rz}R2:2N]n

Takes input from STDIN.

[z                         ]n  .- z is the numeric value of the input -.
  j                     :2N    .- join with two newlines              -.
   m[                }R2       .- do twice                            -.
      J                        .- join with a newline                 -.
       m[         }Rz          .- do z times                          -.
          j     wS             .- join with spaces                    -.
           kw                  .- wrap each number                    -.
             R                 .- shuffle                             -.
              Rz               .- list of the first z numbers         -.

Example run:

> java -jar clip4.jar random.clip
4
2 1 0 3
3 1 2 0
1 0 2 3
3 1 0 2

3 0 1 2
0 1 2 3
3 2 0 1
0 1 3 2
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Python 3, 90 bytes

from random import*
def f(n):S="*L,=range(n);shuffle(L);print(*L);"*n;exec(S+"print();"+S)

I'm sure there's a better method for handling the newline break in between, but I'm having trouble coming up with a way.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

CJam, 20 19 bytes

ri_a*0+2*{,mrS*}%N*

Try it here (for Firefox).

Other solutions:

{T,mrS*N}_ri:T*N](T*
"T,mrS*N"ri:T*:F~NF~
LN]"T,mrS*N"ri:T*f{~}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Is a trailing newline ok? You can put N in the block \$\endgroup\$ – aditsu quit because SE is EVIL Mar 12 '15 at 10:06
  • \$\begingroup\$ @aditsu Then there will be two trailing newlines. \$\endgroup\$ – jimmy23013 Mar 12 '15 at 10:10
  • \$\begingroup\$ Oh, right.. it's not obvious in the online interpreter. \$\endgroup\$ – aditsu quit because SE is EVIL Mar 12 '15 at 10:17
2
\$\begingroup\$

Java, 190 187 bytes

void f(int n){int k=0,i,t,x,o[]=new int[n];for(;k<n;o[k]=k++);for(k=0;k++<n*2;)for(i=n;i>0;t=o[x*=Math.random()],o[x]=o[i],o[i]=t,System.out.print(o[i]+(i>0?" ":k==n?"\n\n":"\n")))x=i--;}

Clunky, but it does the job (that's Java's motto, right?). Pretty simplistic: it fills an array, then repeatedly uses my earlier Fisher-Yates to shuffle and print. I tried using Collections.shuffle() instead, but it was a touch longer once you add in the import.

Ah well, such is life.

With line breaks:

void f(int n){
    int k=0,i,t,x,o[]=new int[n];
    for(;k<n;o[k]=k++);
    for(k=0;k++<n*2;)
        for(i=n;
            i>0;
            t=o[x*=Math.random()],
            o[x]=o[i],
            o[i]=t,
            System.out.print(o[i]+(i>0?" ":k==n?"\n\n":"\n"))
        )
            x=i--;
}
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save a byte by removing the +" ", and using i>0?" ":k==n?" \n\n":" \n" instead. \$\endgroup\$ – Ypnypn Mar 12 '15 at 3:33
  • \$\begingroup\$ @Ypnypn Saved three with it, since I don't need trailing spaces with newlines. Thanks :) \$\endgroup\$ – Geobits Mar 12 '15 at 13:05
1
\$\begingroup\$

Python - 139 138 bytes

import random as r
n=4
s=range
t=s(0,4)
print('\n\n'.join('\n'.join(' '.join('%d'%i for i in r.sample(t,n)) for j in t) for k in s(0,2)))

EDIT: Knocked off a byte

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$
import static java.lang.System.out;public class A{public static void main(String[]a){int n=Integer.decode(a[0]);for(int x=0;x<2;x++){for(int i=0;i<n;i++){java.util.stream.IntStream.range(0,n).parallel().forEach(k->out.print(k+" "));out.println();}out.println();}}}

As short as I could manage in Java - 265 bytes.

It takes an ordered stream of n integers and concurrently prints them separated by a space, so the output order is non-deterministic and it does this per line.

EDIT:

If done as only a function:

void g(int n){for(int x=0,i=0;x<2;x++){for(;i<n;i++){java.util.stream.IntStream.range(0,10).parallel().forEach(k->out.print(k+" "));System.out.println();}System.out.println();}}}}}

This is 179 bytes; the ordering may not seem very random - but as far as I'm aware it is quite non-deterministic.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ You could use a function instead. \$\endgroup\$ – TheNumberOne Mar 12 '15 at 0:12
  • \$\begingroup\$ This has got to be the worst RNG ever. I like it for sheer cheek, but the "randomness" is terrible :) \$\endgroup\$ – Geobits Mar 12 '15 at 1:53
  • \$\begingroup\$ Plus, you could declare x and i together with n and scrape off a few characters. \$\endgroup\$ – Rodolfo Dias Mar 12 '15 at 9:43
  • \$\begingroup\$ I agree that it's non-deterministic, but our standard definition of "random" can be found here for future reference: meta.codegolf.stackexchange.com/a/1325/14215 \$\endgroup\$ – Geobits Mar 12 '15 at 14:27
1
\$\begingroup\$

Rebol - 76 75

N: 4 do b:[loop N[print random collect[repeat i N[keep i - 1]]]]print""do b

Ungolfed:

N: 4 

do b: [
    loop N [
        print random collect [
            repeat i N [keep i - 1]
        ]
    ]
]

print ""
do b
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 109

$n=4;$p=range(0,$n-1);for($k=0;$k<2;$k++){for($i=0;$i<$n;$i++){shuffle($p);echo join(' ',$p)."\n";}echo"\n";}

New implemented solution uses 1 more bytes. But now fulfill OP requirement.

Old solution which do not randomize permutation of line.

PHP, 108

$n=4;for($k=0;$k<2;$k++){for($i=0;$i<$n;$i++){for($j=0;$j<$n;$j++)echo rand(0,$n-1)." ";echo"\n";}echo"\n";}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This solution is wrong. "each line of each square is a random permutation of [0, N)" \$\endgroup\$ – abc667 Mar 12 '15 at 15:40
  • \$\begingroup\$ Rule 3, quoting: "the value of n can't just be scattered across your program". The first 5 characters are $n=4;. There is nothing reading anything from STDIN, argument, POST, GET, COOKIE, SESSION.... Nothing. \$\endgroup\$ – Ismael Miguel Mar 12 '15 at 16:05
  • \$\begingroup\$ @IsmaelMiguel, Many of other answers also uses the variable assignment instead of parameter/STDIN. And they also get more upvotes. So I am confusing if using assignment will broke rule. I think what OP wants not to use constant 4 or any other integer in program to same these 5 bytes. See but there must be a distinct value somewhere \$\endgroup\$ – kuldeep.kamboj Mar 13 '15 at 5:36
  • \$\begingroup\$ @abc667, I did not understood how each line is not randomized when individual element is random. \$\endgroup\$ – kuldeep.kamboj Mar 13 '15 at 5:39
  • \$\begingroup\$ Lines aren't suppose to be random but be random permutation of [0,n). Line 1 1 1 1 is wrong. There must be every number from (1,2,3,4) and every number must appear exactly once. \$\endgroup\$ – abc667 Mar 13 '15 at 6:23
0
\$\begingroup\$

PHP (106 bytes):

This one was quite unexpectedly hard.

But here is a somewhat large solution:

<?for(;3>$j++;$o='',$z=range(0,($i=$n=$_GET[n])-1)){for(;$i--;shuffle($z))$o.=join(' ',$z)."
";echo"$o
";}

This can be rewritten to Javascript quite 'easily'.

For this to work, you must access the file over an http server, with ?n=<number> appended to the name.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ruby - 69

r=->(n){[0,0].map{(1..n).map{(0..n-1).to_a.shuffle*" "}*"\n"}*"\n\n"}

Sample output:

puts r[5]

yields:

3 0 2 1 4
0 4 1 3 2
2 1 0 4 3
0 4 2 1 3
4 1 2 3 0

4 0 3 2 1
3 1 0 2 4
3 4 0 2 1
0 2 3 4 1
3 2 4 0 1

and

puts r[7]

yields

5 4 0 6 1 3 2
6 3 1 2 4 0 5
5 2 1 0 6 4 3
4 0 5 2 3 1 6
0 6 3 1 4 5 2
6 3 0 2 5 1 4
2 4 1 0 6 5 3

0 1 4 3 6 5 2
3 5 4 2 6 1 0
2 3 5 1 4 6 0
3 0 5 2 1 4 6
4 6 5 0 2 3 1
6 5 3 2 0 4 1
3 4 6 1 0 5 2
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I think I can shave some bytes by making a helper function, give me a minute. \$\endgroup\$ – Devon Parsons Mar 12 '15 at 15:58
  • \$\begingroup\$ It was too complicated to create a helped function :( \$\endgroup\$ – Devon Parsons Mar 12 '15 at 16:34
  • \$\begingroup\$ Your lines appear to be random numbers in [0, N-1], whereas they should be random permutations of [0, N-1]. \$\endgroup\$ – Théophile Mar 15 '15 at 5:30
  • 1
    \$\begingroup\$ @Théophile fixed; interestingly it's the same length as before \$\endgroup\$ – Devon Parsons Mar 15 '15 at 15:24
0
\$\begingroup\$

Scala, 105 98 95 84 bytes

(n:Int)=>{def s=0.until(n).permutations take n map(_ mkString " ") mkString "\n";s+"\n\n"+s}

Ungolfed

def squares(n: Int): String = {
  def square(n: Int): String = 0.until(n).permutations.take(n).map(_.mkString(" ")).mkString("\n")
  square(n)+"\n\n"+square(n)
}
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

C++ 201

void f(int n)
{
std::vector<int> v;int N=n;
while(n--)v.push_back(n);
for(int i=0;i<2*N+1;i++)
{
random_shuffle(v.begin(),v.end());
if(!(i==N))for(int j=0;j<N;j++)printf("%d ",v.at(j));
else puts("");
puts("");
}
}
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 13 bytes

2FFL<.rðý,}¶?

Try it online.

Or alternatively:

·FIL<.r})»2ä»

Try it online.

Explanation:

2F          # Loop 2 times:
  F         #  Inner loop the (implicit) input amount of times:
   L<       #   Push a list in the range [0, (implicit) input-1]
     .r     #   Randomly shuffle it
       ðý   #   Join it by spaces
         ,  #   Pop and output it with trailing newline
  }¶?       #  After the inner-loop is done: print a newline

·           # Double the (implicit) input
 F          # Loop that many times:
  IL<       #  Push a list in the range [0, input-1]
     .r     #  Randomly shuffle it
 })         # After the loop: wrap everything on the stack into a list
   »        # Join each inner list by spaces, and then each string by newlines
    2ä      # Split it into a list of two equal-sized strings
      »     # And join those by newlines as well (which is output implicitly as result)

If a leading instead of trailing newline is allowed, the first version could be 2F¶?FL<.rðý, instead, to save a byte on the }: Try it online.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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