23
\$\begingroup\$

Challenge:

Take a list, L containing positive integers as input:

3 5 2 1 6

and create a matrix where the n'th column contains the vector 1:L(n), where shorter rows are padded with zeros.

Test cases:

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

1
-
1

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

Rules:

  • Optional input and output formats
    • List of lists is an acceptable output format
  • The matrix must be as small as possible (you may not pad it with more zeros than needed)
  • Shortest code in each language wins
  • Explanations are highly encouraged
\$\endgroup\$
6
  • \$\begingroup\$ May we distribute the ranges horizontally instead? \$\endgroup\$
    – Mr. Xcoder
    Commented Sep 7, 2017 at 19:03
  • \$\begingroup\$ No, they should be vertical. If you use a language where the words horizontal/vertical doesn't have any meaning then it's optional. (Could be relevant for languages where lists of lists aren't associated with either horizontal/vertical directions) \$\endgroup\$ Commented Sep 7, 2017 at 19:11
  • 1
    \$\begingroup\$ @StewieGriffin What sane language doesn't associate dimensions with nested lists? \$\endgroup\$ Commented Sep 8, 2017 at 9:22
  • 6
    \$\begingroup\$ @EriktheOutgolfer, How many insane languages are used on this site? \$\endgroup\$ Commented Sep 8, 2017 at 9:31
  • 3
    \$\begingroup\$ @EriktheOutgolfer R for one doesn't see matrices as nested list, but rather one long list, which wraps around row-wise. \$\endgroup\$
    – JAD
    Commented Sep 8, 2017 at 11:35

29 Answers 29

21
\$\begingroup\$

R, 40 38 bytes

function(l)outer(m<-1:max(l),l,"<=")*m

Try it online!

Explanation:

outer applies its third argument (the function) to all combinations of elements of its first two arguments, generating a matrix of TRUE and FALSE where each column has TRUE where 1:max(l) is less than or equal to the corresponding element of l, for the example where l=c(3,5,2,1,6):

      [,1]  [,2]  [,3]  [,4] [,5]
[1,]  TRUE  TRUE  TRUE  TRUE TRUE
[2,]  TRUE  TRUE  TRUE FALSE TRUE
[3,]  TRUE  TRUE FALSE FALSE TRUE
[4,] FALSE  TRUE FALSE FALSE TRUE
[5,] FALSE  TRUE FALSE FALSE TRUE
[6,] FALSE FALSE FALSE FALSE TRUE

Then supposing the resultant matrix is A, then A*m -> A[i,j]=A[i,j]*i which coerces TRUE to 1 and FALSE to 0, producing the desired result.

\$\endgroup\$
7
  • \$\begingroup\$ I think - you can save 2 bytes, by replacing function(l) with l=scan(); \$\endgroup\$
    – AndriusZ
    Commented Sep 8, 2017 at 7:34
  • \$\begingroup\$ @AndriusZ but then I'd have to wrap everything in a print so I would lose those bytes. \$\endgroup\$
    – Giuseppe
    Commented Sep 8, 2017 at 12:02
  • \$\begingroup\$ I think, you don't need to wrap everything - TOI \$\endgroup\$
    – AndriusZ
    Commented Sep 8, 2017 at 12:13
  • 2
    \$\begingroup\$ @AndriusZ we've definitely talked about this before. The only answer to this meta question gives a +4 penalty for using source(...,echo=TRUE) and reading from stdin as a full program, if you have an alternative suggestion, by all means weigh in there, but as far as I'm aware that's the closest we have to an R consensus on full programs and it stands for the time being. \$\endgroup\$
    – Giuseppe
    Commented Sep 8, 2017 at 12:20
  • \$\begingroup\$ Late to the game: save two bytes using [this tip] (codegolf.stackexchange.com/a/111578/80010) \$\endgroup\$
    – JayCe
    Commented May 2, 2018 at 1:36
7
\$\begingroup\$

MATL, 8 bytes

"@:]Xho!

Try it online!

Explanation

"      % Implicit input, L. For each k in L
  @    %   Push k
  :    %   Range [1 2 ... k]
]      % End
Xh     % Collect all stack contents in a cell array
o      % Convert to double matrix. The content of each cell is
       % right-padded with zeros if needed
!      % Transpose. Implicitly display
\$\endgroup\$
6
\$\begingroup\$

Python 3, 54 bytes

lambda x:[[-~i*(i<a)for a in x]for i in range(max(x))]

Try it online!

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

Mathematica, 20 bytes

PadRight@Range@#&

Contains U+F3C7 (Mathematica's builtin Transpose function)

Try it on Wolfram Sandbox

Usage

PadRight@Range@#&[{3, 5, 2, 1, 6}]
{
 {1, 1, 1, 1, 1},
 {2, 2, 2, 0, 2},
 {3, 3, 0, 0, 3},
 {0, 4, 0, 0, 4},
 {0, 5, 0, 0, 5},
 {0, 0, 0, 0, 6}
}

Explanation

PadRight@Range@#&

         Range@#    (* Generate {1..n} for all elements of input *)
PadRight@           (* Right-pad 0s so that all lists are equal length *)
                   (* Transpose the result *)
\$\endgroup\$
2
  • \$\begingroup\$ @downvoters why the downvotes? Could y'all explain? \$\endgroup\$ Commented Sep 7, 2017 at 22:57
  • \$\begingroup\$ I didn't downvote, but I suspect it is because you are lacking the function signature or an input of arguments, which causes your code snippet not to be a black box! \$\endgroup\$
    – sergiol
    Commented Apr 12, 2018 at 17:50
6
\$\begingroup\$

Octave, 26 bytes

@(x)((y=1:max(x))'<=x).*y'

Anonymous function that inputs a row vector and outputs a matrix.

Try it online!

Explanation

Consider input x = [3 5 2 1 6]. This is a row vector of size 1×5.

1:max(x) gives the row vector [1 2 3 4 5 6], which is assigned to variable y.

The transpose of that, i.e. the column vector [1; 2; 3; 4; 5; 6], is <=-compared (element-wise with broadcast) with the input [3 5 2 1 6]. The result is the 6×5 matrix

[1 1 1 1 1;
 1 1 1 0 1;
 1 1 0 0 1;
 0 1 0 0 1;
 0 1 0 0 1;
 0 0 0 0 1]

Finally, multiplying (element-wise with broadcast) by the column vector [1; 2; 3; 4; 5; 6], obtained as y transposed, gives the desired result:

[1 1 1 1 1;
 2 2 2 0 2;
 3 3 0 0 3;
 0 4 0 0 4;
 0 5 0 0 5;
 0 0 0 0 6]
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I was hoping to see a MATLAB/Octave submission. I implemented this without putting any thought into it, so it was probably more than 40 bytes. Very nice solution :) \$\endgroup\$ Commented Sep 8, 2017 at 4:54
4
\$\begingroup\$

05AB1E, 4 bytes

€L0ζ

Try it online! or as a nicely formatted test suite

€L   # For each: get the range 1..input
  0ζ # zip, padding with 0s
\$\endgroup\$
3
\$\begingroup\$

Husk, 4 bytes

Returns a list of lists

T0mḣ

Try it online!

Explanation

  m    Map over the input
   ḣ   Range from 1 to n
T0     Transpose, padding with 0s
\$\endgroup\$
3
\$\begingroup\$

Pyth, 6 bytes

.tSMQZ

Try it here! or Verify all the test cases (with pretty-print)!


Explanation

.tSMQZ   - Full program.

  SMQ    - Get the inclusive unary ranges for each.
.t       - Transpose, padding with copies of...
     Z   - ... Zero.
         - Implicit print.

A non-built-in transpose version would be:

mm*hd<dkQeS

This works as follows:

mm*hd<dkQeS   - Full program.

m        eS   - Map over [0, max(input)) with a variable d.
 m      Q     - Map over the input with a variable k.
   hd         - d + 1.
  *           - Multiplied by 1 if...
     <dk      - ... d is smaller than k, else 0.
              - Output implicitly.
\$\endgroup\$
3
\$\begingroup\$

Jelly, 3 bytes

Rz0

Try it online!

Explanation

Rz0  Input: array A
R    Range, vectorizes to each integer
 z0  Transpose and fill with 0
\$\endgroup\$
3
\$\begingroup\$

Actually, 17 bytes

;M╗♂R⌠╜;0@α(+H⌡M┬

Try it online!

Explanation:

;M╗♂R⌠╜;0@α(+H⌡M┬
;M╗                store the maximal element (M) of the input in register 0
   ♂R              range(1, n+1) for each n in input
     ⌠╜;0@α(+H⌡M   for each range:
      ╜;0@α          push a list containing M 0s
           (+        append to range
             H       take first M elements
                ┬  transpose
\$\endgroup\$
1
  • \$\begingroup\$ Yeah, Actually actually needs zip with padding support... \$\endgroup\$ Commented Sep 8, 2017 at 9:43
2
\$\begingroup\$

Pyke, 3 bytes

This uses the new feature of Pyke, hex encodings... The best part is that we tie Jelly! Raw bytes:

4D 53 AC

Try it here!

The ASCII-Pyke equivalent would be 4 bytes:

MS.,

How?

4D 53 AC   - Full program.

4D         - Map.
   53      - Inclusive range.
      AC   - Transpose with zeroes.
           - Output implicitly.

-------------------------------------

MS.,   - Full program.

M      - Map.
 S     - Inclusive range.
  .,   - Transpose with zeroes.
       - Output implicitly.

Here is a pretty-print version with ASCII, and here is one with hex encodings.

\$\endgroup\$
2
\$\begingroup\$

Perl 6, 39 bytes

{zip (1 X..$_).map:{|@_,|(0 xx.max-1)}}

Try it

Expanded:

{                # bare block lambda with implicit parameter 「$_」

  zip

    (1 X.. $_)   # turn each input into a Range that starts with 1

    .map:        # map each of those Ranges using the following code

    {            # bare block lambda with implicit parameter 「@_」 
                 # (「@_」 takes precedence over 「$_」 when it is seen)

      |@_,       # slip the input into a new list

      |(         # slip this into the list

        0        # a 「0」
        xx       # list repeated by

          .max   # the max of 「$_」 (implicit method call)
          - 1    # minus 1 (so that zip doesn't add an extra row)
      )
    }
}

Note that zip terminates once the shortest input list is exhausted.

\$\endgroup\$
2
\$\begingroup\$

C#, 136 bytes


Data

  • Input Int32[] i An array of ints
  • Output Int32[,] A bidimentional array.

Golfed

i=>{int m=System.Linq.Enumerable.Max(i),l=i.Length,x,y;var o=new int[m,l];for(y=0;y<m;y++)for(x=0;x<l;)o[y,x]=i[x++]>y?y+1:0;return o;};

Ungolfed

i => {
    int
        m = System.Linq.Enumerable.Max( i ),
        l = i.Length,
        x, y;
        
    var o = new int[ m, l ];
    
    for( y = 0; y < m; y++ )
        for( x = 0; x < l; )
            o[ y, x ] = i[ x++ ] > y ? y + 1 : 0;
            
    return o;
};

Ungolfed readable

// Take an array of Int32
i => {

    // Store the max value of the array, the length and declare some vars to save some bytes
    int
        m = System.Linq.Enumerable.Max( i ),
        l = i.Length,
        x, y;
        
    // Create the bidimensional array to output
    var o = new int[ m, l ];
    
    // Cycle line by line...
    for( y = 0; y < m; y++ )
    
        // ... and column by column...
        for( x = 0; x < l; )
        
            // And set the value of the line in the array if it's lower than the the value at the index of the input array
            o[ y, x ] = i[ x++ ] > y ? y + 1 : 0;
            
    // Return the bidimentional array.
    return o;
};

Full code

using System;
using System.Collections.Generic;

namespace TestBench {
    public class Program {
        // Methods
        static void Main( string[] args ) {
            Func<Int32[], Int32[,]> f = i => {
                int
                    m = System.Linq.Enumerable.Max( i ),
                    l = i.Length,
                    x, y;
                var o = new int[ m, l ];
                for( y = 0; y < m; y++ )
                    for( x = 0; x < l; )
                        o[ y, x ] = i[ x++ ] > y ? y + 1 : 0;
                return o;
            };

            List<Int32[]>
                testCases = new List<Int32[]>() {
                    new[] { 1, 2, 5, 6, 4 },
                    new[] { 3, 5, 2, 1, 6 },
                    new[] { 1, 2, 3, 4, 3, 2, 1 },
                };

            foreach( Int32[] testCase in testCases ) {
                Console.WriteLine( " INPUT: " );
                PrintArray( testCase );

                Console.WriteLine( "OUTPUT: " );
                PrintMatrix( f( testCase ) );
            }

            Console.ReadLine();
        }

        public static void PrintArray<TSource>( TSource[] array ) {
            PrintArray( array, o => o.ToString() );
        }
        public static void PrintArray<TSource>( TSource[] array, Func<TSource, String> valueFetcher ) {
            List<String>
                output = new List<String>();

            for( Int32 index = 0; index < array.Length; index++ ) {
                output.Add( valueFetcher( array[ index ] ) );
            }

            Console.WriteLine( $"[ {String.Join( ", ", output )} ]" );
        }

        public static void PrintMatrix<TSource>( TSource[,] array ) {
            PrintMatrix( array, o => o.ToString() );
        }
        public static void PrintMatrix<TSource>( TSource[,] array, Func<TSource, String> valueFetcher ) {
            List<String>
                output = new List<String>();

            for( Int32 xIndex = 0; xIndex < array.GetLength( 0 ); xIndex++ ) {
                List<String>
                    inner = new List<String>();

                for( Int32 yIndex = 0; yIndex < array.GetLength( 1 ); yIndex++ ) {
                    inner.Add( valueFetcher( array[ xIndex, yIndex ] ) );
                }

                output.Add( $"[ {String.Join( ", ", inner )} ]" );
            }

            Console.WriteLine( $"[\n   {String.Join( ",\n   ", output )}\n]" );
        }
    }
}

Releases

  • v1.0 - 136 bytes - Initial solution.

Notes

  • None
\$\endgroup\$
2
\$\begingroup\$

Java 10, 115 bytes

a->{int l=a.length,m=0;for(int j:a)m=j>m?j:m;var r=new int[m][l];for(;l-->0;)for(m=0;m<a[l];r[m][l]=++m);return r;}

Explanation:

Try it online.

a->{                  // Method with integer-array parameter and integer-matrix return-type
  int l=a.length,     //  Length of the array
      m=0;            //  Largest integer in the array, 0 for now
  for(int j:a)        //  Loop over the array
    m=j>m?            //   If the current item is larger than `m`:
       j              //    Set `m` to this item as new max
      :               //   Else:
       m;             //    Leave `m` the same
  var r=new int[m][l];//  Result-matrix of size `m` by `l`, filled with zeroes by default
  for(;l-->0;)        //  Loop over the columns
    for(m=0;m<a[l];   //   Inner loop over the rows
      r[m][l]=++m);   //    Set the cell at position `m,l` to `m+1`
  return r;}          //  Return the result-matrix
\$\endgroup\$
2
\$\begingroup\$

Uiua, 8 bytes

+1⍉⬚¯1∵⇡

Try it!

+1⍉⬚¯1∵⇡
      ∵⇡  # range of each
   ⬚¯1    # filling with -1
  ⍉       # transpose
+1        # increment
\$\endgroup\$
2
\$\begingroup\$

Perl 5, 62 57 + 1 (-a) = 58 bytes

$,=$";say map$i*($_-->0),@F while++$i&&(sort{$b-$a}@F)[0]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Nice answer! You can save 1 byte with this too by moving to "@{[...]}" instead of setting $, and (I'm sure you probably don't want to but...) you can replace the sort call with an additional flag -MList::Util+(max) and call max instead. \$\endgroup\$ Commented Nov 24, 2023 at 8:46
  • 1
    \$\begingroup\$ @DomHastings Under the rules of the time, the -M flag would have been added to the byte count, significantly increasing it. \$\endgroup\$
    – Xcali
    Commented Nov 28, 2023 at 22:20
2
\$\begingroup\$

J, 10 bytes

0|:>:@i."0

No surprises

Attempt This Online!

0|:>:@i."0
      i."0   NB. create 0..n-1 range for each atom
   >:@       NB. then increment
0|:          NB. transpose
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 17 bytes

{a*~x</:a:1+!|/x}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Julia, 31 bytes

v->(m=1:max(v...)).*(@.v'÷m>0)

Attempt This Online!

This solution creates a boolean matrix in a different manner than the R1 and Octave2 answers: the vectors v and m are integer-divided. This results in a matrix filled with the integer numbers where v is greater or equal to m and zeroes otherwise. >0 turns it to a boolean matrix and multiplication by vector m gives the desired result.

EDIT Below is the port of the Octave answer (find 10 differences:)):

# Julia, 28 bytes
x->((y=1:max(x...)).<=x').*y

Attempt This Online!

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

C (gcc), 142 bytes

i,j,k;main(c,v)char**v;{for(;++i<c;k=k<*v[i]?*v[i]:k)printf("%c ",*v[i]);for(i=48;puts(""),i++<k;)for(j=1;j<c;)printf("%c ",i<=*v[j++]?i:48);}

Try it online!

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

Proton, 38 bytes

a=>[[i<j?-~i:0for j:a]for i:0..max(a)]

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Let me guess, the bug is the space after it? \$\endgroup\$ Commented Sep 7, 2017 at 20:02
  • \$\begingroup\$ @cairdcoinheringaahing Yes. The question mark will consume the character after it to make sure it's not another question mark but I forgot to compensate for the extra character resulting in it being skipped. \$\endgroup\$
    – hyperneutrino
    Commented Sep 7, 2017 at 20:04
  • \$\begingroup\$ Seems you got a pull, you can now remove the notice :) \$\endgroup\$ Commented Sep 8, 2017 at 9:24
1
\$\begingroup\$

Add++, 37 bytes

D,g,@@*,bL_1+0XA$p$+bUp
L~*,€RAbM€gBc

Try it online!

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

JavaScript (Node.js), 55 bytes

x=>f=(t=1,s,e=x.map(y=>y<t?0:s|=t))=>s?[e,...f(++t)]:[]

Try it online!

JavaScript (Node.js), 63 bytes

x=>[...Array(Math.max(...x,t=0))].map(_=>x.map(y=>y<t?0:t,++t))

Try it online!

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

Japt, 6 bytes

Would be 4 if Japt's transpose padded with 0 instead of null.

mõ zÔÕ

Try it

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

TI-Basic, 48 bytes

Ans→A
List►matr(1 or Ans,[A]
[A]
For(I,2,max(ʟA
List►matr(I(I≤ʟA),[B]
augment(Ans,[B]
End
Ansᵀ

Takes input in Ans. Similar method to this answer.

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

K (ngn/k), 20 bytes

{+(1+!'x),'&'-x-|/x}

Try it online!

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

Scala, 76 bytes

Golfed version. Try it online!

l=>l.flatMap(v=>(1 to l.max).map(i=>if(i<=v)i else 0)).grouped(l.max).toList

Ungolfed version. Try it online!

object Main {
  def f(l: List[Int]): List[List[Int]] = {
    val m = (1 to l.max).toList
    l.flatMap { value =>
      m.map { i =>
        if (i <= value) i else 0
      }
    }.grouped(m.size).toList
  }

  def main(args: Array[String]): Unit = {
    println(f(List(3, 5, 2, 1, 6)))
  }
}
\$\endgroup\$
1
\$\begingroup\$

Nekomata, 8 bytes

ṀR$ᵒ{≤0I

Attempt This Online!

Longer than other answers, because Nekomata doesn't have a padding builtin yet. I'll add one in some future version.

ṀR$ᵒ{≤0I
Ṁ           Maximum
 R          Range from 1 to that
  $         Swap
   ᵒ{       Make a 2D array by the following function
     ≤      If left <= right, return left
      0I    Otherwise, return 0

Nekomata, 8 bytes

R:∑0*ᵚ+Ť

Attempt This Online!

R:∑0*ᵚ+Ť
R           Range from 1 to input
 :          Duplicate
  ∑         Sum
   0*       Multiply by 0
     ᵚ+     Add this to each element of the other array
       Ť    Transpose
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Classic), 5 bytes

⍉∘↑⍳¨

Anonymous tacit function. Did you know that APL's Mix function automatically pads with zeros?

Try it online!

\$\endgroup\$

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.