Advent Challenge 4: Present Assembly Line!

Santa was able to remanufacture all of the presents that the elves stole overnight! Now he has to send them to the assembly line for packaging. He usually has a camera to supervise the assembly line both to make sure the elves are doing a good job and because assembly line pictures look nice on advertising posters [citation-needed]

Unfortunately, his camera broke, so he would like you to draw out a simulation of what the assembly line would look like!

In order to keep to assembly line working at maximum efficiency and to reduce the risk of error or failure, all present boxes have the same width so that they fit perfectly on the conveyor belt.

Challenge

Given a list of presents represented by their dimensions, output a conveyor belt with all of the presents.

A present is drawn like such:

+----+
/    /|
+----+ |
|    | +
|    |/
+----+

This present has width 1, height 2, and length 4. Note that the plus-signs don't count for the side-length, so a present with length 4 actually spans 6 positions.

All presents are drawn next to each other with one space between the closest two characters; that is, the bottom-left corners of the presents are spaced such that if a present box has length l and width w, the next present box's bottom-left corner will be exactly l + w + 4 positions right of the bottom-left corner of the previous box.

After all present boxes are drawn, the conveyor belt is drawn by replacing the space between boxes on each of the last width + 2 lines with underscores.

The final output for present boxes with (l, w, h) of [(4, 1, 2), (8, 1, 3), (1, 1, 1)] would be:

+--------+
+----+  /        /|
/    /| +--------+ |   +-+
+----+ | |        | |  / /|
|    | +_|        | +_+-+ +
|    |/__|        |/__| |/
+----+___+--------+___+-+

Formatting Specifications

You can choose either to take a list of 3-tuples where one of the elements is consistent across the whole list (that would be the width), or you can take the present width and then a list of 2-tuples representing the length and height of each present. You can take the inputs in any order and in any reasonable format, but the presents must be displayed in the same order that they are given as input.

You may choose any reasonable output format for the ASCII-art (including returning from a function).

Test Cases

These test cases are given as [(l, w, h), ...] format.

[(4, 1, 2), (8, 1, 3), (1, 1, 1)]:

+--------+
+----+  /        /|
/    /| +--------+ |   +-+
+----+ | |        | |  / /|
|    | +_|        | +_+-+ +
|    |/__|        |/__| |/
+----+___+--------+___+-+

[(5, 3, 4), (8, 3, 1), (1, 3, 7)]:

+-+
/ /|
/ / |
+-----+                 / /  |
/     /|                +-+   |
/     / |                | |   |
/     /  |     +--------+ | |   |
+-----+   |    /        /| | |   |
|     |   +___/        / +_| |   +
|     |  /___/        / /__| |  /
|     | /___+--------+ /___| | /
|     |/____|        |/____| |/
+-----+_____+--------+_____+-+

[(0, 0, 0)] (this is the most interesting test case ever :P)

++
+++
++

[(8, 3, 0), (0, 3, 8)] (more zero cases)

++
//|
// |
//  |
++   |
||   |
||   |
||   |
+--------+ ||   |
/        /+_||   +
/        //__||  /
/        //___|| /
+--------+/____||/
+--------+_____++

Rules

• Standard Loopholes Apply
• This is , so the shortest answer in bytes wins
• No answer will be accepted

Note: I drew inspiration for this challenge series from Advent Of Code. I have no affiliation with this site

You can see a list of all challenges in the series by looking at the 'Linked' section of the first challenge here.

• @AdmBorkBork all present boxes have the same width Dec 4 '17 at 15:50
• If Charcoal doesn't wreck this, I don't know what will. Dec 4 '17 at 16:05
• @totallyhuman actually, brainf**k will win this challenge :P Dec 4 '17 at 17:04
• Can you make a post on meta to index all of these questions? Dec 4 '17 at 20:05
• @RamenChef Hm good idea. I might do that :P Dec 5 '17 at 0:03

Charcoal, 96 81 bytes

ＮθＷＳ«→ＦυＧ↗→↙⁺²θ_≔Ｉ⪪ι υ≔⊟υπ≔§υ⁰ρ→↗Ｇ↑⊕π↗⊕θ→⊕ρ↓⊕π↙⊕θ ↑πＰ↗⊕θＰ←⊕ρ↓+↓πＦ²«↷⁴+ρ↷²+π↷¹+θ↶³

Try it online! Link is to verbose version of code. Input is the width on the first line, then the other dimensions on following lines, ending with a blank line. Explanation:

Ｎθ

Input the width.

ＷＳ«

Loop over the remaining lines until the blank line is reached.

→ＦυＧ↗→↙⁺²θ_

Draw the belt between presents. The u variable is predefined to an empty list, which therefore does nothing on the first pass, while later on it ends up with a single element, causing this code to run once. (Using an if would be less golfy.)

≔Ｉ⪪ι υ

Split the dimensions at the space, cast them to integer, and save them in u.

≔⊟υπ

Remove the last dimension and save it in p.

≔§υ⁰ρ

Copy the first dimension to r, but leave it in u so that the belt gets drawn on the next loop.

→↗Ｇ↑⊕π↗⊕θ→⊕ρ↓⊕π↙⊕θ

Erase the interior of the present, in case the belt overlaps it.

↑πＰ↗⊕θＰ←⊕ρ↓+↓π

Draw the interior lines of the present.

Ｆ²«↷⁴+ρ↷²+π↷¹+θ↶³

Draw halfway around the exterior of the present, then repeat for the other half.

Pip, 160 154 bytes

153 bytes of code, +1 for -l flag.

{YMX:_+B+3MUaRV\$.({UwhlWg+^11{a<=h+w?J[sXa-haN[0hh+w]?'-XlWR'+sXlWR("/|"a<h)RV(("+|/"aCMw).sXw)@<MN[ah+w-awh]'_Xw-a+1|s]sXl+w+3}M,y}MUa)R_ +'_X#_<|:'_}

This is a function that takes a list of lists containing [width height length]. Try it online!

How?

Top-level explanation:

• Define a function that returns a list of lines representing one box
• Map the function to each list of dimensions given
• Concatenate the resulting lists of lines item-wise
• Do a little post-processing with regex replacements to get the underscores to behave properly

Python 2, 508 bytes

def f(B):
d=B+2;H=max(B)+d+1;W=sum(sum(b[1:])+3for b in B)+len(B);r=[[' ']*i+W*['_']for i in range(d)]+[W*[' ']for _ in' '*H];o=0
for h,w,l in B:
for i in range(w+2,1,-1):r[i-1][o+i-2:o+l+i]=[' ']*(l+2)+['/'];r[h+i][o+i-1]=r[h+i][o+l+i]='/'
r[o:o+l+2]=r[h+1][o:o+l+2]=r[w+h+2][o+w+1:o+w+l+3]=['+']+['-']*l+['+']
for i in range(1,h+1):m=min(i,w)-1;r[i][o:o+l+2+m]=['|']+[' ']*l+['|']+[' ']*m;r[i+w+1][o+l+w+2]='|'
r[w+1][o+l+w+2]='+';o+=l+w+4
for l in r[H-1::-1]:print''.join(l).rstrip('_')

Try it online!

Takes a list of lists of [height, width, length]