Bridges are metaphors for everything in ASCII Art

Python 2 , 173 bytes

f=lambda b:'-|'+b[::-1].replace('/','\\')+-~(~i%2)*'-'+b+'|-'
for x in range(1,~-i/2):print f((len(b)-x)*'-'+b[:x]).replace('-',' ')
print f(b)

Mirror the value of b and add the central "-"
f=lambda b:'-|'+b[::-1].replace('/','\\')+-~(~i%2)*'-'+b+'|-'
Base pattern (right half of the bottom line)
Loop for non-bottom layers
for x in range(1,~-i/2):
Get the first x characters of the base pattern and complete with "-"
Replace all - with spaces to print all the layers (except bottom)
print f().replace('-',' ')
Print bottom layer
print f(b)

Befunge, 150 bytes


Try it online!

I've also provided an ungolfed version of the code which better demonstrates the architecture used in the construction of the bridge.

        >4                                         5v
        v+3                                       <&<
        >:00                                     p4+v
        v-`p0                                   1:/2<
        |\/->3#*                             *#`^#1\<

Try it online!

The towers handle the input and parameter initialisation. The deck is made up two loops calculating the parts of the bridge that need to be output for each x,y coordinate. And the foundation holds the character table for the those bridge parts, as well as some other completely unrelated code.

Detailed Explanation

We start by calculating the width and height of the output area that will need to be iterated in order to render the bridge.

w  = n + 3                (stored at 0,0)
h  = (w + 4)/2            (stored at 1,0)

Note that the y range is not zero-based. The initial value is 5 - (h<5) and is iterated up to h (the current value is stored at 2,0). The x value is iterated from w down to 0 and is stored on the stack.

The inner loop is just a series of boolean conditions determining whether a particular x,y coordinate matches any of the locations that require a non-space character. These calculations are based on two sliding offsets that follow the path of the suspension cables.

loff = y + x - w
roff = y - x 

The various conditions are then determined as follows:

left_tower       = (x == w-1)
left_suspension  = (loff > 0) and (loff%3 == 0) and (x < w-1)
right_tower      = (x == 1)
right_suspension = (roff > 0) and (roff%3 == 0) and (x > 1)
bridge_deck      = (y == h)

To translate these conditions into the correct character offset, we just need to multiply each of them by an appropriate offset and sum the result. This calculation is performed as the conditions are evaluated. So it looks something like this:

char_offset =  left_tower
char_offset += left_suspension * 2
char_offset += right_tower
char_offset += right_suspension * 3
char_offset += !char_offset * bridge_deck * 4

Note that the bridge_deck value is merged in based on whether any of the other conditions have been met, since a suspension or tower character will take precedence over the deck.

The end result is an offset into the character table on the last line of the playfield. We simply output that character and repeat the loop.

05AB1E, 79 59 58 bytes

"\  "×¹<;£R.sð«¹3‹ið}.BvyD¹Éi¨}R„\/„/\‡«'|.øð.ø}ð'-‡¹2›i»}

Try it online!.


"\  "×                                                     # Push n copies of "\  ".
      ¹<;£                                                 # Push a[0:(n-1)/2] 
          R.s                                              # Reverse, get substrings.
             ð«                                            # Append a space.
               ¹3‹ið}                                      # If n < 3, push a space.
                     .B                                    # Boxify.
                       vy                      }           # For each...
                         D¹Éi¨}R                           # Dupe, if n is odd, a[0:-1].
                                „\/„/\‡                    # Reverse the slashes.
                                       «'|.øð.ø            # Surround with | and a space.
                                                ð'-‡       # Replace spaces with "-".
                                                    ¹2›i } # If it's more than 2...
                                                        »  # Join stack by newlines.

Found the better solution, the key was to return the following arrays for each number as follows:

1=[" "]
2=["  "]
4=["\ "]
5=["\"," \"]
6=["\"," \ "]
7=["\"," \","  \"]
8=["\"," \","  \ "]