Rebuild a rectangular array from a corner

30

2

I once had a beautiful rectangular array. It was very symmetrical, but unfortunately it has fallen apart and now I only have the top left corner. Your task will be to rebuild the original array.

Your program will receive a 2 dimensional array of integers. For ease of parsing, you may assume they are all between 1 and 9. Your task is to reverse the array's columns, its rows, and both, stitch together the resulting corners, and return the resulting array.

You can assume the array dimensions will be at least 1x1.

Test cases:

Input:
1 2 3
4 5 6

Output:
1 2 3 3 2 1
4 5 6 6 5 4
4 5 6 6 5 4
1 2 3 3 2 1

Input:
1

Output:
1 1
1 1

Input:
9
9
9

Output:
9 9
9 9
9 9
9 9
9 9
9 9

This is , fewest bytes wins!

Pavel

Posted 2018-03-05T16:00:22.230

Reputation: 8 585

1I'll bet charcoal can do this in under 10 – FantaC – 2018-03-05T16:19:00.723

1

@tbfninja https://chat.stackexchange.com/transcript/message/43184083#43184083 but could maybe be shorter with a different input format.

– Pavel – 2018-03-05T16:20:21.730

@MagicOctopusUrn yes – Pavel – 2018-03-05T16:39:51.413

2@tfbninja WS⟦ι⟧‖M→↓ perhaps? 5 bytes to read the input and 4 to reflect it. – Neil – 2018-03-05T17:51:55.563

@Neil nice <filler> – FantaC – 2018-03-05T17:55:35.170

@Neil yeah, except that I don't see an answer yet :P also is that valid? – Erik the Outgolfer – 2018-03-05T18:34:25.697

4I'm 99% sure that there is a lang that do this with (or some similar character) just can't remember which one :c – Rod – 2018-03-05T19:36:56.913

@Rod Close enough?

– totallyhuman – 2018-03-05T20:20:50.897

@Rod called it :P. – Magic Octopus Urn – 2018-03-05T21:32:06.240

Answers

1

Proton, 29 bytes

a=>[b+b[by-1]for b:a+a[by-1]]

Try it online!

There are a few other interesting approaches though:

Proton, 29 bytes

a=>map(g,(g=x=>x+x[by-1])(a))

Try it online!

You can define the mirror sub-function g in-line, because Proton. It's not shorter though.

Proton, 36 bytes

(a=>[x[0]for x:zip(*(a+a[by-1]))])*2

Try it online!

This should be (a=>zip(*(a+a[by-1])))*2 which is 24 bytes, but the zip function is completely broken. Basically, you mirror it and zip, and then do that twice (you can multiply a function by a positive integer to apply the function multiple times).

HyperNeutrino

Posted 2018-03-05T16:00:22.230

Reputation: 26 575

19

Canvas, 1 byte

Try it here!

Outputs as a multiline string

dzaima

Posted 2018-03-05T16:00:22.230

Reputation: 19 048

2Nice, @Rod called that one hah! Is this your language too Dzaima? – Magic Octopus Urn – 2018-03-05T20:49:02.883

Damn... I should've remembered... – totallyhuman – 2018-03-05T20:53:16.413

@MagicOctopusUrn Yeah, IIRC it's meant to basically be S.O.G.L. II: Electric Boogaloo? – ASCII-only – 2018-03-06T10:50:47.037

12

Haskell, 25 24 bytes

r=(++)<*>reverse
r.map r

Try it online!

nimi

Posted 2018-03-05T16:00:22.230

Reputation: 34 639

5

Python 3, 38 bytes

lambda a:[b+b[::-1]for b in a+a[::-1]]

Try it online!

Takes a list of lists and returns a list of lists.

Explanation:

lambda a:                              # anonymous lambda function
                   for b in a+a[::-1]  # for each row in the array and the upside-down array
          b+b[::-1]                    # the row with its reverse appended
         [                           ] # return in a list

pizzapants184

Posted 2018-03-05T16:00:22.230

Reputation: 3 174

5

Husk,  7  6 bytes

Coincidentally, Erik had posted the exact same code in the Husk chatroom about a minute before I posted this.

‼oTS+↔

Try it online!

Pervious version, 7 bytes:

mS+↔S+↔

Mr. Xcoder

Posted 2018-03-05T16:00:22.230

Reputation: 39 774

5

05AB1E, 2 bytes

∞∊

Try it online!


   # Input:Array of String | ['12','34']
---#-----------------------+------------------------------------------
∞  # Mirror horizontally.  | [12,34]       -> [1221,3443]
 ∊ # Mirror vertically.    | [1221,3443]   -> [1221\n3443\n3443\n1221]

Credit for Mr. Xcoder pointing out that arrays of string may count as 2D arrays and Pavel for confirming it.

Magic Octopus Urn

Posted 2018-03-05T16:00:22.230

Reputation: 19 422

... 2 bytes – Mr. Xcoder – 2018-03-05T16:35:29.183

For ease of parsing, you may assume they are all between 1 and 9 – So I think this is valid. Awaiting Pavel's confirmation, I guess – Mr. Xcoder – 2018-03-05T16:37:03.270

@Mr.Xcoder that was what I had initially, then the TIO 2D arrays as input was weird... so had to come up with that header stuff. – Magic Octopus Urn – 2018-03-05T16:38:08.267

A string is an array of characters, so a list of strings is still a 2d array. @Mr.Xcoder's solution is valid. – Pavel – 2018-03-05T16:38:33.773

Coolio, works for me. – Magic Octopus Urn – 2018-03-05T16:41:28.307

5

Retina, 13 bytes

\%`$
$^$`
Vs`

Try it online!

Explanation

\%`$
$^$`

On each line (%), match the end of the line ($), and insert the reverse ($^) of the entire line ($`) and print the result with a trailing linefeed (\). This does the reflection along the vertical axis and prints the first half of the output.

Vs`

This just reverses the entire string, which is equivalent to a 180° degree rotation, or in our case (due to the horizontal symmetry) a reflection along the horizontal axis. This way this works is that V's (reverse) default regex is (?m:^.*$), which normally matches each line of the string. However, we activate the singleline option s, which makes . match linefeeds as well and therefore this default regex actually matches the entire string.

The result of this is printed automatically at the end of the program, giving us the second half of the output.

Martin Ender

Posted 2018-03-05T16:00:22.230

Reputation: 184 808

This doesn't look like any regex flavor I know of :P – Pavel – 2018-03-05T16:36:21.993

@Pavel Because Retina isn't just regex. :) – Erik the Outgolfer – 2018-03-05T16:36:49.880

@Pavel the only part of that code that is an actual regex is the $ on the first line. ;) I'll add an explanation later. – Martin Ender – 2018-03-05T17:01:18.440

3

Jelly, 5 bytes

m€0m0

Try it online!

Erik the Outgolfer

Posted 2018-03-05T16:00:22.230

Reputation: 38 134

Also 5 bytes: m0Z$⁺ (by Hyper Neutrino). – Pavel – 2018-03-05T16:05:11.927

3

MATL, 5 bytes

,tPv!

Try it online!

Explanation:

(implicit input)
,               # do twice:
 t              # dup top of stack
 P              # flip vertically
 v              # vertically concatenate
 !              # transpose
(implicit output)

Giuseppe

Posted 2018-03-05T16:00:22.230

Reputation: 21 077

3

Octave,  33  29 bytes

Thanks to @Giuseppe for golfing four bytes!

@(A)[B=[A;flip(A)] fliplr(B)]

Try it online!

Steadybox

Posted 2018-03-05T16:00:22.230

Reputation: 15 798

29 bytes – Giuseppe – 2018-03-05T21:12:54.423

3

JavaScript (Node.js), 62 55 49 46 bytes

A=>(j=x=>[...x,...[...x].reverse()])(A).map(j)

Try it online!

Because Array.prototype.reverse() reverses the array in place, I have to make a shallow copy somewhere first. A=>(j=x=>[...x,...x.reverse()])(A).map(j) does not work.

Shieru Asakoto

Posted 2018-03-05T16:00:22.230

Reputation: 4 445

3

J, 12 bytes

(,|.)@,.|."1

Try it online!

Explanation

         |."1 - reverse each row
       ,.     - and stitch them to the input
 (   )@       - and 
  ,|.         - append the rows in reversed order        

Galen Ivanov

Posted 2018-03-05T16:00:22.230

Reputation: 13 815

3

awk, 88 bytes

{s="";for(i=NF;i>0;i--)s=" "$i s" "$i;a[FNR]=s;print s}END{for(i=NR;i>0;i--)print a[i]}

mmuntag

Posted 2018-03-05T16:00:22.230

Reputation: 76

3Welcome to PPCG! Nice first answer :) – HyperNeutrino – 2018-03-08T15:34:48.310

2

Triangularity, 31 bytes

...)...
..IEM..
.DRs+}.
DRs+...

Try it online!

Explanation

Removing the characters that make up for the padding, here is what the program does:

)IEMDRs+}DRs+ – Full program. Takes a matrix as a 2D list from STDIN.
)             – Push a 0 onto the stack.
 I            – Take the input at that index.
  E           – Evaluate it.
   M    }     – For each row...
    DR        – Duplicate and replace the second copy by its reverse.
      s+      – Swap and append.
         DR   – Duplicate the result and replace the second copy by its reverse.
           s+ – Swap and append.

Mr. Xcoder

Posted 2018-03-05T16:00:22.230

Reputation: 39 774

2

R, 57 bytes

function(m)rbind(N<-cbind(m,m[,ncol(m):1]),N[nrow(N):1,])

Try it online!

Giuseppe

Posted 2018-03-05T16:00:22.230

Reputation: 21 077

2

APL+WIN, 11 bytes

Prompts for a 2d array of integers.

m⍪⊖m←m,⌽m←⎕

Graham

Posted 2018-03-05T16:00:22.230

Reputation: 3 184

2

Stax, 5 bytes

:mm:m

Run and debug it online

:m means mirror, which is input.concat(reverse(input)). m, in this context means output each line after applying...

So, mirror the array of rows, and then mirror each row and output.

recursive

Posted 2018-03-05T16:00:22.230

Reputation: 8 616

2

SNOBOL4 (CSNOBOL4), 119 113 bytes

	T =TABLE()
I	X =X + 1
	I =INPUT	:F(D)
	OUTPUT =T<X> =I REVERSE(I)	:(I)
D	X =X - 1
	OUTPUT =GT(X) T<X>	:S(D)
END	

Try it online!

Takes input as strings on STDIN, without spaces. This only works because the digits are 1-9 and would fail otherwise.

Giuseppe

Posted 2018-03-05T16:00:22.230

Reputation: 21 077

I can see why people don't use this language anymore. This is so weird. – Pavel – 2018-03-05T17:15:18.007

1@Pavel SNOBOL is truly a terrible language to work with. this is a more modern C implementation of it which has additional builtin functions like REVERSE; the original only supported integer arithmetic as well, as far as I can tell. – Giuseppe – 2018-03-05T17:29:24.703

2

Add++, 30 bytes

D,f,@,bU€{r}B]{r}
D,r,@,dbR+

Try it online!

The footer simply transforms the nested array into the format in the question. Defines a function f, which expects a matrix (nested array) as an argument.

caird coinheringaahing

Posted 2018-03-05T16:00:22.230

Reputation: 13 702

2

Japt, 6 bytes

mê1 ê1

Try it here


Explanation

           :Implicit input of 2D array
m          :Map
 ê1        :  Mirror sub array
    ê1     :Mirror main array

Shaggy

Posted 2018-03-05T16:00:22.230

Reputation: 24 623

2

Charcoal, 5 bytes

θ‖C→↓

Try it online!

Thanks to ASCII-only for a better input format.

Erik the Outgolfer

Posted 2018-03-05T16:00:22.230

Reputation: 38 134

I wonder if this input format is valid, since I'm afraid Charcoal can't handle input otherwise. If it isn't, I'll happily delete this answer. – Erik the Outgolfer – 2018-03-05T18:41:02.050

This is valid I/o. – Pavel – 2018-03-05T18:42:52.880

@Pavel I just wondered because you had said that "Your program will receive a 2 dimensional array of integers", while a string is 1-dimensional (and no, the outer [] don't exactly make it 2D). – Erik the Outgolfer – 2018-03-05T18:44:08.473

@ASCII-only Charcoal really needs a better I/O method... – Neil – 2018-03-05T20:09:17.030

@Neil He didn't get pinged here, but I pinged him over TNB. :) – Erik the Outgolfer – 2018-03-05T20:13:05.873

Well, this works? Not sure if it counts as super hacky or not

– ASCII-only – 2018-03-05T21:51:12.780

@ASCII-only That's no improvement at all lol. – Erik the Outgolfer – 2018-03-05T22:02:42.237

@EriktheOutgolfer Well, it's basically the same as standard Python input method – ASCII-only – 2018-03-06T01:59:00.090

@EriktheOutgolfer fixed.

– ASCII-only – 2018-03-06T23:04:02.070

2

Mathematica, 29 bytes

(g=#~Join~Reverse@#&)@*Map[g]

Try it online!

totallyhuman

Posted 2018-03-05T16:00:22.230

Reputation: 15 378

2

SOGL V0.12, 2 bytes

-1 byte thanks to dzaima.

╬ø

Try it here!

totallyhuman

Posted 2018-03-05T16:00:22.230

Reputation: 15 378

2

APL (Dyalog Classic), 7 bytes

⍪∘⊖⍨⊢,⌽

Try it online!

ngn

Posted 2018-03-05T16:00:22.230

Reputation: 11 449

2

Ruby, 35 bytes

->a{r=->b{b+b.reverse}
r[a].map &r}

Try it online!

A lambda accepting a 2D array and returning a 2D array. It's straightforward, but here's the ungolfed version anyway:

->a{
  r=->b{ b+b.reverse } # r is a lambda that returns the argument and its reverse
  r[a].map &r          # Add the array's reverse, then add each row's reverse
}

benj2240

Posted 2018-03-05T16:00:22.230

Reputation: 801

2

C (gcc), 114 111 bytes

j,i;f(A,w,h)int*A;{for(i=h+h;i-->0;puts(""))for(j=w+w;j-->0;)printf("%d,",A[(i<h?i:h+h+~i)*w+(j<w?j:w+w+~j)]);}

Try it online!

C (gcc), 109 bytes (abusing ease of parsing)

  • Thanks to Kevin Cruijssen for suggesting to only allow one-digit input integers; saved two bytes.
j,i;f(A,w,h)int*A;{for(i=h+h;i-->0;puts(""))for(j=w+w;j-->0;)putchar(A[(i<h?i:h+h+~i)*w+(j<w?j:w+w+~j)]+48);}

Try it online!

Jonathan Frech

Posted 2018-03-05T16:00:22.230

Reputation: 6 681

You can save 3 bytes by inverting the loops. for(i=h+h;i-->0;puts(""))for(j=w+w;j-->0;) – Kevin Cruijssen – 2018-03-06T08:18:47.797

Does not fulfill spec; prints the array, rather than returning it. – None – 2018-03-06T11:14:39.147

"For ease of parsing, you may assume they are all between 1 and 9.", so you can remove the comma in the printf("%d" for an additional -1 byte. – Kevin Cruijssen – 2018-03-06T15:12:13.137

@Rogem I would say printing the array falls under accepted i/o. – Jonathan Frech – 2018-03-06T19:07:38.863

1@KevinCruijssen Thanks a lot; using the ease of parsing I managed to shave off another byte. – Jonathan Frech – 2018-03-06T19:12:36.803

2

Java 8, 140 131 bytes

m->{String r="";for(int a=m.length,b=m[0].length,i=a+a,j;i-->0;r+="\n")for(j=b+b;j-->0;)r+=m[i<a?i:a+a+~i][j<b?j:b+b+~j];return r;}

Explanation:

Try it online.

m->{                      // Method with integer-matrix parameter and String return-type
  String r="";            //  Result-String, starting empty
  for(int a=m.length,     //  Amount of rows of the input-matrix
          b=m[0].length,  //  Amount of columns of the input-matrix
          i=a+a,j;        //  Index integers
      i-->0;              //  Loop over double the rows
      r+="\n")            //    After every iteration: append a new-line to the result
     for(j=b+b;j-->0;)    //   Inner loop over double the columns
       r+=                //    Append the result with:
          m[i<a?          //     If `i` is smaller than the amount of rows
             i            //      Use `i` as index in the input-matrix
            :             //     Else:
             a+a+~i]      //      Use `a+a+i-1` as index instead
           [j<b?          //     If `j` is smaller than the amount of columns
             j            //      Use `j` as index in the input-matrix
            :             //     Else:
             b+b+~j];     //      Use `b+b+j-1` as index instead
  return r;}              //  Return the result-String

Kevin Cruijssen

Posted 2018-03-05T16:00:22.230

Reputation: 67 575

2

J, 11 bytes

Anonymous tacit prefix function.

|:@(,|.)^:2

Try it online!

|: transpose

@(…) the result of:

, the argument followed by

|. its reverse

^:2 and all this done twice

Adám

Posted 2018-03-05T16:00:22.230

Reputation: 37 779

1

V, 12 bytes

yGæGPÎy$æ_|P

Try it online!

Explanation:

yG              " Yank every line
  æG            " Reverse the order of the lines
    P           " Paste what we yanked
     Î          " On every line:
      y$        "   Yank the whole line
        æ_      "   Reverse the whole line
          |     "   Move to the beginning of the line
           P    "   Paste what we yanked

James

Posted 2018-03-05T16:00:22.230

Reputation: 54 537

1

Julia 0.6, 55 49 bytes

~i=i:-1:1
!x=[x x[:,~end];x[~end,:] x[~end,~end]]

Try it online!

~(i) is a function to create slice from i down to 1.
So ~end gives the slice end:-1:1

!(x) is the function to do the rebuilding of the array.

Lyndon White

Posted 2018-03-05T16:00:22.230

Reputation: 1 021

1

Python 3, 49 bytes

def f(a):o=[i+i[::-1]for i in a];return o+o[::-1]

Where a is the input array. This function will return a 2D array.

Dat

Posted 2018-03-05T16:00:22.230

Reputation: 879

1

Clojure, 56 bytes

(fn[i](map #(concat %(reverse %))(concat i(reverse i))))

Creates an anonymous function which takes the two dimensional list and returns the fixed rectangle as two dimensional list.

Try it online!

Joshua

Posted 2018-03-05T16:00:22.230

Reputation: 231

1

Perl 5 -lp -Mfeature=say, 36 bytes

unshift@l,$_.=reverse;END{say for@l}

Deparsed:

BEGIN { $/ = "\n"; $\ = "\n"; }
use feature 'say';
LINE: while (defined($_ = readline ARGV)) {
    chomp $_;
    unshift @l, $_ .= reverse;
    sub END {
        say $_ foreach (@l);
    }
}
continue {
    die "-p destination: $!\n" unless print $_;
}

Try it online!

Pavel

Posted 2018-03-05T16:00:22.230

Reputation: 8 585