18
\$\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\$
  • \$\begingroup\$ May we distribute the ranges horizontally instead? \$\endgroup\$ – Mr. Xcoder Sep 7 '17 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\$ – Stewie Griffin Sep 7 '17 at 19:11
  • 1
    \$\begingroup\$ @StewieGriffin What sane language doesn't associate dimensions with nested lists? \$\endgroup\$ – Erik the Outgolfer Sep 8 '17 at 9:22
  • 4
    \$\begingroup\$ @EriktheOutgolfer, How many insane languages are used on this site? \$\endgroup\$ – Stewie Griffin Sep 8 '17 at 9:31
  • 2
    \$\begingroup\$ @EriktheOutgolfer R for one doesn't see matrices as nested list, but rather one long list, which wraps around row-wise. \$\endgroup\$ – JAD Sep 8 '17 at 11:35

19 Answers 19

18
\$\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\$
  • \$\begingroup\$ I think - you can save 2 bytes, by replacing function(l) with l=scan(); \$\endgroup\$ – AndriusZ Sep 8 '17 at 7:34
  • \$\begingroup\$ @AndriusZ but then I'd have to wrap everything in a print so I would lose those bytes. \$\endgroup\$ – Giuseppe Sep 8 '17 at 12:02
  • \$\begingroup\$ I think, you don't need to wrap everything - TOI \$\endgroup\$ – AndriusZ Sep 8 '17 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 Sep 8 '17 at 12:20
  • \$\begingroup\$ Late to the game: save two bytes using [this tip] (codegolf.stackexchange.com/a/111578/80010) \$\endgroup\$ – JayCe May 2 '18 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\$
5
\$\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\$
  • \$\begingroup\$ @downvoters why the downvotes? Could y'all explain? \$\endgroup\$ – JungHwan Min Sep 7 '17 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 Apr 12 '18 at 17:50
5
\$\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
    \$\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\$ – Stewie Griffin Sep 8 '17 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\$
  • \$\begingroup\$ Yeah, Actually actually needs zip with padding support... \$\endgroup\$ – Erik the Outgolfer Sep 8 '17 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\$
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
\$\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\$
0
\$\begingroup\$

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

$,=$";map$m=$_>$m?$_:$m,@F;say map$_&&$_--&&$i,@F while$i++-$m

Try it online!

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

Proton, 38 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Let me guess, the bug is the space after it? \$\endgroup\$ – caird coinheringaahing Sep 7 '17 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 Sep 7 '17 at 20:04
  • \$\begingroup\$ Seems you got a pull, you can now remove the notice :) \$\endgroup\$ – Erik the Outgolfer Sep 8 '17 at 9:24
0
\$\begingroup\$

Add++, 37 bytes

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

Try it online!

\$\endgroup\$
0
\$\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\$

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.