16
\$\begingroup\$

Introduction

Sometimes, my boxes are too small to fit anything in it. I need you to make a box expander! So, what makes a box a box in this challenge.

 OOOO
O    O
O    O
O    O
 OOOO

The corners of the box are always spaces. The box itself can be made out of the same character. That character can be any printable ASCII character, except a space. So, that's these characters:

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

The side lengths of the box above are 4, 3. You may assume that the side length is always positive. That means that this is the smallest box you need to handle:

 #
# #
 #

In order to expand a box, you need to increment each side length. Let's go through this, step by step, with the above example. We first take the upper side of the box, which is:

 OOOO

We expand this by one, so we get:

 OOOOO

This is the upper and lower part of the box now. After that, we do the same with the sides on the left and right:

O
O
O

Becomes:

O
O
O
O

Now we reassemble the box, which results into:

 OOOOO
O     O
O     O
O     O
O     O
 OOOOO

The task

Given a box, expand it by 1. The box can be given in multiple lines, or in an array.

Test cases

 OOOO          OOOOO
O    O    >   O     O
 OOOO         O     O
               OOOOO

 XXXXXX        XXXXXXX
X      X  >   X       X
X      X      X       X
 XXXXXX       X       X
               XXXXXXX

 ~             ~~
~ ~       >   ~  ~
 ~            ~  ~
               ~~

This is , so the submission with the least amount of bytes wins!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ can the box have a new line before it? \$\endgroup\$
    – Riley
    Aug 12, 2016 at 21:40
  • \$\begingroup\$ @Riley Yes, that is allowed :). \$\endgroup\$
    – Adnan
    Aug 12, 2016 at 21:41
  • 1
    \$\begingroup\$ Can the box be padded with spaces? \$\endgroup\$
    – Leaky Nun
    Aug 13, 2016 at 3:54
  • \$\begingroup\$ @LeakyNun Yes, you may do that. \$\endgroup\$
    – Adnan
    Aug 13, 2016 at 8:45

19 Answers 19

11
\$\begingroup\$

Vim, 7 bytes

♥GYPjYp

where ♥ is Control-V.

           The cursor starts on the first non-whitespace character of the first line.
♥G         Enter visual block mode and go to bottom of document.
  YP       Duplicate this column.
    j      Move down to the second line of the file.
     Yp    Duplicate this line.

enter image description here

\$\endgroup\$
7
  • \$\begingroup\$ Why not use YP both times for consistency? \$\endgroup\$
    – Neil
    Aug 13, 2016 at 10:34
  • \$\begingroup\$ I accidentally hit p while recording the animation, so I stuck with it when transcribing the answer. Does it matter? >_>; \$\endgroup\$
    – Lynn
    Aug 13, 2016 at 10:37
  • \$\begingroup\$ I just found the inconsistency odd, but I like your explanation. \$\endgroup\$
    – Neil
    Aug 13, 2016 at 11:21
  • \$\begingroup\$ This is exactly the same thing as my V answer, just that I happened to create one-byte mappings for <C-v> G and YP. It kinda makes my language feel cheap. :/ \$\endgroup\$
    – DJMcMayhem
    Aug 13, 2016 at 13:57
  • \$\begingroup\$ Hm, control-V shows up as a heart on my phone... ❤ \$\endgroup\$
    – Beta Decay
    Aug 13, 2016 at 17:52
6
\$\begingroup\$

JavaScript (ES6), 57 53 52 bytes

s=>s.replace(/^.(.)/gm,s="$&$1").replace(/(\n.*)/,s)

Explanation: The first regexp duplicates the second column and the second regexp duplicates the second row, thus enlarging the box as desired. Edit: Saved 4 bytes thanks to MartinEnder♦.

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

Python, 49 42 bytes

Anonymous lambda:

-7 from xnor

lambda s:[t[:2]+t[1:]for t in s[:2]+s[1:]]

Previous version:

D=lambda s:s[:2]+s[1:]
lambda s:D(list(map(D,s)))

D is a function that duplicates the second item of a sequence.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The idea of re-using the function is clever, but it seems to be shorter to just repeat the code: lambda L:[s[:2]+s[1:]for s in L[:2]+L[1:]]. \$\endgroup\$
    – xnor
    Aug 13, 2016 at 2:34
  • \$\begingroup\$ Side note for the previous version: I think map(D,D(s)) would give 43 instead \$\endgroup\$
    – Sp3000
    Aug 13, 2016 at 8:01
5
\$\begingroup\$

Retina, 20 bytes

Byte count assumes ISO 8859-1 encoding.

1`¶
¶$%'¶
%2=`.
$&$&

Try it online! (There's several additional lines which enable a test suite where the test cases are separated by two linefeeds.)

Explanation

1`¶
¶$%'¶

1 is a limit which restricts Retina to apply the substitution only to the first match it finds. matches a single linefeed, so we only need to consider replacing the linefeed at the end of the first line. It is replace with ¶$%'¶, where $%' inserts the entire line following the match (a Retina-specific substitution element). Hence, this duplicates the second line.

%2=`.
$&$&

Here, % is per-line mode, so each line is processed individually, and the lines are joined again afterwards. 2= is also a limit. This one means "apply the substitution only to the second match". The match itself is simple a single character and the substitution duplicates it. Hence, this stage duplicates the second column.

\$\endgroup\$
5
\$\begingroup\$

Haskell, 24 bytes

f(a:b:c)=a:b:b:c
f.map f

Uses RootTwo's idea of duplicating the second row and column. The map f does this to each row, and the f. then does this to the rows.

\$\endgroup\$
4
\$\begingroup\$

V, 6 5 bytes

yêpjÄ

Try it online!

This is actually a byte longer than it should be. It should have been:

äêjÄ

But this has an unknown bug. :(

Explanation:

yê     "yank this colum
  p    "paste what we just yanked
   j   "move down to line 2
    Ä  "and duplicate this line
\$\endgroup\$
2
  • \$\begingroup\$ What does the other one do? \$\endgroup\$ Aug 13, 2016 at 3:42
  • \$\begingroup\$ @ConorO'Brien ä is the duplicate operator (essentially "y" and "p" together in one byte) so äê is "duplicate column" \$\endgroup\$
    – DJMcMayhem
    Aug 13, 2016 at 3:46
4
\$\begingroup\$

PowerShell v2+, 57 53 52 bytes

param($n)($n-replace'^.(.)','$&$1')[0,1+1..$n.count]

Slightly similar to Neil's JavaScript answer. The first replace matches the beginning of the line and the next two characters, and replaces them with the first character and second-character-twice. Instead of a second replace, it's swapped out for array-indexing to duplicate the second line. Takes input as an array of strings. The resultant array slices are left on the pipeline and printing is implicit.

Saved 4 bytes thanks to Martin.

Some examples:

PS C:\Tools\Scripts\golfing> .\automatic-box-expander.ps1 ' oooo ','o    o',' oooo '
 ooooo 
o     o
o     o
 ooooo 

PS C:\Tools\Scripts\golfing> .\automatic-box-expander.ps1 ' # ','# #',' # '
 ## 
#  #
#  #
 ## 
\$\endgroup\$
0
4
\$\begingroup\$

Brachylog, 28 26 bytes

2 bytes thanks to Fatalize.

{bB,?~c[A:C]hl2,A:Bc.}:1a.

Try it online!

\$\endgroup\$
2
3
\$\begingroup\$

MATL, 12 bytes

tZy"@:2hSY)!

Input is a 2D char array, with semicolon as row separator. For example, the first test case has input

[' OOOO ';'O    O';' OOOO ']

Try it online! Test cases 1, 2, 3.

Explanation

The code does the following twice: repeat the second row of the array and transpose.

To repeat the second row of an m×n array, the vector [1 2 2 3 ... m] is used as row index. This vector is generated as follows: range [1 2 3 ... m], attach another 2, sort.

t       % Take input implicitly. Duplicate
Zy      % Size of input as a two-element array [r, c]
"       % For each of r and c
  @     %   Push r in first iteration (or c in the second)
  :     %   Generate range [1 2 3 ... r] (or [1 2 3 ... c])
  2hS   %   Append another 2 and sort
  Y)    %   Apply as row index
  !     %   Transpose
        % End for. Display implicitly
\$\endgroup\$
2
\$\begingroup\$

Pyth, 10 bytes

L+<b2tbyMy

Try it online!

\$\endgroup\$
2
\$\begingroup\$

SED 69 19 (14 + 1 for -r) 15

s/.(.)/&\1/;2p   
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Can't you just do /.\(.\)/\0\1;2p? \$\endgroup\$
    – Neil
    Aug 12, 2016 at 22:48
  • \$\begingroup\$ @Neil I looked all over for that 2p, I figured there was a way to do it, but I couldn't find it. Thanks! \$\endgroup\$
    – Riley
    Aug 12, 2016 at 23:00
  • \$\begingroup\$ The -r'' part is not needed as long as you add 1 byte for the r flag, thus saving 3 bytes. Also, since you edited your first version of the code, the explanation at the end is now not valid. \$\endgroup\$
    – seshoumara
    Sep 3, 2016 at 11:06
  • \$\begingroup\$ @Neil Couldn't believe my eyes when I saw the \0 backreference, since they start at 1. The GNU sed's online manual speaks none of it. However, using & is I think equivalent and shorter. \$\endgroup\$
    – seshoumara
    Sep 3, 2016 at 11:50
  • \$\begingroup\$ @seshoumara Ah, those regexp version subtleties... which one uses \0 then? \$\endgroup\$
    – Neil
    Sep 3, 2016 at 16:36
1
\$\begingroup\$

CJam, 14 bytes

q~{~\_@]z}2*N*

Similar to my MATL answer, but repeats the second-last row instead of the second.

Try it online!

Explanation

q                e# Read input
 ~               e# Interpret as an array
  {      }2*     e# Do this twice
   ~             e# Dump array contents onto the stack
    \            e# Swap top two elements
     _           e# Duplicate
      @          e# Rotate
       ]         e# Pack into an array again
        z        e# Zip
            N*   e# Join by newlines. Implicitly display
\$\endgroup\$
1
\$\begingroup\$

K, 15 bytes

2{+x@&1+1=!#x}/

Takes input as a matrix of characters:

  b: (" OOOO ";"O    O";" OOOO ")
(" OOOO "
 "O    O"
 " OOOO ")

Apply a function twice (2{…}/) which gives the transpose (+) of the right argument indexed (x@) by the incremental run-length decode (&) of one plus (1+) a list of the locations equal to 1 (1=) in the range from 0 up to (!) the size of the outer dimension of the right argument (#x).

Step by step,

  #b
3
  !#b
0 1 2
  1=!#b
0 1 0
  1+1=!#b
1 2 1
  &1+1=!#b
0 1 1 2
  b@&1+1=!#b
(" OOOO "
 "O    O"
 "O    O"
 " OOOO ")
  +b@&1+1=!#b
(" OO "
 "O  O"
 "O  O"
 "O  O"
 "O  O"
 " OO ")
  2{+x@&1+1=!#x}/b
(" OOOOO "
 "O     O"
 "O     O"
 " OOOOO ")

Try it here with oK.

\$\endgroup\$
1
\$\begingroup\$

APL, 17 15 bytes

{⍉⍵⌿⍨1+2=⍳≢⍵}⍣2

Test:

      smallbox largebox
┌───┬──────┐
│ # │ OOOO │
│# #│O    O│
│ # │O    O│
│   │O    O│
│   │ OOOO │
└───┴──────┘
      {⍉⍵⌿⍨1+2=⍳≢⍵}⍣2 ¨ smallbox largebox
┌────┬───────┐
│ ## │ OOOOO │
│#  #│O     O│
│#  #│O     O│
│ ## │O     O│
│    │O     O│
│    │ OOOOO │
└────┴───────┘

Explanation:

             ⍣2   run the following function 2 times:
{           }     stretch the box vertically and transpose
         ⍳≢⍵      indices of rows of box
       2=         bit-vector marking the 2nd row
  ⍵/⍨1+           replicate the 2nd row twice, all other rows once
 ⍉                transpose
\$\endgroup\$
2
  • \$\begingroup\$ The APL symbol monadic ⍉ is matrix transpose, which isn't the same thing as rotating by 90 degrees. \$\endgroup\$
    – JohnE
    Aug 13, 2016 at 15:03
  • 1
    \$\begingroup\$ @JohnE: of course. I must've been more tired than I thought. Actually rotating by 90 degrees would be ⌽⍉ or ⊖⍉, but in this case it does not matter. \$\endgroup\$
    – marinus
    Aug 16, 2016 at 3:06
0
\$\begingroup\$

ListSharp, 326 bytes

STRG a=READ[<here>+"\\a.txt"]
ROWS p=ROWSPLIT a BY ["\r\n"]
ROWS p=GETLINES p [1 TO p LENGTH-1]
ROWS p=p+p[1]+p[0]
STRG o=p[0]
ROWS y=EXTRACT COLLUM[2] FROM p SPLIT BY [""]
ROWS x=EXTRACT COLLUM[3] FROM p SPLIT BY [""]
[FOREACH NUMB IN 1 TO o LENGTH-1 AS i]
ROWS m=COMBINE[m,x] WITH [""]
ROWS m=COMBINE[y,m,y] WITH [""]
SHOW=m

I definitely need to add the nesting of functions, but this works very well

comment if you want an explanation

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

JavaScript, 160 146 141 bytes

s=>{a=s[1];r="";l=s.split("\n");m=l.length;n=l[0].length;for(i=0;i<=m;i++){for(j=0;j<=n;j++)r+=!(i%m)&&j%n||i%m&&!(j%n)?a:" ";r+="\n"}return r}
\$\endgroup\$
0
\$\begingroup\$

Dyalog APL, 14 bytes

(1 2,1↓⍳)¨∘⍴⌷⊢

(

1 2, {1, 2} prepended to

1↓ one element dropped from

the indices

of each

of

the {row-count, column-count}

indexes into

the argument

E.g. for

 XX
X  X
 XX

we find the indices; {1, 2, 3} for the rows, and {1, 2, 3, 4} for the columns. Now we drop the initial elements to get {2, 3} and {2, 3, 4}, and then prepend with {1, 2}, giving {1, 2, 2, 3} and {1, 2, 2, 3, 4}. Finally, we use this to select rows and columns, simultaneously doubling row 2 and column 2.

TryAPL online!

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

Ruby, 46 bytes

->a{a.map{|r|r.insert(2,r[1])}.insert(2,a[1])}

Very straighforward solution, taking input as array of lines. I don't like duplicated inserts, so will try to golf it.

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

C#, 127 124 bytes

s=>{int n=s.Count-1,i=0;s[0]=s[n]=s[0].Insert(1,s[0][1]+"");s.Insert(1,s[1]);for(;i++<n;)s[i]=s[i].Insert(1," ");return s;};

Compiles to a Func<List<string>, List<string>>.

Formatted version:

s =>
{
    int n = s.Count - 1, i = 0;

    s[0] = s[n] = s[0].Insert(1, s[0][1] + "");

    s.Insert(1, s[1]);

    for (; i++ < n;)
        s[i] = s[i].Insert(1, " ");

    return s;
};
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.