23
\$\begingroup\$

Have a look at this ascii art diagram of various boxes:

+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |          +-------+       |
|   |     |                |        |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+

Each box is formed with pipe characters for the vertical parts (|), dashes for the horizontal parts (-), and pluses for the corners (+).

The diagram also shows boxes inside other boxes. We'll call the number of boxes that a box is contained within that box's layer. Here's the diagram again with the layer of each box annotated:

+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |   1   |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |    0     +-------+       |
|   |     |        2       |   1    |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |   1   |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+

Your program will take in a box diagram similiar to the one at the top as input. As output, your program should output the box diagram with:

  • The box on layer 0 should be filled with the character # (NB: There will only ever be one box on layer 0);
  • Boxes on layer 1 should be filled with the character =;
  • Boxes on layer 2 should be filled with the character -;
  • Boxes on layer 3 should be filled with the character .;
  • Boxes on layer 4 and above should not be filled.

Here is what the output of the example input should look like:

+--------------------------------------------------------------+
|##############################################################|
|###+-------------------------------+##########+-------+#######|
|###|===============================|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###|=====+----------------+========|##########|=======|#######|
|###|=====|----------------|========|##########+-------+#######|
|###|=====|----------------|========|##########################|
|###|=====|----------------|========|##########+-------+#######|
|###|=====+----------------+========|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###+-------------------------------+##########+-------+#######|
|##############################################################|
+--------------------------------------------------------------+

Here is another input and output showing layers 3, 4, and 5. Note the horizontal lines at the top that are very close together. In these cases there is not enough space to fill any characters there.

+-----------------------------------------------------------------------+
|     +--------------------------------------------------------------+  |
|     |      +-----------------------------------------------------+ |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           |         |             |   | | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |                                         | | |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |                                                     | |  |
|     |      |                                                     | |  |
|     |      +-----------------------------------------------------+ |  |
|     |                                                              |  |
|     +--------------------------------------------------------------+  |
|                                                                       |
|                                                                       |
|                                                                       |
+-----------------------------------------------------------------------+

The output:

+-----------------------------------------------------------------------+
|#####+--------------------------------------------------------------+##|
|#####|======+-----------------------------------------------------+=|##|
|#####|======|---------+-----------------------------------------+-|=|##|
|#####|======|---------|...........+---------------------------+.|-|=|##|
|#####|======|---------|...........|         +-------------+   |.|-|=|##|
|#####|======|---------|...........|         |             |   |.|-|=|##|
|#####|======|---------|...........|         +-------------+   |.|-|=|##|
|#####|======|---------|...........+---------------------------+.|-|=|##|
|#####|======|---------|.........................................|-|=|##|
|#####|======|---------+-----------------------------------------+-|=|##|
|#####|======|-----------------------------------------------------|=|##|
|#####|======|-----------------------------------------------------|=|##|
|#####|======+-----------------------------------------------------+=|##|
|#####|==============================================================|##|
|#####+--------------------------------------------------------------+##|
|#######################################################################|
|#######################################################################|
|#######################################################################|
+-----------------------------------------------------------------------+

Another input, this time with the vertical lines close together as well:

+-------------+
|+-----------+|
||           ||
||           ||
||           ||
|+-----------+|
+-------------+

The output:

+-------------+
|+-----------+|
||===========||
||===========||
||===========||
|+-----------+|
+-------------+

Additional Notes

  • There can be whitespace around the outermost box.
  • Boxes cannot have an internal width or height of 0 (so they'll always be some space inside them)
  • Boxes on the same layer can touch each other.
\$\endgroup\$
0

8 Answers 8

3
\$\begingroup\$

Ruby 163 164

w=l=-1
x=$<.map{|l|w=l.size;l}.join
b=[]
x.size.times{|i|c=x[i]
x[i..i+1]=='+-'&&(x[i+w]!=?|?b-=[i%w]:b<<i%w)
c>?z&&l+=b&[i%w]!=[]?1:-1
$><<(c==' '&&'#=-.'[l]||c)}

Try online: test case #1, test case #2.

The ungolfed program:

  # read all lines from STDIN
  input = $<.map{|l|l}.join
  width = input.index(?\n)+1

  box_left_margins = []
  current_layer = -1

  input.size.times{|i|
    c = input[i]

    if c == ?+ && input[i+1] == ?-
      #we're at a box's left margin
      if input[i+width] == ?|
        # we're at the box's top - mark this index as a left margin
        box_left_margins << i%width
      else
        # we're at the box's bottom - this index is no longer a left margin
        box_left_margins-=[i%width]
      end
    end

    if c == ?|
      if box_left_margins.include? (i%width)
        current_layer += 1
      else
        current_layer -= 1
      end
    end

    if c == ' '
      $><< ('#=-.'[current_layer]||' ')
    else
      $><<c
    end
  }
\$\endgroup\$
2
\$\begingroup\$

Java, 476 466 bytes

import java.util.*;class H{public static void main(String[]a){Scanner p=new Scanner(System.in);char[]l=p.nextLine().toCharArray(),d={'#','=','-','.'};int s=l.length,b,i;int[]m=new int[s];String o=new String(l);for(;;){o+='\n';l=p.nextLine().toCharArray();if(l[0]=='+')break;o+='|';b=0;for(i=1;i<s;++i){char c=l[i];switch(c){case' ':c=b>3?' ':d[b];break;case'+':m[i]=l[i-1]=='-'?-++m[i]:- --m[i];break;case'|':b+=m[i];}o+=c;}}o+=new String(l);System.out.println(o);}}

This reads the first line to determine the width (s) of the outermost box. With this it keeps an array of length s. This array stores from left to right where boxes begin and end and is initialized with 0s. It also stores the box-height.

The program reads the input line by line and watches for the following characters:

  • '+' is, as we know, the edge of a box. If the input char to the left is a '-', it is the end of the box, else it is the beginning. The marker array gets updated as follows:
    • If the marker at this index is 0, set the value to 1 (beginning) or -1 (end).
    • Else set the value to 0. (We reached the bottom of the box, it is not important anymore)
  • '|' changes the current box-height by the marker at the current index.
  • ' ' Every char gets output as it was, except for blanks, which are replaced according to the current box-height.

Edit: Thanks to TheNumberOne for the suggestion. I also replaced while(true) with for(;;).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can replace import java.util.Scanner with import java.util.* \$\endgroup\$ Jun 5, 2015 at 14:20
2
\$\begingroup\$

CJam, 114 111 108 104 103 102 98 bytes

q"-+":R/Ws*N/z{_,{"|1"/Bs*}*}%z{_,,{_I=S&{_I>_1sf&s,\"|+"f&s,m5e<" #=2."=I\t}&}fI}%N*Ws/R*Cs"|-"er

Try it online in the CJam interpreter.

How it works

q               e# Read all input from STDIN.
"-+":R/Ws*      e# Replace each "-+" with "-1".
N/z             e# Split at linefeeds and zip. Pushes the array of columns.
{               e# For each column:
  _,            e#   Push its length.
  {             e#   Do that many times:
    "|1"/Bs*    e#   Replace each "|1" with "11".
  }*            e#
}%              e#
z               e# Transpose. Goes back to array of rows.
{               e# For each row:
  _,,           e#   Push the array of its indexes.
  {             e#   For each index I:
    _I=         e#     Get the Ith character of the row.
    S&{         e#     If it is a space:
      _I>       e#       Get the characters after the Ith.
      _1sf&s,   e#       Count how many characters are 1's.
      \"|+"f&s, e#       Count how many are |'s or +'s.
      m5e<      e#       Subtract and truncate at 5.
      " #=2."=  e#       Retrieve the corresponding character.
      I\t       e#       Replace the Ith character of the row with that one.
    }&          e#
  }fI           e#
}%              e#
N*              e# Join the rows, separating by linefeeds.
Ws/R*           e# Turn "-1"s back to "-+"s.
Cs"|-"er        e# Turn 1's and 2's into |'s and -'s.
\$\endgroup\$
0
2
\$\begingroup\$

JavaScript (ES6) 156

Run snippet in Firefox to test

F=b=>(
  r=b.split(/\n/),q=[n=0],
  r.map((r,i)=>(
    [...r].map((c,p)=>c=='+'?(q[p]=r[p-1]=='-'?-1:1,c):c<'!'?' #=-.'[n]||' ':((n+=q[p]|0),c)).join(''))
  ).join('\n')
)

// TEST

o=x=>O.innerHTML += x+'\n\n'


;[`+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |          +-------+       |
|   |     |                |        |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+`
,`+-----------------------------------------------------------------------+
|     +--------------------------------------------------------------+  |
|     |      +-----------------------------------------------------+ |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           |         |             |   | | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |                                         | | |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |                                                     | |  |
|     |      |                                                     | |  |
|     |      +-----------------------------------------------------+ |  |
|     |                                                              |  |
|     +--------------------------------------------------------------+  |
|                                                                       |
|                                                                       |
|                                                                       |
+-----------------------------------------------------------------------+`
,`+-------------+
|+-----------+|
||           ||
||           ||
||           ||
|+-----------+|
+-------------+`  
].forEach(t=>o(t+'\n'+F(t)+'\n'))
pre { font-size:10px;}
<pre id=O></pre>

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

CJam, 76 74 bytes

q:Q"-+":R/Ws*{_"| "#"]_QN#~%'|m0='+=2*(U+:U+~; \"#=-.\"+U5e<= "S/=~}%Ws/R*

Try it online in the CJam interpreter.

How it works

q:Q        e# Read all input from STDIN and save it in the variable Q.
"-+":R/Ws* e# Replace each "-+" with "-1".
           e# This allows us to easily keep track of right corners.
{          e# For each charcter in the modified input:
  _"| "#   e#   Push its index in the string (0 for '|', 1 for ' ', -1 otherwise).

  "]_QN#~%'|m0='+=2*(U+:U+~; \"#=-.\"+U5e<= "S/

           e#   Split the pushed string at spaces, which results in three chunks:

           e#     ]        Turn the entire stack into a string.
           e#     _QN#     Compute the first index of a linefeed (row length).
           e#     ~%       Retrieve every previous character in the current column,
           e#              starting with the last.
           e#     '|m0=    Get the first character that is not a vertical bar.
           e#     '+=2*(   Push 1 if it's a plus sign and -1 otherwise.
           e#     U+:U     Add to U (initially 0) to keep track of the layer.
           e#     +~;      Add U to the string (casts to Array), dump and discard U.

           e#     "#=-."+  Concatenate this string with the space on the stack.
           e#     U5e<     Truncate U at 5.
           e#     =        Retrieve the corresponding character to replace the space.

           e#     (empty)

  =~       e#   Select and execute the proper chunk.
}%         e#
Ws/R*      e# Replace each "-1" with "-+".
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Unicode), 50 bytesSBCS

s[⊃¨0~¨⍨a,¨5|5⌊+⍀+\(⊢ׯ1*+⍀++\)5=a←⎕⍳⍨s←' #=-.+|']

Try it online!

s←' #=-.+|' assign a string to variable s

evaluated input, it must be a character matrix

⎕⍳⍨s replace every element of with its index in s

a← assign to a

5= return a boolean matrix of where the +-es are in a (s[5] is '+')

(⊢ׯ1*+⍀++\) this is a train of functions:

  • +\ matrix of partial sums by row

  • + plus

  • +⍀ matrix of partial sums by column

  • ¯1* negative one to the power of - turn odds into ¯1 and evens into 1

  • ⊢× multiply by the train's argument - zero out everything except box corners

+⍀+\ partial sums by column of partial sums by row

5⌊ minimum of that and 5

5| modulo 5

a,¨ pair up the elements of a and of the current matrix

0~¨⍨ remove 0 from the pairs

⊃¨ first each of what's remaining

s[ ] use every element as an index in s

\$\endgroup\$
6
  • \$\begingroup\$ oh no! \$\endgroup\$ Feb 9, 2018 at 17:23
  • \$\begingroup\$ @EriktheOutgolfer No need to worry, the answer is correct :) The expression that prepares the argument (mixes raw input lines into a matrix) should reverse it because ↑⍞⍞...⍞ evaluates right-to-left. For the first example it didn't matter and I forgot to mention this. \$\endgroup\$
    – ngn
    Feb 9, 2018 at 17:40
  • \$\begingroup\$ except that it still fills with .s where it shouldn't \$\endgroup\$ Feb 9, 2018 at 17:43
  • \$\begingroup\$ @EriktheOutgolfer ah, I see... I'll delete the answer now and I'll fix it later. Thanks. \$\endgroup\$
    – ngn
    Feb 9, 2018 at 17:52
  • \$\begingroup\$ should be fixed now \$\endgroup\$
    – ngn
    Feb 9, 2018 at 23:59
0
\$\begingroup\$

><>, 118 115 87 bytes

]0{i:0(?;:"-"=?\:"+"=?\:" "=?\$3l$g+}:ob(?
~$?:g2.10p1+4f:<p3l+10/.16@:$/>.!0"#"$
 #=-.

Try it online!

If one of the symbols wasn't a - then this could be 6 bytes shorter. Eh, made it a bit lot smaller anyway

How It Works:

] Resets the stack
 0{ Pushes a 0 and rotates the stack
    If the stack is empty, this initialises 0 as the counter
    Otherwise it adds an extra 0 to the stack and pushes the counter to the top
   i:0(?; Gets input and ends if it is EOF
         :"-"=?\ If the inputted character is a -
         p1+4f:< Put a - at cell (19, 1)
      .10        And skip to the end of this line
         
         :"+"=?\ Else if the inputted character is +
            ?10/ Generate either -1 or 1, depending on what was last put into cell (19,1)
                 The question mark represents cell (19,1), which is either + or -
         p3l     Put this number on (3, length of the stack)
.10p1+4f:<       Repeat the exact same code as with the -, except we put a + at cell (19,1)
         :" "=?\ Else if the character is a space
            @:$/ Create a copy of the counter
         .16     Skip to cell (1,6)
      g2         Get the cell (2, counter) (the  #=-.)
   ~$?           If that cell is a zero, pop it, leaving the initial space. 
                 Else pop the space, leaving the fetched character
        Else if the character is a | or a newline
        $3l$g+   Get the cell at (3, length of the stack) and add it to the counter
    For everything but the last else, we are at the end of the second line
       >.!0"#"$ Skip to the 35th instruction on the first line
 
 } Push the counter to the bottom of the stack
  :o Output the current character
    b(? If the character is smaller than 11 (a newline)
 ]          Skip the clear stack at the start of the line
 Repeat this until EOF


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

C (gcc), 190 179 bytes

-11 bytes thanks to ceilingcat

Fails if sizeof(int) > 9, but then you can take solace in the fact that your computer is from the future.

l;*H,*h,d;f(S){h=H=calloc(l=index(S,10)-S,9);for(char*s=S;*s;s++)h=*s^10?h:H-1,d=*s-43?d:s!=S&s[-1]==45|s-S>l&s[~l]=='|'?-1:1,*h+=*s^45?0:d,h+=write(1,*s^32|*h>4?s:" #=-."+*h,1);}

Try it online!

\$\endgroup\$
0

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.