31
\$\begingroup\$

Here is a simple, bite-sized (byte-sized?) code golf: given a non-empty list of positive integers less than 10, print a block-diagonal matrix, where the list specifies the size of the blocks, in order. The blocks must consist of positive integers less than 10. So if you're given as input

[5 1 1 2 3 1]

Your output could be, for instance,

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

or

1 2 3 4 5 0 0 0 0 0 0 0 0
6 7 8 9 1 0 0 0 0 0 0 0 0
2 3 4 5 6 0 0 0 0 0 0 0 0
7 8 9 1 2 0 0 0 0 0 0 0 0
3 4 5 6 7 0 0 0 0 0 0 0 0
0 0 0 0 0 8 0 0 0 0 0 0 0
0 0 0 0 0 0 9 0 0 0 0 0 0
0 0 0 0 0 0 0 1 2 0 0 0 0
0 0 0 0 0 0 0 3 4 0 0 0 0
0 0 0 0 0 0 0 0 0 5 6 7 0
0 0 0 0 0 0 0 0 0 8 9 1 0
0 0 0 0 0 0 0 0 0 2 3 4 0
0 0 0 0 0 0 0 0 0 0 0 0 5

or something like that. The elements in the matrix must be separated by (single) spaces, and the rows separated by (single) newlines. There must not be leading or trailing spaces on any lines. You may or may not print a trailing newline.

You may write a function or program, taking input via STDIN (or closest alternative), command-line argument or function argument, in any convenient string or list format (as long as it isn't preprocessed). However, the result must be printed to STDOUT (or closest alternative), as opposed to returned from a function, say.

You must not use any built-in functions designed to create block-diagonal matrices.

This is code golf, so the shortest submission (in bytes) wins.

Leaderboards

I expect the array-based languages (like J and APL) to have the edge here, but I don't want that to discourage people from trying to do as well as they can in their language of choice. So here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language. So why not try and grab a spot on the latter?

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:true,success:function(e){answers.push.apply(answers,e.items);if(e.has_more)getAnswers();else process()}})}function shouldHaveHeading(e){var t=false;var n=e.body_markdown.split("\n");try{t|=/^#/.test(e.body_markdown);t|=["-","="].indexOf(n[1][0])>-1;t&=LANGUAGE_REG.test(e.body_markdown)}catch(r){}return t}function shouldHaveScore(e){var t=false;try{t|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(n){}return t}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading);answers.sort(function(e,t){var n=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0],r=+(t.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0];return n-r});var e={};var t=0,c=0,p=-1;answers.forEach(function(n){var r=n.body_markdown.split("\n")[0];var i=$("#answer-template").html();var s=r.match(NUMBER_REG)[0];var o=(r.match(SIZE_REG)||[0])[0];var u=r.match(LANGUAGE_REG)[1];var a=getAuthorName(n);t++;c=p==o?c:t;i=i.replace("{{PLACE}}",c+".").replace("{{NAME}}",a).replace("{{LANGUAGE}}",u).replace("{{SIZE}}",o).replace("{{LINK}}",n.share_link);i=$(i);p=o;$("#answers").append(i);e[u]=e[u]||{lang:u,user:a,size:o,link:n.share_link}});var n=[];for(var r in e)if(e.hasOwnProperty(r))n.push(e[r]);n.sort(function(e,t){if(e.lang>t.lang)return 1;if(e.lang<t.lang)return-1;return 0});for(var i=0;i<n.length;++i){var s=$("#language-template").html();var r=n[i];s=s.replace("{{LANGUAGE}}",r.lang).replace("{{NAME}}",r.user).replace("{{SIZE}}",r.size).replace("{{LINK}}",r.link);s=$(s);$("#languages").append(s)}}var QUESTION_ID=45550;var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:&lt;(?:s&gt;[^&]*&lt;\/s&gt;|[^&]+&gt;)[^\d&]*)*$)/;var NUMBER_REG=/\d+/;var LANGUAGE_REG=/^#*\s*([^,]+)/
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><link rel=stylesheet type=text/css href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id=answer-list><h2>Leaderboard</h2><table class=answer-list><thead><tr><td></td><td>Author<td>Language<td>Size<tbody id=answers></table></div><div id=language-list><h2>Winners by Language</h2><table class=language-list><thead><tr><td>Language<td>User<td>Score<tbody id=languages></table></div><table style=display:none><tbody id=answer-template><tr><td>{{PLACE}}</td><td>{{NAME}}<td>{{LANGUAGE}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table><table style=display:none><tbody id=language-template><tr><td>{{LANGUAGE}}<td>{{NAME}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table>

\$\endgroup\$
0

33 Answers 33

20
\$\begingroup\$

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.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ I don't think the parentheses around [:=/~]#<\ count towards your score. Also, =/~@#<\ for two extra bytes shaved off. \$\endgroup\$
    – FUZxxl
    Feb 11, 2015 at 10:49
  • \$\begingroup\$ "However, the result must be printed to STDOUT (or closest alternative), as opposed to returned from a function, say." You probably need either explicit input (so it's not just a function) or explicit output. \$\endgroup\$
    – marinus
    Feb 11, 2015 at 17:48
  • \$\begingroup\$ @marinus J prints the result of an expression to stdout if it's not bound to a variable. \$\endgroup\$
    – FUZxxl
    Feb 13, 2015 at 17:20
  • \$\begingroup\$ @FUZxxl: yes, but (=/~@#<\) is just a function. You'd have to actually apply it to something to get an expression, so you'd need explicit input (".1!:1[1), or if you want to submit a function, that function should actually print the value and not just return it (like echo@ or something). \$\endgroup\$
    – marinus
    Feb 15, 2015 at 14:13
  • 1
    \$\begingroup\$ =/~&I.­­­­­­­ \$\endgroup\$
    – ngn
    Oct 24, 2019 at 20:40
11
\$\begingroup\$

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.
\$\endgroup\$
8
  • \$\begingroup\$ To test this on http://tryapl.org, you might want to use the dfn {∘.=⍨⍵/⍋⍵}, as the site filters all uses of (except for ⎕IO and stuff like that). \$\endgroup\$
    – FUZxxl
    Feb 11, 2015 at 10:53
  • 1
    \$\begingroup\$ @FUZxxl: it says "However, the result must be printed to STDOUT (or closest alternative), as opposed to returned from a function, say.", so {∘.=⍨⍵/⍋⍵} isn't valid. You'd need {⎕←∘.=⍨⍵/⍋⍵}, which not only costs two characters but still wouldn't work on TryAPL. (And in general, TryAPL is too limited to be useful.) \$\endgroup\$
    – marinus
    Feb 11, 2015 at 11:10
  • \$\begingroup\$ If it has to print out the result, wouldn't you need a ⎕← anyway, even without the dfn? \$\endgroup\$
    – FUZxxl
    Feb 11, 2015 at 11:31
  • \$\begingroup\$ @FUZxxl: no, the output of an expression is printed automatically if nothing else is done with it. \$\endgroup\$
    – marinus
    Feb 11, 2015 at 11:41
  • \$\begingroup\$ Ah, I see. I was under the impression that this only happens when you are using the interpreter interactively. \$\endgroup\$
    – FUZxxl
    Feb 11, 2015 at 11:44
8
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ Very nice solution \$\endgroup\$
    – MickyT
    Feb 11, 2015 at 18:03
  • \$\begingroup\$ Great solution. Never thought about using -/+ to coerce logical. Save a few bytes function(x)write(+outer(i<-rep(1:length(x),x),i,"=="),1,sum(x)) 63 \$\endgroup\$
    – Vlo
    Feb 12, 2015 at 19:24
6
\$\begingroup\$

Python 3, 103 97 82 78 76 bytes

def P(L,n=0):k,*L=L;exec("print(*[0]*n+[1]*k+[0]*sum(L));"*k);L and P(L,n+k)

Using splat to take advantage of the space-separating nature of print, with a bit of recursion.

\$\endgroup\$
6
\$\begingroup\$

Ruby, 86 90 83 bytes

My first golf ever!

->l{n=l.reduce :+;s=0;l.map{|x|x.times{puts ([0]*s+[1]*x+[0]*(n-x-s))*" "};s+=x}}

Receives an array with the integers, prints the expected result:

$ (->l{n=l.reduce :+;s=0;l.map{|x|x.times{puts ([0]*s+[1]*x+[0]*(n-x-s))*" "};s+=x}}).call([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

Edit:

Thanks to Martin Büttner for helping me shortening some things!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save some more characters: ->(l) can be ->l. map is shorter than each. .join(" ") can be shortened to *" ". \$\endgroup\$ Feb 11, 2015 at 13:04
6
\$\begingroup\$

Matlab, 60 54 bytes

This would be Matlab's special field IF we could use builtin functions...

Thanks @sanchises for fixing the error I missed.

c=0;a=input('');for A=a;v=c+1:c+A;d(v,v)=1;c=c+A;end;d
\$\endgroup\$
9
  • \$\begingroup\$ Wooow, it was until now that I noticed that this js snippet actually produces a leaderboard!!! How did I never notice this??? Thanks for pointing this out=) \$\endgroup\$
    – flawr
    Feb 10, 2015 at 22:19
  • \$\begingroup\$ I know, right? It's really cool! \$\endgroup\$
    – Alex A.
    Feb 10, 2015 at 22:25
  • 1
    \$\begingroup\$ I was about to post almost the same answer :-) \$\endgroup\$
    – Luis Mendo
    Feb 10, 2015 at 22:55
  • \$\begingroup\$ The exact same or something slightly different? =) (Well apart from variable names.) \$\endgroup\$
    – flawr
    Feb 10, 2015 at 23:08
  • \$\begingroup\$ Too similar for me to post it :-) \$\endgroup\$
    – Luis Mendo
    Feb 11, 2015 at 22:52
6
\$\begingroup\$

Matlab, 53 bytes

Though it is only one char shorter than the other Matlab fragment, I figured the code is sufficiently different to warrant a new answer:

d=[];a=input('');for A=a;v=1:A;d(end+v,end+v)=1;end;d

The main trick is of course out of bounds indexing, but this is combined with using end as a variable to make it more compact.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Damn - I spent half an hour trying to golf end+1:end+v to get rid of a 'counter' variable, and I didn't think of this solution. \$\endgroup\$
    – Sanchises
    Feb 12, 2015 at 16:14
  • \$\begingroup\$ Indeed, as @Geobits mentioned the attempted edit by an anonymous into blkdiag would violate the requirements. Just for reference I will put the core of it here anyway: blkdiag(A,ones(i)) \$\endgroup\$ Feb 13, 2015 at 11:29
6
\$\begingroup\$

APL (Dyalog Extended), 6 bytes

∘.=⍨⍸⎕

Try it online!

A full program that takes the input vector from stdin and prints the matrix.


If a function returning a matrix were allowed:

APL (Dyalog Extended), 5 bytes

∘.=⍨⍸

Try it online!

APL wins back against J and K with the extended domain for .

How it works

∘.=⍨⍸
    ⍸  ⍝ Where; convert to an array that,
       ⍝   for each element n at index i, has n copies of i
∘.=⍨   ⍝ Outer product by element-wise equality on self
\$\endgroup\$
4
\$\begingroup\$

CJam, 21

q~{T):Ta*~}%_f{f=S*N}

Try it at http://cjam.aditsu.net/

Explanation:

q~          read and evaluate the input array
{…}%        transform each number using the block
    T):T    increment T (initially 0)
    a*      wrap T in an array and repeat it <number> times
    ~       dump the repeated numbers so they end up in a flat array
_           duplicate the array
f{…}        for each array item and the array
    f=      compare the current item with each item, resulting in an array of 1 and 0
    S*      join with spaces
    N       add a newline
\$\endgroup\$
4
\$\begingroup\$

Python 3, 79

def f(l,s=0):
 for x in l:r=[0]*sum(l);r[s:s+x]=[1]*x;s+=x;exec("print(*r);"*x)

Tracks the leftmost index of the block as s and makes the x entries after it be 1, where x is the current block size. This row is then printed x times. Python 3 is needed to do print(*r).

\$\endgroup\$
1
  • \$\begingroup\$ It's one char shorter to just do express r as [0]*s+[1]*x+[0]*(sum(l)-s-x), but I'm still looking for a better way. \$\endgroup\$
    – xnor
    Feb 11, 2015 at 0:20
4
\$\begingroup\$

Haskell, 118 116 bytes

(#)=replicate
f i=putStr$[e#(unwords$sum h#"0"++e#"1"++sum t#"0")|(h,e:t)<-map(`splitAt`i)[0..length i-1]]>>=unlines

Usage: f [2,1,1,3]

Output:

1 1 0 0 0 0 0
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 1
0 0 0 0 1 1 1
0 0 0 0 1 1 1

How it works:

[0..length i-1]           for each index n of the input list i
(h,e:t)<-map(`splitAt`i)  split i at n and
                            let e be the element at index n
                            let h be the list of elements to the left of e
                            let t be the list of elements to the right of e
                          foreach triple h, e, t make a list of
sum h # "0" ++              sh copies of "0" (sh = the sum of the elements of h) followed by
e # "1" ++                  e copies of "1" followed by
sum t # "0"                 st copies of "0" (st = the sum of the elements of t)
unwords                   join those list elements with spaces inbetween
e #                       make e copies
>>=unlines                join those lists with newlines inbetween
putStr                    print
\$\endgroup\$
2
  • \$\begingroup\$ You can save two bytes by doing (h,e:t)<-map(`splitAt`i)[0..length i-1], since n is not used outside the let binding. \$\endgroup\$
    – Zgarb
    Feb 15, 2015 at 15:38
  • \$\begingroup\$ @Zgarb: nice find. Thanks! \$\endgroup\$
    – nimi
    Feb 15, 2015 at 22:37
4
\$\begingroup\$

K (ngn/k), 12 bytes

5:'=/:/2#,&:

Try it online!

5: is "debug print". Since the default formatting of a matrix is not what is wanted here, it is printed row-wise via '.


if function returning a matrix (list of lists) were allowed:

K (ngn/k), 9 bytes

=/:/2#,&:

Try it online!

Took almost two years to golf a byte from the previous ngn/k answer :P

The algorithm itself is the same. The problem with making something a train is that you're allowed to reference the input only once. This code solves the problem by making =/: reduce over the two copies of the vector &x.

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

Pyth, 23 21 bytes

GitHub repository for Pyth

Ju+G*]GHQYFNJjdmsqdNJ

Input is a list of integers, like [3, 1, 1, 2]. Try it online: Pyth Compiler/Executor

Uses a quite similar idea as randomra's J code. The first part of the code Ju+G*]GHQY generates n parts of similar things. For the example input [3, 1, 1, 2] the result looks like this:

[
 [], 
 [], 
 [], 
 [[], [], []], 
 [[], [], [], [[], [], []]], 
 [[], [], [], [[], [], []], [[], [], [], [[], [], []]]], 
 [[], [], [], [[], [], []], [[], [], [], [[], [], []]]]
]

First three identical elements, than one element , then one element again and at the end two identical elements.

Ju+G*]GHQY
 u      QY  reduce the input Q, start with empty list G=[]
            for each H in input, replace the value of G by:
  +G*]GH       G+[G]*H
J           store the result in J

The second part of the code is comparing the elements of the Cartesian product and printing it.

FNJjdmsqdNJ
FNJ          for N in J:
     m    J     map each element d of J to
       qdN          the boolean value of d == N
      s             and convert it to an integer (0 = False, 1 = True)
   jd           print the resulting list seperated by d (=space)
\$\endgroup\$
0
3
\$\begingroup\$

C++ , 294 bytes

Compiler used - GCC 4.9.2

#include<bits/stdc++.h>
using namespace std;
#define F(a,b) for(a=0;a<b;a++)
#define V vector<int>
int n,i,j,s,o;
main(){V v;while(cin>>n)v.push_back(n),s+=n;vector<V> m(s,V(s,0));F(i,v.size()){F(j,v[i])F(n,v[i])m[j+o][n+o]=1;o+=v[i];}F(j,s){F(n,s)cout<<m[j][n]<<((n==s-1)?"":" ");cout<<"\n";}}

Explanation -:

#include<bits/stdc++.h>
using namespace std;
#define F(a,b) for(a=0;a<b;a++)
#define V vector<int>
int n, i, j, s, o;
/*
 n = Used to take inputs, and as an iterator after that
 i, j = Iterators
 s = sum of all the inputs
 o = offset ( used to find the location of the starting cell of the next matrix of 1's )
*/

main()
{
    V v;
    while ( cin >> n )  // Take input
    {
        v.push_back( n ), s += n;
    }

    vector<V> m( s, V( s, 0 ) ); // m is a matrix of size (s*s) with all elements initialized to 0
    F( i, v.size() )
    {
        F( j, v[i] )F( n, v[i] )m[j + o][n + o] = 1; // Assign 1 to the required cells
        o += v[i]; // Add the value of the current element to the offset
    }

    F( j, s )  // Output the matrix
    {
        F( n, s )cout << m[j][n] << ( ( n == s - 1 ) ? "" : " " ); // Prevent any trailing whitespace
        cout << "\n";
    }
}
\$\endgroup\$
0
3
\$\begingroup\$

K, 30 bytes

{"i"$,/x#',:',/'g=\:\:x#'g:<x}

Basically stole marinus's answer

k){"i"$,/x#',:',/' g=\:\:x#'g:<x}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
\$\endgroup\$
2
\$\begingroup\$

Java, 163

a->{int n=a.stream().mapToInt(x->x).sum(),t=0,j,k;for(int i:a){for(j=0;j++<i;System.out.println("\b"))for(k=0;k<n;)System.out.print(k>=t&k++<t+i?"1 ":"0 ");t+=i;}}

A consumer which accepts a list of integers.

Readable version, with boilerplate code:

java.util.function.Consumer<java.util.List<Integer>> c = a -> {
    int n = a.stream().mapToInt(x -> x).sum(), t = 0, j, k;
    for (int i : a) {
        for (j = 0; j++ < i; System.out.println("\b")) {
            for (k = 0; k < n;) {
                System.out.print(k >= t & k++ < t + i ? "1 " : "0 ");
            }
        }
        t += i;
    }
};

Invoke using:

List list = Arrays.asList(5, 1, 1, 2, 3, 1);
c.accept(list);
\$\endgroup\$
2
\$\begingroup\$

Python 2, 163 114 bytes

gnibbler golfed this a bunch.

h=input()
r=range
l=len(h)
for i in r(l):
 for k in r(h[i]):print" ".join("01"[i==j]for j in r(l)for x in r(h[j]))
\$\endgroup\$
4
  • 3
    \$\begingroup\$ how about print" ".join("01"[i==j]for j in r(l(h))for x in r(h[j]))? \$\endgroup\$
    – gnibbler
    Feb 10, 2015 at 20:06
  • \$\begingroup\$ Aha! I thought I could do something like that. \$\endgroup\$
    – KSFT
    Feb 10, 2015 at 23:47
  • \$\begingroup\$ This seems to only print one row of each block. \$\endgroup\$
    – xnor
    Feb 11, 2015 at 0:14
  • \$\begingroup\$ @xnor You're right; I fixed it. \$\endgroup\$
    – KSFT
    Feb 11, 2015 at 0:18
2
\$\begingroup\$

Python 3, 74

def f(a,p=0):n=a.pop(0);exec("print(*'0'*p+'1'*n+'0'*sum(a));"*n);f(a,p+n)
\$\endgroup\$
7
  • \$\begingroup\$ Doesn't this terminate with an error? \$\endgroup\$
    – xnor
    Feb 11, 2015 at 4:25
  • \$\begingroup\$ @xnor yes it does! \$\endgroup\$
    – feersum
    Feb 11, 2015 at 4:26
  • 1
    \$\begingroup\$ @feersum Is that allowed? I don't see any meta post on the issue. What do you think, Martin? If it's allowed, Sp3000 can save 6 chars by getting rid of the and short-circuit. \$\endgroup\$
    – xnor
    Feb 11, 2015 at 5:40
  • \$\begingroup\$ @xnor Does the error terminate the program or only the function call? If this terminates the program, then no I don't think it's allowed. I've expressed my opinion on this here on meta. I also think if feersum was of the opinion that this is completely legit, he would have stated it in his answer instead of hoping that no one notices. \$\endgroup\$ Feb 11, 2015 at 12:09
  • \$\begingroup\$ @MartinBüttner Terminate the program, if I understand what you're asking. If you were to do f([1,2,3]);print("Done"), the error would end the program after it prints the block matrix, and it wouldn't get to printing "Done". \$\endgroup\$
    – xnor
    Feb 11, 2015 at 21:10
2
\$\begingroup\$

JavaScript (ES6), 103 107

103 bytes as an anonymous function, not counting F= (but you need this to test it)

F=l=>alert(l.map((n,y)=>(l.map((n,x)=>Array(n).fill(x==y|0))+'\n').repeat(n))
.join('').replace(/,/g,' '))

Test In Firefox/FireBug console

F([5,1,1,2,3,1])

Output

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
\$\endgroup\$
2
\$\begingroup\$

Octave, 49 41 bytes

@(a)(c=repelems(b=1:length(a),[b;a]))'==c
\$\endgroup\$
1
\$\begingroup\$

Pyth, 31 30

FbQVbjd++*]0Z*b]b*]0--sQbZ)~Zb

A pretty naive program, takes the input on stdin. This can probably be golfed more ;)

Thanks @Jakube for pointing out a wasted char

Try it here

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

Perl, 69

#!perl -na
$j=s/./0 x$&/ger;print+($j|$i.1x$_)=~s/\B/ /gr x($i.=0 x$_,$_)for@F

Uses standard input:

$ perl a.pl <<<"1 2 3"
1 0 0 0 0 0
0 1 1 0 0 0
0 1 1 0 0 0
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
\$\endgroup\$
3
  • \$\begingroup\$ strangely, this doesn't print newlines for me on ideone. also, according to this post you should code the custom shebang as 4 bytes, not two. you can fix that by not using the shebag but instead using the flags on the interpreter and calling the code with -e instead of from a file (see examples in that meta post). also, I think you don't need the n flag - according to the perldoc, a sets n implicitly. \$\endgroup\$ Feb 11, 2015 at 11:53
  • \$\begingroup\$ The program reuses the eol from the standard input. Your ideone setup works when you add it. As for the character count, I count it this way in all my answers, and I've seen others do it this way too. I have seen the post you linked before, but I don't get what it means by "count the difference to perl -nl file.pl". Original perlgolf rules would count the hyphen but not the space so 3 characters in this case. \$\endgroup\$
    – nutki
    Feb 11, 2015 at 14:03
  • \$\begingroup\$ @MartinBüttner, it is all moot anyway as randomra's approach gives much shorter solution: -lna //,print join$",map$'==$_|0,@,for@,=map{(++$i)x$_}@F. BTW my version of Perl does not set -n with -a, it must be a recent addition. \$\endgroup\$
    – nutki
    Feb 11, 2015 at 14:39
1
\$\begingroup\$

R, 117 144 137 133 129 123 bytes

Reasonably verbose at the moment. Should be able to shave a few more out. Gained a number of bytes formatting it correctly, but saved some swapping out the matrix for an array.

Thanks to Alex for the tip on the replacing sep with s and removing the function name.

Dropped the array completely and used a series of reps to build each line.

Although soundly beaten by Miff, his solution made me realise I could drop the s=' ' altogether.

function(i){s=sum(i);i=cumsum(i);b=0;for(n in 1:s){d=i[i>=n][1];cat(c(rep(0,b),rep(1,d-b),rep(0,s-d)),fill=T);if(d==n)b=d}}

And the test

> (function(i){s=sum(i);i=cumsum(i);b=0;for(n in 1:s){d=i[i>=n][1];cat(c(rep(0,b),rep(1,d-b),rep(0,s-d)),fill=T,s=' ');if(d==n)b=d}})(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
> 
\$\endgroup\$
3
  • \$\begingroup\$ You can save 2 bytes using partial matching of function parameters. In cat(), change sep= to s= since no other recognized parameters for that function begin with "s". \$\endgroup\$
    – Alex A.
    Feb 10, 2015 at 21:19
  • \$\begingroup\$ @Alex Thanks, didn't realise that. Still on a learning curve \$\endgroup\$
    – MickyT
    Feb 10, 2015 at 21:51
  • \$\begingroup\$ You can save another 2 by removing f=. This gives you a function object. If you do that, you just have to stipulate that it be assigned using something like f= before running it. I didn't realize that was legit in contests like this until I saw Martin Büttner do it with Ruby. \$\endgroup\$
    – Alex A.
    Feb 10, 2015 at 21:57
1
\$\begingroup\$

Batch - 226 Bytes

@echo off&setLocal enableDelayedExpansion&set c=0&for %%a in (%*)do set/ac+=1&for /l %%b in (1,1,%%a)do (set l=&set d=0&for %%c in (%*)do (set/ad+=1&for /l %%d in (1,1,%%c)do if !d!==!c! (set l=!l!1)else set l=!l!0)
echo !l!)

Takes input from stdin (C:\>script.bat 5 1 1 2 3 1) and echo's output. Unfortunately I couldn't get that last echo on the same line, otherwise I could probably call the whole line within cmd/von/c to avoid having to enable delayed expansion the long way.

Nice and neat - nothing but grunt work:

@echo off
setLocal enableDelayedExpansion
set c=0
for %%a in (%*) do (
    set /a c+=1
    for /l %%b in (1,1,%%a) do (
        set l=
        set d=0
        for %%c in (%*) do (
            set /a d+=1
            for /l %%d in (1,1,%%c) do if !d!==!c! (set l=!l!1) else set l=!l!0
        )
        echo !l!
    )
)
\$\endgroup\$
1
\$\begingroup\$

Haskell, 124

(%)=replicate
d l=fst$foldr(\x(m,n)->(m>>mapM_(\_->putStrLn$unwords$n%"0"++x%"1"++(sum l-n-x)%"0")[1..x],n+x))(return(),0)l

Produces output by combining IO actions through mapM_ and foldr. The function d should be given a list of ints.

\$\endgroup\$
1
\$\begingroup\$

Jelly, 7 bytes

ĖŒṙ⁼þ`G

Try it online!

Same approach as the J answer.

      G    Grid format
   ⁼þ      a table of whether or not pairs of elements are equal, from
 Œṙ        the run-length decoded
Ė          enumeration of the input,
     `     compared with itself.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think Äx might work although I can't get it to work \$\endgroup\$
    – emanresu A
    Jul 29, 2022 at 11:31
  • \$\begingroup\$ @emanresuA If the grid formatting weren't mandatory, Äxµ⁼þ would be shorter, but the best I can think of considering it is is Äx¹⁼þG` which ties. Nice thinking though--and gets me thinking maybe x's arguments should be the other way around! \$\endgroup\$ Jul 29, 2022 at 23:21
1
\$\begingroup\$

Julia 1.6, 68 bytes

>(L,c=0)=((x,l...)=L;print(("0 "^c*"1 "^x*"0 "^sum(l)*"
")^x);l>c+x)

Attempt This Online!

port of Sp3000's answer

needs julia 1.6 for x,l...=L

output as a matrix would save a lot of bytes but printing it as expected uses more bytes:

!L=(l=[(a=1;L.|>i->(a+=1)ones(i))...;]).==l' (44bytes)

\$\endgroup\$
1
\$\begingroup\$

Uiua, 20 bytes

4 bytes for constructing the array; 16 bytes for formatting the output :/

≡(&p↘1/⊂)∵⊂@ +@0⊞=.⊚

Try it online!

Explanation

                ⊞=.⊚ # construct the table in the same way as other array languages
             +@0     # convert numbers to characters
      /⊂ ∵⊂@         # interleave spaces (including leading space)
    ↘1               # remove said leading space
≡(&p    )            # and print each line
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 7 bytes

żẋf:v=⁋

Try it Online! -1 byte thanks to lyxal.

Same approach as a lot of the array-language answers

 ẋ      # Repeat elements of
ż       # [1...len(input)
 ẋ      # By numbers in the input
  f     # Flatten
   :v=  # Table by equality
      ⁋ # Format as grid
\$\endgroup\$
1
  • \$\begingroup\$ It seems like żẋf:v=⁋ can work for 7 bytes \$\endgroup\$
    – lyxal
    Nov 7, 2023 at 12:22
1
\$\begingroup\$

K (ngn/k), 14 bytes:

{5:'x=\:x:&x;}

fixed. now prints to stdout

\$\endgroup\$
3
  • 1
    \$\begingroup\$ {x=\:x:&x}­­­ \$\endgroup\$
    – ngn
    Oct 24, 2019 at 20:41
  • \$\begingroup\$ @ngn oh come on... \$\endgroup\$
    – scrawl
    Oct 25, 2019 at 8:12
  • \$\begingroup\$ this challenge had been discussed in the apl room, i knew the solution from there :) k and j have an advantage here because their "where"-s (& in k or I. in j) work with int vectors, while apl's works only with booleans. \$\endgroup\$
    – ngn
    Oct 25, 2019 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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