Matrix with 1 to L(n), in all n columns

18

1

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

Stewie Griffin

Posted 2017-09-07T18:58:31.340

Reputation: 43 471

May we distribute the ranges horizontally instead? – Mr. Xcoder – 2017-09-07T19:03:53.513

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) – Stewie Griffin – 2017-09-07T19:11:53.293

1@StewieGriffin What sane language doesn't associate dimensions with nested lists? – Erik the Outgolfer – 2017-09-08T09:22:41.470

4@EriktheOutgolfer, How many insane languages are used on this site? – Stewie Griffin – 2017-09-08T09:31:26.863

@StewieGriffin It depends on how you define insane, but if your language doesn't have any concept of dimensionality at all, I'm not sure how sane it is. – Erik the Outgolfer – 2017-09-08T09:41:40.750

2@EriktheOutgolfer R for one doesn't see matrices as nested list, but rather one long list, which wraps around row-wise. – JAD – 2017-09-08T11:35:00.900

Answers

18

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.

Giuseppe

Posted 2017-09-07T18:58:31.340

Reputation: 21 077

I think - you can save 2 bytes, by replacing function(l) with l=scan(); – AndriusZ – 2017-09-08T07:34:09.087

@AndriusZ but then I'd have to wrap everything in a print so I would lose those bytes. – Giuseppe – 2017-09-08T12:02:13.737

I think, you don't need to wrap everything - TOI

– AndriusZ – 2017-09-08T12:13:18.987

2

@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.

– Giuseppe – 2017-09-08T12:20:33.637

Late to the game: save two bytes using [this tip] (https://codegolf.stackexchange.com/a/111578/80010)

– JayCe – 2018-05-02T01:36:05.320

@JayCe yeah, that would make this an R + pryr answer rather than a pure R answer, which technically counts as a separate language. – Giuseppe – 2018-05-02T16:59:30.623

@Giuseppe Didn't know that - I've seen this used in so many answers. Thanks for clarifying! – JayCe – 2018-05-02T17:39:45.063

7

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

Luis Mendo

Posted 2017-09-07T18:58:31.340

Reputation: 87 464

6

Python 3, 54 bytes

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

Try it online!

Halvard Hummel

Posted 2017-09-07T18:58:31.340

Reputation: 3 131

5

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 *)

JungHwan Min

Posted 2017-09-07T18:58:31.340

Reputation: 13 290

@downvoters why the downvotes? Could y'all explain? – JungHwan Min – 2017-09-07T22:57:45.530

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! – sergiol – 2018-04-12T17:50:30.873

5

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]

Luis Mendo

Posted 2017-09-07T18:58:31.340

Reputation: 87 464

1I 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 :) – Stewie Griffin – 2017-09-08T04:54:35.413

4

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

Riley

Posted 2017-09-07T18:58:31.340

Reputation: 11 345

3

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

H.PWiz

Posted 2017-09-07T18:58:31.340

Reputation: 10 962

3

Jelly, 3 bytes

Rz0

Try it online!

Explanation

Rz0  Input: array A
R    Range, vectorizes to each integer
 z0  Transpose and fill with 0

miles

Posted 2017-09-07T18:58:31.340

Reputation: 15 654

3

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.

Mr. Xcoder

Posted 2017-09-07T18:58:31.340

Reputation: 39 774

3

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

Mego

Posted 2017-09-07T18:58:31.340

Reputation: 32 998

Yeah, Actually actually needs zip with padding support... – Erik the Outgolfer – 2017-09-08T09:43:26.493

2

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.

Mr. Xcoder

Posted 2017-09-07T18:58:31.340

Reputation: 39 774

2

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.

Brad Gilbert b2gills

Posted 2017-09-07T18:58:31.340

Reputation: 12 713

2

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

auhmaan

Posted 2017-09-07T18:58:31.340

Reputation: 906

1

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!

cleblanc

Posted 2017-09-07T18:58:31.340

Reputation: 3 360

1

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

Kevin Cruijssen

Posted 2017-09-07T18:58:31.340

Reputation: 67 575

0

Proton, 38 bytes

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

Try it online!

HyperNeutrino

Posted 2017-09-07T18:58:31.340

Reputation: 26 575

Let me guess, the bug is the space after it? – caird coinheringaahing – 2017-09-07T20:02:16.413

@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. – HyperNeutrino – 2017-09-07T20:04:33.547

Seems you got a pull, you can now remove the notice :) – Erik the Outgolfer – 2017-09-08T09:24:46.170

0

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

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

Try it online!

Xcali

Posted 2017-09-07T18:58:31.340

Reputation: 7 671

0

Add++, 37 bytes

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

Try it online!

caird coinheringaahing

Posted 2017-09-07T18:58:31.340

Reputation: 13 702

0

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!

l4m2

Posted 2017-09-07T18:58:31.340

Reputation: 5 985