Lists and arrays, part by part

14

2

In this challenge, you'll get four different but somewhat related tasks that must be solved in a specific manner. First, I'll explain the tasks, then follows an explanation of how you must solve it.

Your code should for all four tasks take two positive integers as input: n,m, where n<m. All tasks must be solved in the same language. The orientation of matrices are optional (n-by-m may be interpreted as "n rows, m columns", or "n columns, m rows").

Task 1:

Create (and output/print) a vector / list consisting of the elements: n, n+1 ... m-1, m. So, for n=4, m=9, you should output: 4,5,6,7,8,9.

Task 2:

Create (and output/print) a matrix / array / list of lists (or equivalent) looking like this:

n,   n+1, ... m-1, m
n+1, n+2, ... m-1, m+1
...
n+m, n+m+1, ... 2*m-1, 2*m

For n=4, m=9 you should output:

4, 5, 6, 7, 8, 9
5, 6, 7, 8, 9, 10
...
13, 14, 15, 16, 17, 18

Task 3:

Create (and output/print) an n-by-m multiplication table (on any suitable format). Example for n=4, m=9:

1   2   3  4
2   4   6  8
3   6   9  12
4   8  12  16
5  10  15  20
6  12  18  24
7  14  21  28
8  16  24  32
9  18  27  36

Task 4:

Output / print a vector / list consisting of the elements in the multiplication table from task 3, sorted in ascending order, keeping duplicate values. For n=4, m=9, you should output: 1, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 6, 7, 8, 8, 8, 9, 9, 10, 12, 12, 12, 14, 15, 16, 16, 18, 18, 20, 21, 24, 24, 27, 28, 32, 36.

The challenge:

Now, all the tasks above are quite trivial. The real challenge here is that the code for task 2 must start with the code for task 1, the code for task 3 must start with the code for task 2 and the code for task 4 must start with the code for task 3.

To make it more clear:

Suppose the code for Task 1 is (works in Octave):

@(n,m)(n:m)

Then your code for Task 2 could be (works in Octave):

@(n,m)(n:m)+(0:m)'

The code for task Task 3 must be (doesn't work in Octave):

@(n,m)(n:m)+(0:m)'"Code_for_task_3"

And finally, the code for Task 4 must be (doesn't work in Octave):

@(n,m)(n:m)+(0:m)'"Code_for_task_3""Code_for_task_4"

This is , so the submission with the shortest code for task 4 in each language wins. As always: Explanations are highly encouraged.

Stewie Griffin

Posted 2017-03-31T17:20:05.933

Reputation: 43 471

Just to be clear, I'm going to guess that this is against the spirit of the challenge, but is it permissible to start the next task's code with a redirect to STDERR >2; so that the previous task's code is essentially rendered a no-op? – AdmBorkBork – 2017-03-31T18:49:24.803

1

@AdmBorkBork, there's no such thing as "the spirit of the challenge" on PPCG :P Yes, that's OK.

– Stewie Griffin – 2017-03-31T18:59:48.797

Does the multiplication table need to be padded nicely? – HyperNeutrino – 2017-03-31T20:31:09.930

1@HyperNeutrino, no. – Stewie Griffin – 2017-03-31T20:31:35.973

When you say "positive integer", do you mean 0<n<m or 0<=n<m? – Value Ink – 2017-04-03T21:05:09.040

0<n<m @valueink – Stewie Griffin – 2017-04-03T21:09:00.667

Answers

6

Jelly, 12 bytes

Task 1

r

Try it online!

Task 2

r+þ0r$}

Try it online!

Task 3

r+þ0r$}
×þ

Try it online!

Task 4

r+þ0r$}
×þFṢ

Try it online!

How it works

Task 1

r is the dyadic range atom and does exactly what the task asks for.

Task 2

A dyadic chain that begins with three dyadic links is a fork; the outmost links get evaluated first, then the middle link is called with the results to both sides as arguments.

  • r behaves as before, yielding [n, …, m].

  • 0r$} is a quicklink (or quickquicklink, if you will).

    The quick $ (monadich chain) consumes the links 0 (yield 0) and r (dyadic range) and turns them into a monadic chain. When called with argument k, this will yield [0, …, k].

    The quick } (right argument) takes the quicklink created by $ and turns it into a dyadic link that calls 0r$ with 0r$}'s right argument.

    0r$} will be called with left argument n and right argument m, so 0r$ is alled with argument m and yields [0, …, m].

  • is another quicklink. þ (table) will call + (addition) for every element in its left argument and any element in its right argument, grouping the results for each right argument into a single row.

    will be called with left argument [n, …, m] and right argument [0, …, m], yielding the desired table.

Task 3

Every line in a Jelly program defines a different link. The last one is the main link and, like C's main function, is the only link that is executed by default. The remaining links can be called from the main link, but we won't do this here.

As before, þ (table) will call × (addition) for every element in its left argument and any element in its right argument, grouping the results for each right argument into a single row.

Since both arguments to ×þ are integers, þ casts them to ranges, transforming the arguments n and m into [1, …, n] and [1, …, m].

Task 4

×þ works as before. The following links are monadic, making them atops, i.e., they are applied on top of the previous ones.

After executing ×þ, F flattens the resulting 2D array, and sorts the resulting 1D array.

Dennis

Posted 2017-03-31T17:20:05.933

Reputation: 196 637

5

05AB1E, 18 17 bytes

Task 1

Ÿ

Try it online

Task 2

Ÿ²FD>})

Try it online

Task 3

Ÿ²FD>})v¹LN*})¦

Try it online

Task 4

Ÿ²FD>})v¹LN*})¦˜{

Try it online

Explanations

Task 1

Ÿ     # range[n ... m]

Task 2

Ÿ        # range[n ... m]
 ²F      # m times do:
   D     # duplicate
    >    # increment
     }   # end loop
      )  # wrap in list

Task 3

v          # for each list in result of Task 2 do
 ¹L        # push range[1 ... n]
   N*      # multiply by index
     }     # end loop
      )    # wrap in list
       ¦   # discard first element

Task 4

˜          # flatten the result from Task 3
 {         # sort

Emigna

Posted 2017-03-31T17:20:05.933

Reputation: 50 798

3

MATL, 18 17 bytes

Task 1

&:

Try it online!

Task 2

&:O2G:h!+

Try it online!

Task 3

&:O2G:h!+:7M!*

Try it online!

Task 4

&:O2G:h!+:7M!*1eS

Try it online!

Explanation

Task 1

&:    % Binary range [n n+1 ... m] from implicit inputs n, m

Task 2

      % ... Stack contains [n n+1 ... m]
O     % Push 0
2G    % Push second input, m
:     % Unary range: gives [1 2 ... m]
h     % Concatenate horizontally: gives [0 1 2 ... m]
!     % Transpose into a column vector
+     % Add with broadcast

Task 3

      % ... Stack contains matrix from task 2
:     % Unary range. For matrix input it uses its (1,1) entry. So this gives [1 2 ... n]
7M    % Push [1 2 ... m] again
!     % Transpose into a column vector
*     % Multiply with broadcast

Task 4

      % ... Stack contains matrix from task 3
1e    % Linearize into a row vector
S     % Sort

Luis Mendo

Posted 2017-03-31T17:20:05.933

Reputation: 87 464

3

Mathematica, 84 77 bytes

Edit: Thanks to Martin Ender for saving 7 bytes.

Task 1:

{n,m}n~Range~m

Pure Function with arguments n and m which outputs n~Range~m, the infix form of Range[n,m].

Task 2:

{n,m}n~Range~m~Table~(m+1)//0~Range~m+#&

n~Range~m~Table~(m+1) creates a 2D array with m+1 rows, where each row is the output of the previous task. Then //0~Range~m+#& is postfix application of the function 0~Range~m+#& which effectively adds 0 to the first row, 1 to the second row, and so on up to m for the m+1-th row.

Task 3:

{n,m}n~Range~m~Table~(m+1)//0~Range~m+#&//1##&~Array~{n,m}&

This just applies the constant function 1##&~Array~{n,m}& to the output of the previous task.

Task 4:

{n,m}n~Range~m~Table~(m+1)//0~Range~m+#&//1##&~Array~{n,m}&//Flatten//Sort

Flattens and Sorts the multiplication table.

ngenisis

Posted 2017-03-31T17:20:05.933

Reputation: 4 600

2

Python, 183 bytes

Task 1, 29 bytes

r=range
a=lambda n,m:r(n,m+1)

Try it online!

Task 2, 84 bytes

r=range
a=lambda n,m:r(n,m+1)
s=lambda n,m:[[w+i for w in r(n,m)] for i in a(0,m+1)]

Try it online!

Task 3, 137 bytes

r=range
a=lambda n,m:r(n,m+1)
s=lambda n,m:[[w+i for w in r(n,m)] for i in a(0,m+1)]
d=lambda n,m:[[w*i for w in a(1,n)] for i in a(1,m)]

Try it online!

Task 4, 183167 bytes

r=range
a=lambda n,m:r(n,m+1)
s=lambda n,m:[[w+i for w in r(n,m)] for i in a(0,m+1)]
d=lambda n,m:[[w*i for w in a(1,n)] for i in a(1,m)]
f=lambda(z):sorted(sum(z,[]))

Try it online!

Explanation:

Task 1:

Simple enough, it generates a n to m list using Python's built-in range function.

Task 2:

For every number 0 to m+1, it adds that number to each item of a list from n to m.

Task 3:

For each number from 1 to m, it multiplies that number by every number in a list from 1 to n.

Task 4:

This uses Python's built in sorted function which sorts a list from least to greatest. The list comprehension in the function is used to flatten the list. It creates a list of every item in every item of the list given to it by task 3.

  • Saved very many bytes thanks to @math_junkie.
  • Saved 16 bytes thanks to @ThisGuy

Saved very many bytes thanks to @math_junkie.

Comrade SparklePony

Posted 2017-03-31T17:20:05.933

Reputation: 5 784

Can you not use anonymous functions or are lambdas not actually shorter? (by my count it seems they are) – cole – 2017-03-31T21:54:31.370

Is this generally acceptable for Python asnwers? The code for task 2, for instance, isn't a full program with input and output, and it's also not a function or function definition. – ngenisis – 2017-03-31T22:07:52.873

@Cole I had to use non-anonymous functions so that I could use them in the later code. – Comrade SparklePony – 2017-03-31T22:16:29.370

@ngenisis I think it is okay, because the OP said the code for task 2 must start with the code for task 1, and the code for task 2, def s(n,m):return [[w+i for w in r(n,m)] for i in a(0,m+1)], is a complete function when the code for task 1 defined. – Comrade SparklePony – 2017-03-31T22:18:57.553

You can do something like a=lambda n,m:... for each of your function definitions. Anonymous function are always shorter in python – math junkie – 2017-04-01T00:35:20.690

It would save a few bytes (17) if you changed the list comprehension in 4 to sum(w,[]) – caird coinheringaahing – 2017-04-03T01:09:27.597

Since 0<n<m is a guarantee, the result from Task 1 is always truthy, meaning that Task 2 can attach itself using an and: r=range;a=lambda n,m:r(n,m+1)and[[w+i for w in r(n,m)] for i in r(0,m+1)] for -9 bytes. Taking it further, Task 3 tacks itself onto the end of that with and[[w*i for w in r(1,n+1)] for i in r(1,m+1)]! Task 4's addition stays about the same, although lambda z: is shorter than lambda(z): – Value Ink – 2017-04-03T21:18:04.097

@ValueInk Wow, I never would have thought of that. Ill make the changes when I get access to s computer. – Comrade SparklePony – 2017-04-03T22:39:27.710

2

PHP 7, 200 bytes

Uses the output buffer to clear previous output.

Task 1

[,$n,$m]=$argv;ob_start();eval($s='echo join(" ",$v?:range($n+$i,$m+$i)),"
";');

Saves the code in $s to reuse it later. The $v variable is for the last task.

Task 2

[,$n,$m]=$argv;ob_start();eval($s='echo join(" ",$v?:range($n+$i,$m+$i)),"
";');for(;++$i<=$m;)eval($s);

Prints the remaining lines.

Task 3

[,$n,$m]=$argv;ob_start();eval($s='echo join(" ",$v?:range($n+$i,$m+$i)),"
";');for(;++$i<=$m;)eval($s);for(($c=ob_clean)();++$j<=$m;print"
")for(;++$$j<=$n;sort($v))echo$v[]=$j*$$j,' ';

Clears the output buffer and prints the multiplication table, saving the numbers to $v.

Task 4

[,$n,$m]=$argv;ob_start();eval($s='echo join(" ",$v?:range($n+$i,$m+$i)),"
";');for(;++$i<=$m;)eval($s);for(($c=ob_clean)();++$j<=$m;print"
")for(;++$$j<=$n;sort($v))echo$v[]=$j*$$j,' ';$c();eval($s);

Clears the output buffer again and prints $v.

user63956

Posted 2017-03-31T17:20:05.933

Reputation: 1 571

1

PowerShell, 126 bytes

Task 1

param($n,$m)$n..$m

Try it online!

Uses the .. built-in range operator. The default behavior for the implied Write-Output inserts a newline between elements, so that's why the output shows as newline separated.


Task 2

param($n,$m)$n..$m>2;0..$m|%{$i=$_;($n..$m|%{$_+$i})-join','}

Try it online!

Dumps the first task to STDERR with >2;, then loops from 0 to $m, each iteration setting helper $i before looping again from $n to $m and incrementing each number by $i. Those are -joined together with commas, else this would be an ambiguous gigantic long one-element-per-line output.


Task 3

param($n,$m)$n..$m>2;0..$m|%{$i=$_;($n..$m|%{$_+$i})-join','}>2;(1..$m|%{$i=$_;(1..$n|%{$_*$i})-join' '})

Try it online!

Same sort of thing >2; to dump the previous to STDERR. Then we simply double-loop from 1 to $m then 1 to $n, setting helper $i along the way, multiply the values, and -join with a space to make it tabular. Note the encapsulating parens -- they'll come into play on the next task -- but here they just ensure that the output is put onto the pipeline (which it already would be, so they're redundant).


Task 4

param($n,$m)$n..$m>2;0..$m|%{$i=$_;($n..$m|%{$_+$i})-join','}>2;(1..$m|%{$i=$_;(1..$n|%{$_*$i})-join' '})-split' '|%{+$_}|sort

Try it online!

Aha! Finally some redundancy. Since the previous task has parens, we can tack on the -split on whitespace without worry, cast each one to an integer |%{+$_}, and then |sort. The output is again newline separated.


I think there are some ways to better leverage the redundancy between tasks -- still golfing it some.

AdmBorkBork

Posted 2017-03-31T17:20:05.933

Reputation: 41 581

1

ES2016-ish, 401 384 chars

Here's a first try. I'm sure it could be condensed a bit, but it's pretty short. Arrow functions FTW! (Love those implicit return statements.) New and improved with template strings!

Task 1

var a=Array,l=console.log,f=(n,m)=>a.from(a(1+m-n),(w,i)=>n+i),z=(n,m)=>l(f(n,m).join`, `)

Call z(n,m) for the log output. (I'm aliasing console.log for later golfing.)

Task 2

Second verse... expands on the first.

var a=Array,l=console.log,f=(n,m)=>a.from(a(1+m-n),(w,i)=>n+i),z=(n,m)=>l(f(n,m).join`, `),p,o,g=(n,m)=>{p=n,o=m;return [...a(m+1).keys()].map((d)=>f(d+p,d+o))},y=(n,m)=>l(g(n,m).join`\n`

Now call y(n,m). Pretty, no?

Task 3

Have to bypass most of the existing functionality <sadface />.

var a=Array,l=console.log,f=(n,m)=>a.from(a(1+m-n),(w,i)=>n+i),z=(n,m)=>l(f(n,m).join`, `),p,o,g=(n,m)=>{p=n,o=m;return [...a(m+1).keys()].map((d)=>f(d+p,d+o))},y=(n,m)=>l(g(n,m).join`\n`,h=(n,m)=>[...a(m).keys()].map((d)=>(d+1)*n).join`\t`,i=(n,m)=>[...a(n).keys()].map((d)=>h((d+1),m)),v=(n,m)=>i(n,m).join`\n`

Now the method name is v. Call it the same way.

Task 4

And now we can reuse again.

var a=Array,l=console.log,f=(n,m)=>a.from(a(1+m-n),(w,i)=>n+i),z=(n,m)=>l(f(n,m).join`, `),p,o,g=(n,m)=>{p=n,o=m;return [...a(m+1).keys()].map((d)=>f(d+p,d+o))},y=(n,m)=>l(g(n,m).join`\n`,h=(n,m)=>[...a(m).keys()].map((d)=>(d+1)*n).join`\t`,i=(n,m)=>[...a(n).keys()].map((d)=>h((d+1),m)),v=(n,m)=>i(n,m).join`\n`,t=(n,m)=>l(v(n,m).match(/\d+/g).sort((a,b)=>+a>+b||+(a===b)*2-1).join(`, `)

Had to skip u for my method, so it's t. Bummed that I had to put in that sort function, because the String.match returns values as... strings.

Neil JS Grump

Posted 2017-03-31T17:20:05.933

Reputation: 111

0

Ruby, 121 103 bytes

Everything in Ruby is truthy except for nil and false, which means that the tasks can be set up to ignore previous input with naught but a well-placed and/&&.

Task 1

Try it online!

n,m=$*.map &:to_i
p [*n..m]

Task 2

Try it online!

n,m=$*.map &:to_i
p [*n..m]&&(0..m).map{|i|[*n+i..m+i]}

Task 3

Try it online!

n,m=$*.map &:to_i
p [*n..m]&&(0..m).map{|i|[*n+i..m+i]}&&(1..m).map{|i|(1..n).map{|j|i*j}}

Task 4

Try it online!

n,m=$*.map &:to_i
p [*n..m]&&(0..m).map{|i|[*n+i..m+i]}&&(1..m).map{|i|(1..n).map{|j|i*j}}.flatten.sort

Value Ink

Posted 2017-03-31T17:20:05.933

Reputation: 10 608