Illustrate the square of a binomial

28

Given (by any means) two different natural numbers (of any reasonable size), output (by any means) the square of their sum as in the examples below:

Given 4 and 3, output:

12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

Given 1 and 3, output:

3 9 9 9
3 9 9 9
3 9 9 9
1 3 3 3

Whitespace may vary within reason but the columns must be left-aligned, right-aligned, or (pseudo-)centered.

A trailing newline is fine, but standard loopholes are not.

This is so include a header like # LanguageName, 123 in your answer, where the number is chars (bytes for languages that are not text-based). Packing code to large Unicode chars is not allowed.


Bonus: -3 if your code outputs just one square when one of the numbers is 0; e.g. given 0 and 3, output:

9 9 9
9 9 9
9 9 9

Adám

Posted 2015-10-19T20:50:18.037

Reputation: 37 779

what is the maximum value of the input numbers? thanks. – don bright – 2015-10-19T21:17:25.870

1@donbright No artificial limit. Only limit is what your computer and language can handle when it comes to representation, computation (with your chosen algorithm) and result. Potentially, a modern computer equipped with a printer that accepts data line by line, would have almost no limit... :-) – Adám – 2015-10-19T21:22:47.367

Is the square orientation a given, or can we rotate it 90 degrees? – John Dvorak – 2015-10-20T05:34:24.633

1Why the bonus for 0 values though? What would the expected output be if not just one square? – March Ho – 2015-10-20T09:15:16.690

@MarchHo That's why the bonus is so small. Still, some languages may not be able to handle empty arrays. – Adám – 2015-10-20T11:55:14.067

@JanDvorak The orientation must be as shown: First input's square in lower left corner, second input's in upper right. – Adám – 2015-10-20T12:01:02.190

Answers

14

J, 9 bytes - 3 = 6

#~@|.*/#~

Inspired by @NBZ's APL answer, golfed down by @randomra. This defines a verb that takes in an array of numbers. It's used as follows:

   (#~@|.*/#~) 4 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

I also claim the 3-byte bonus, since an input of 0 produces sub-matrices of size zero:

   (#~@|.*/#~) 4 0
16 16 16 16
16 16 16 16
16 16 16 16
16 16 16 16
   (#~@|.*/#~) 0 3
9 9 9
9 9 9
9 9 9

Explanation

J has a definite edge in this challenge. In addition to eating array manipulation problems for breakfast, it prints 2D matrices in the correct format by default.

       #~  Replicate each number n in input n times
#~@|.      The same for reversed input
     */    Compute their multiplication table

Zgarb

Posted 2015-10-19T20:50:18.037

Reputation: 39 083

This makes me feel right at home. – Adám – 2015-10-20T12:00:06.620

3This solution looks like an obscure variation of the table flipper ASCII emoticon (╯°□°)╯︵ ┻━┻ – Pete TNT – 2015-10-20T17:43:55.053

10

Octave, 45 bytes - 3 = 42

s=@(m,n)[a=ones(n,1)*n;b=ones(m,1)*m].*[b;a]'

Explanation

This constructs two vectors (let's assume m = 4 and n = 3):

ones(n, 1) constructs an array of ones of size n x 1, so multiplying the ones by n we get:

ones(n, 1) * n => [3 3 3]' (where ' is transpose... n x 1 is a column vector)

a = [3 3 3  4 4 4 4]'   %// a is a column vector
b = [4 4 4 4  3 3 3]    %// b is a row vector

Then the vectors are multiplied in an element-wise fashion, with automatic broadcast expansion so that the 7-element vectors produce a 7x7-element matrix:

    [3] .* [4 4 4 4 3 3 3]
    [3]
    [3]
    [4]
    [4]
    [4]
    [4]

For example, multiplication of the first row of a by b gives:

    [3] .* [4 4 4 4 3 3 3] = [12 12 12 12  9  9  9]

And similarly for the remaining rows of a.

Output:

>> s(4,3)
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

>> s(3,0)
ans =

   9   9   9
   9   9   9
   9   9   9

You can try it here on ideone

beaker

Posted 2015-10-19T20:50:18.037

Reputation: 2 349

You can remove the s=. We have the convention that anonymous functions/lambdas do not have to be stored in a variable. – flawr – 2015-10-19T22:08:45.310

6@flawr but then the answer wouldn't be 42... – beaker – 2015-10-19T22:11:24.657

OK.​​​​​​​​​​​​ – Adám – 2015-10-20T11:51:56.290

9

Dyalog APL, 10-3 = 7

Inspired* by this answer where the arguments are replicated and then used in a multiplication table:

⊖∘.×⍨(/⍨⎕)

Issues a prompt (⎕:) and evaluates any expression entered then. (For security reasons, this doesn't work on TryAPL but it does work on NGN/APL.)
/⍨ Replicates its argument itself times (/⍨4 3 ​⇔ 3 3 3 4 4 4 4)
∘.×⍨ Creates a multiplication table.
Flips upside down.

This happens to work on any length input (input is indented 6 spaces, output is at left margin):

      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍬      ⍝ Empty list (the square of nothing)
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0      ⍝ 0​² = 0
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0 1      ⍝ (0+1)​² = 1²
1
      ⊖∘.×⍨(/⍨⎕)
⎕:
      2 3      ⍝ (2+3)​² = 2² + 3²
6 6 9 9 9
6 6 9 9 9
6 6 9 9 9
4 4 6 6 6
4 4 6 6 6
      ⊖∘.×⍨(/⍨⎕)
⎕:
      1 2 3      ⍝ (1+2+3)​² = 1² + 2(1×2) + 2(1×3) + 2² + 2(2×3) + 3²
3 6 6 9 9 9
3 6 6 9 9 9
3 6 6 9 9 9
2 4 4 6 6 6
2 4 4 6 6 6
1 2 2 3 3 3
      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍳4    ⍝ Integers 1 through 4
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
2 4 4  6  6  6  8  8  8  8
2 4 4  6  6  6  8  8  8  8
1 2 2  3  3  3  4  4  4  4

*Originally, I had a different solution in mind: Each rectangle is created separately by creating a multiplication table for each combination of the two arguments. Then the four squares are mended together vertically and horizontally. It looks like this:

,/⍪⌿⊖∘.(,⍴×)⍨⎕

Prompt, as above.
,⍴×< Combine (,) the args and use that to shape () a rectangle filled with their product (×).
∘.(​…)⍨ Create a table where each cell is whatever is specified in (​…)
Flip vertically.
⍪⌿ Combine cells vertically.
,/ Combine cells horizontally.

Adám

Posted 2015-10-19T20:50:18.037

Reputation: 37 779

1Nice! Same idea in J with equal score: (|.*/])@#~ – Zgarb – 2015-10-20T15:10:51.680

@Zgarb Update your answer and put a footnote like mine. J deserves it! – Adám – 2015-10-20T16:01:59.910

7

R, 31 - 3 = 28

rev(b<-rep(a<-scan(),a))%*%t(b)

Explanation:

           a<-scan()            # take numeric input and store as vector a
    b<-rep(         ,a)         # repeat each numeric input by itself and store as vector b
rev(                   )        # the reverse of vector b
                        %*%     # matrix multiplication
                           t(b) # the transposed of vector b

This also works for more than two numbers. For example, the output for (5,3,2) looks like this:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10   10   10   10   10    6    6    6    4     4
 [2,]   10   10   10   10   10    6    6    6    4     4
 [3,]   15   15   15   15   15    9    9    9    6     6
 [4,]   15   15   15   15   15    9    9    9    6     6
 [5,]   15   15   15   15   15    9    9    9    6     6
 [6,]   25   25   25   25   25   15   15   15   10    10
 [7,]   25   25   25   25   25   15   15   15   10    10
 [8,]   25   25   25   25   25   15   15   15   10    10
 [9,]   25   25   25   25   25   15   15   15   10    10
[10,]   25   25   25   25   25   15   15   15   10    10

freekvd

Posted 2015-10-19T20:50:18.037

Reputation: 909

You will probably need to wrap it up into cat or write in order for it to be a valid answer. – David Arenburg – 2015-10-20T14:48:33.000

@DavidArenburg I don't see why? It says "Output (by any means)". It took me only one mean to output so that puts me within requirements. – freekvd – 2015-10-20T14:50:06.357

Yeah maybe you are right. Not sure what they mean by that. – David Arenburg – 2015-10-20T14:51:14.583

@DavidArenburg Yeah, it's fine. This is a data/text challenge, not an input/output challenge. – Adám – 2015-10-20T17:44:35.197

5

Haskell, 153 125 bytes - 3 = 122

(#)=replicate
d=length.show
y%x=unlines$(>>= \n->(1+d(x*x+y*y)-d n)#' '++show n)<$>x#(y#(x*y)++x#(x*x))++y#(y#(y*y)++x#(x*y))

Half of the code is for output formatting. It works for arbitrary large integers. Example output:

> putStrLn $ 4 % 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

> putStrLn $ 6 % 0
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36

Sometimes there's an additional whitespace between the numbers, because I'm calculating the space needed based on x*x+y*y instead of max (x*x) (y*y), e.g.

> putStrLn $ 2 % 3
  6  6  9  9  9
  6  6  9  9  9
  6  6  9  9  9
  4  4  6  6  6
  4  4  6  6  6

But it's at most one whitespace.

nimi

Posted 2015-10-19T20:50:18.037

Reputation: 34 639

4

CJam, 27 bytes - 3 = 24

q:L~_]ze~_ff{*sL,2*Se[}W%N*

Takes input as a CJam style array. It uses a bit more spacing than necessary, but I think it's "within reason", and it's always properly right aligned.

Test it here.

Explanation

q:L    e# Read the input and store it in L.
~_     e# Evaluate the input, pushing [A B] onto the stack and duplicate it.
]z     e# Wrap both in an array and transpose it to get [[A A] [B B]].
e~     e# Run-length decode, getting A copies of A and B copies of B.
_ff{   e# Double map over each pair of entries in this new array...
  *s   e#   Multiply the two values.
  L,2* e#   Push twice the length of the input string.
  Se[  e#   Pad the result to this width with spaces (from the left).
}
W%     e# Reverse the resulting matrix to get the correct orientation.
N*     e# Join the rows with linefeed characters.

Martin Ender

Posted 2015-10-19T20:50:18.037

Reputation: 184 808

Nice, but what causes that much white-space, and what would be needed to reduce it? – Adám – 2015-10-19T21:06:18.913

1@NBZ The shortest way I've found so far to compute a reliable upper bound on the cell width is to use twice the length of the input string (because the larger number squared won't have more than twice as many digits as the number itself). Of course I could compute the actual amount necessary based on the resulting numbers, but that would be a fair bit longer. – Martin Ender – 2015-10-19T21:07:56.410

4

Mathematica 56-3 = 53

Update: I added a second method, of precisely the same code size, that uses a named function. It employs an Array rather than a Table but follows the same logic. (See below.)

Method 1

This makes a table of products, the factors of which depend on the row, column values. The pair of numbers is entered as a list of integers. Anonymous functions such as the following, are most useful if they are used only once in a program. Otherwise it makes more sense to use a named function.

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&

Each factor is an If-then statement:

  • If[r>#2,#,#2] means, "If the row number is greater than the second input, use the first input as the factor, otherwise use the second input.
  • If[c>#,#2,#] means, "If the column number is greater than the first input, use the second input as the factor, otherwise use the first input.

Example 1

 Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{5,3}

ex1


Example 2

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{0,3}

ex2


Method 2 (Also 56-3 = 53)

This works similarly to Method 1. But it requires less code when called. And the cells are addressable, unlike cells in a table. This method is better to use if the function will be used more than once.

a_~f~b_:=Grid@Array[If[#>a,a,b]If[#2>a,b,a]&,{a+b,a+b}]

The examples from above are produced by the following:

Ex 1:

f[4,3]

Ex 2:

f[0,3]

DavidC

Posted 2015-10-19T20:50:18.037

Reputation: 24 524

1That is ingenious. With that method I can reduce my own solution by 4 characters. – Adám – 2015-10-19T22:25:46.130

Thanks. I just realised that the same approach works with a named function. See Method 2 above. – DavidC – 2015-10-20T00:10:31.470

4

C function (using glibc), 122 bytes - 3 = 119

Mostly straightforward implementation with 2 loops. I expect there are some golfing opportunities I have missed here:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

Inputs are passed in the first two parameters of the function, the other two are dummies. Columns are right-aligned.

Note glibc puts() always seems to return the number of bytes written including implicit trailing newline, which is what we need here. No guarantees this will work with any other libc.

In a full program:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

int main (int argc, char **argv) {
    if (argc == 3) {
        f(atoi(argv[1]),atoi(argv[2]));
    }
}

Compile as gcc sqrbin.c -o sqrbin (or make sqrbin). Warnings may safely be ignored.

Example output:

$ ./sqrbin 4 3
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
$ ./sqrbin 4 0
 16 16 16 16
 16 16 16 16
 16 16 16 16
 16 16 16 16
$ 

Digital Trauma

Posted 2015-10-19T20:50:18.037

Reputation: 64 644

Based on my experience, the return value of puts() is machine dependent. It's 10 on mine for instance. Also, here's a tip: you can usually compress two loops into one if you conditionally increment the counter in the external loop. My solution demonstrates how it can be done. – xsot – 2015-10-20T12:28:43.263

@xsot Yes, puts() return code is only guaranteed to be +ve for success. However my testing with glibc seems show that the return value is number of bytes written. As for the loop consolidation - yes, I'm aware of that technique and have tried that here, so far with no shortening in this case. – Digital Trauma – 2015-10-20T17:11:29.760

4

Octave, 34 - 3 = 31

@(a)rot90(b=repelems(a,[1,2;a]))*b

Examples:

octave:1> f = @(a)rot90(b=repelems(a,[1,2;a]))*b;
octave:2> f([4,3])
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

octave:3> f([0,3])
ans =

   9   9   9
   9   9   9
   9   9   9

alephalpha

Posted 2015-10-19T20:50:18.037

Reputation: 23 988

Wow, I had no idea repelems existed. Awesome! – beaker – 2015-10-20T15:07:16.927

2

Python 2, 176 bytes - 3 = 173

def g(m,n):
 y,x,z,l,f='y','x','z','l','%'+str(len(str(max(m*m,n*n))))+'s'
 d={y:m*n,x:n*n,z:m*m,l:'\n'}
 for i in map(lambda x:d[x],(y*m+x*n+l)*n+(z*m+y*n+l)*m): print f % i,

This uses Python string functions to create a character grid, then replaces the characters with integers and prints formatted output.

don bright

Posted 2015-10-19T20:50:18.037

Reputation: 1 189

Interesting method. – Adám – 2015-10-20T11:57:56.440

2

Ruby, (133 - 3) = 130 bytes

s=1
a=ARGV.map{|e|s*=(e=e.to_i);[e]*e}.flatten
s=s.to_s.size
a.reverse.each{|i|a.each{|j|print (i*j).to_s.rjust(s).ljust(s+3)};puts}

for 4,3

12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12

for 1,3

3   9   9   9   
3   9   9   9   
3   9   9   9   
1   3   3   3

for 0,3

9   9   9   
9   9   9   
9   9   9

Golgappa

Posted 2015-10-19T20:50:18.037

Reputation: 21

2Welcome to PPCG! I don't think your padding is sufficient for large numbers. Consider having a 1 and a large number like 9999. Than s will come out as 4, so you're padding to a width of s+3 = 7 but 9999^2 needs 8 digits. You might want to use 2*s instead. – Martin Ender – 2015-10-20T09:53:44.477

2

Regardless, here are some golfing tips: I don't see why you need the rjust before doing ljust. You can shorten print to $><< (and get rid of the space after it). ARGV has an alias $*. You might be able to avoid the flatten by building your array with something like this: http://codegolf.stackexchange.com/a/19493/8478. Also, function-only answers are definitely allowed around here (even unnamed functions), so that function could take the integers as inputs, and you wouldn't have to do any .to_i.

– Martin Ender – 2015-10-20T09:57:10.623

@MartinBüttner, thank you for the tips. – Harsh Gupta – 2015-10-20T11:32:29.013

1

Blocks, 51 bytes 52 62 82 87 (non-competing)

::`+`1|U;{`*`1}|A;`+`1,0+`1={`1^2}|;0+`,`1+`={`^2}|

Ungolfed:

::
  ` + `1                    | Expand;
  {` * `1}                  | SetAll;
  ` + `1, 0 + `1 = {`1 ^ 2} | Set;
  0 + `, `1 + `  = {` ^ 2}  | Set

Try it

Downgoat

Posted 2015-10-19T20:50:18.037

Reputation: 27 116

1

C, (125 - 3) bytes

i,j,a;main(b,s){for(sscanf(gets(s),"%d %d",&a,&b);j<a+b;)printf(++i>a+b?i=!++j,"\n":"%*d",strlen(s)*2,(i<a?a:b)*(j<b?b:a));}

Input is taken as two space-separated integers on the same line. Each cell is padded with spaces to twice length of the input string.

xsot

Posted 2015-10-19T20:50:18.037

Reputation: 5 069

im having trouble getting this to compile with gcc (4.8.4)... – don bright – 2015-10-20T15:11:01.670

1

I tested this on http://golf.shinh.org/check.rb which uses the debian package gcc-4.6.1-2. What compile errors are you getting?

– xsot – 2015-10-20T22:53:24.420

sorry i tried again as all one line and it worked,... but when i run i get a segfault. i entered the string 2 3 and hit return and it says Segmentation fault (core dumped) – don bright – 2015-10-21T01:46:45.167

Sorry but I don't know why it won't work for you. At least you can still try out the code at the site I linked earlier :) – xsot – 2015-10-21T02:18:58.567

1

Matlab, 58 − 3 = 55

Using an anonymous function:

@(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)

Example:

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(4,3)
ans =
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(0,3)
ans =
     9     9     9
     9     9     9
     9     9     9

(Old solution) 59 − 3 = 56

Using an anonymous function:

@(a,b)[b*a*ones(b,a) b^2*ones(b);a^2*ones(a) a*b*ones(a,b)]

Luis Mendo

Posted 2015-10-19T20:50:18.037

Reputation: 87 464

1

Pyth, 39 − 3 = 36

Pyth doesn't have built-in matrix formatting, which greatly increases the size, as one has to manually pad the output numbers. Here's what I came up with.

JAQL*b]jdm.[`d\ l`eS^R2Jsm*d]*bdJj+yHyG

Try it online.

PurkkaKoodari

Posted 2015-10-19T20:50:18.037

Reputation: 16 699