Print a Block-Diagonal Matrix

J, 7 bytes

Thanks for FUZxxl for the 2-byte improvement.

Array based languages should be counted here in a different competition as they have a huge advantage. :)

   =/~@#<\

   (=/~@#<\) 3 1 1 2
1 1 1 0 0 0 0
1 1 1 0 0 0 0
1 1 1 0 0 0 0
0 0 0 1 0 0 0
0 0 0 0 1 0 0
0 0 0 0 0 1 1
0 0 0 0 0 1 1

Another 7-byte approach:

#]=@##\

Explanation for the old version ([:=/~]#<\):

The first step is generating n piece of similar things (e.g. numbers) for every list element n. These should be different from the other elements'. E.g. using the natural numbers 3 1 1 2 becomes 0 0 0 1 2 3 3.

To save on bytes we use the boxed prefixes of the list:

   ]#<\ 3 1 1 2
┌─┬─┬─┬───┬─────┬───────┬───────┐
│3│3│3│3 1│3 1 1│3 1 1 2│3 1 1 2│
└─┴─┴─┴───┴─────┴───────┴───────┘

With the =/~ verb we create a table of Descartes products of these boxed prefixes and each cell will be 1 if the two entries are equal 0 otherwise.


APL, 10

∘.=⍨∆/⍋∆←⎕

Example:

      ∘.=⍨∆/⍋∆←⎕
⎕:
      5 1 1 2 3 1 
1 1 1 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 1

Explanation:

  • ∆←⎕: read input, store in .
  • ⍋∆: find permutation that sorts (this gives an unique value for each value in the input)
  • ∆/: for each of those unique values, repeat it N times, where N is the corresponding value in the input
  • ∘.=⍨: make a matrix comparing each value in that list to the other values.

R, 69 63

function(x)write(+outer(i<-rep(1:length(x),x),i,"=="),1,sum(x))

Test Case:

(function(x)write(+outer(i<-rep(1:length(x),x),i,"=="),1,sum(x)))(c(5,1,1,3,1))
1 1 1 1 1 0 0 0 0 0 0 
1 1 1 1 1 0 0 0 0 0 0 
1 1 1 1 1 0 0 0 0 0 0 
1 1 1 1 1 0 0 0 0 0 0 
1 1 1 1 1 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 0 0 
0 0 0 0 0 0 1 0 0 0 0 
0 0 0 0 0 0 0 1 1 1 0 
0 0 0 0 0 0 0 1 1 1 0 
0 0 0 0 0 0 0 1 1 1 0 
0 0 0 0 0 0 0 0 0 0 1

The outer function does most of the work here, then its just a case of getting the output looking right - Thanks to @Vlo for his help with that