15
\$\begingroup\$

(with apologies to Jim West for the title, and randomly inspired by Cisco's textual representation of their logo: .:|:.:|:. for the concept)

Given an input integer 1 <= n <= 255, output an ASCII art representation of a suspension bridge of distance n following the below construction rules:

  • The start and end of the bridge (not counted in the n distance) are always -| and |-, so the bridge can appropriately connect to the highways next to it.
  • The bridge doesn't extend downward (the roadway level, composed of the - row, is the bottom row).
  • There can be at most two roadway pieces -- in a row, any longer span requires suspension cables for support.
  • The suspension cables \ extend from the roadway up to the towers | in straight lines.
  • The towers | must be tall enough to support the adjacent suspension cables, but no taller.
  • The bridge must be balanced left-to-right about the middle point, favoring the center sections whenever possible.
  • All of the above should result in a minimization of the cables, but just to be clear, the number of suspension cables must be minimized while still following the above rules.

To provide a visual representation, here are the expected outputs for n = 1, 2, 3, ... 15 --

1
-|-|-

2
-|--|-

3
-|\-/|-

4
-|\--/|-

5
 |\   /|
-|-\-/-|-

6
 |\    /|
-|-\--/-|-

7
 |\     /|
 | \   / |
-|--\-/--|-

8
 |\      /|
 | \    / |
-|--\--/--|-

9
 |\       /|
 | \     / |
 |  \   /  |
-|\--\-/--/|-

10
 |\        /|
 | \      / |
 |  \    /  |
-|\--\--/--/|-

11
 |\         /|
 | \       / |
 |  \     /  |
 |\  \   /  /|
-|-\--\-/--/-|-

12
 |\          /|
 | \        / |
 |  \      /  |
 |\  \    /  /|
-|-\--\--/--/-|-

13
 |\           /|
 | \         / |
 |  \       /  |
 |\  \     /  /|
 | \  \   /  / |
-|--\--\-/--/--|-

14
 |\            /|
 | \          / |
 |  \        /  |
 |\  \      /  /|
 | \  \    /  / |
-|--\--\--/--/--|-

15
 |\             /|
 | \           / |
 |  \         /  |
 |\  \       /  /|
 | \  \     /  / |
 |  \  \   /  /  |
-|\--\--\-/--/--/|-

Input

A single positive integer in any convenient format, n > 9.

Output

The ASCII-art bridge following the above construction technique.

Rules

  • Leading or trailing newlines or whitespace are all optional, so long as the bridge characters themselves line up correctly.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • If possible, please include a link to an online testing environment so people can try out your code!
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
4
  • \$\begingroup\$ #RageQuit (05ab1e.tryitonline.net/…) \$\endgroup\$ Commented Dec 15, 2016 at 19:40
  • \$\begingroup\$ @carusocomputing Hah, don't give up! :D \$\endgroup\$ Commented Dec 15, 2016 at 20:27
  • \$\begingroup\$ I didn't give up, just had to go somewhere else and didn't want to lose my progress ;). \$\endgroup\$ Commented Dec 15, 2016 at 21:17
  • 5
    \$\begingroup\$ @carusocomputing Aha. So, more like #RageTemporarilyWalkAway. \$\endgroup\$ Commented Dec 15, 2016 at 21:20

6 Answers 6

4
\$\begingroup\$

Python 2 , 173 bytes

i=input()
f=lambda b:'-|'+b[::-1].replace('/','\\')+-~(~i%2)*'-'+b+'|-'
b=(i*'/--')[:~-i/2]
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)
b=(i*'/--')[:~-i/2]
Loop for non-bottom layers
for x in range(1,~-i/2):
Get the first x characters of the base pattern and complete with "-"
(len(b)-x)*'-'+b[:x]
Replace all - with spaces to print all the layers (except bottom)
print f().replace('-',' ')
Print bottom layer
print f(b)

\$\endgroup\$
1
  • 5
    \$\begingroup\$ You should include the raw version (without any comments) in your post \$\endgroup\$
    – FlipTack
    Commented Dec 15, 2016 at 17:26
4
+100
\$\begingroup\$

Befunge, 150 bytes

45&3+:00p4+2/:10p`-v
*\00g1-\`*2*+\1-!+v>1+:20p55+00g>::::00g1--!\:20g+00g-:0`\3%!
`1\*!%3\`0:-\g02:\<^_@#-g01<:,$_^#`\0:-1,g3+**4!-g01g02!:+*3*
 |\/-

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<
*+\1-!+v>1+:20p55+00g>::::00g1--!\:20g+00g-:0`\3%!*\00g1-\`*2
-\g02:\<^_@#-g01<:,$_^#`\0:-1,g6+7+**4!-g01g02!:>#+<v*!%3\`0:
        |\/->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.

\$\endgroup\$
4
  • \$\begingroup\$ Care to provide an explanation? with all those gets and puts, its hard to follow \$\endgroup\$ Commented Jan 6, 2017 at 18:14
  • \$\begingroup\$ You're the only one to post after I added the bounty, if nobody else beats you I'll award you the 100. \$\endgroup\$ Commented Jan 9, 2017 at 19:52
  • \$\begingroup\$ @carusocomputing I know you were hoping for better than this, but there's still plenty of time, and it should get more notice once it's closer to the top of the featured list. \$\endgroup\$ Commented Jan 9, 2017 at 23:00
  • \$\begingroup\$ This is a cool answer in and of itself, it already has more up votes than mine; better is definitely not the right word. \$\endgroup\$ Commented Jan 10, 2017 at 14:54
3
\$\begingroup\$

05AB1E, 79 59 58 bytes

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

Try it online!.

Explanation:

"\  "×                                                     # 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=["  "]
3=["\"]
4=["\ "]
5=["\"," \"]
6=["\"," \ "]
7=["\"," \","  \"]
8=["\"," \","  \ "]
Etc...
\$\endgroup\$
3
\$\begingroup\$

Batch, 241 bytes

@echo off
set t=set s=
%t%
for /l %%i in (1,1,%1)do call %t% %%s%%
%t% !%s%! 
for /l %%i in (5,2,%1)do call:l 0
:l
%t%%s:\ = \%
%t%%s: /=/ %
%t%%s:!   =!\  %
%t%%s:   !=  /!%
%t%%s:\  !=\ /!%
if %1 gtr 0 %t%%s: =-%
echo %s:!=^|%

Note: Trailing space on line 5. Starts by building up a row of spaces, then adding cables as necessary, repeating to build towers to the desired height, ending by replacing any remaining spaces with road.

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

WinDbg, 312 bytes

r$t4=@$t0+4;.block{j3>@$t0'r$t5=1';r$t5=(@$t0-1)/2};f8<<16 L@$t4*@$t5 2d;f8<<16 L@$t4*(@$t5-1) 20;.for(r$t1=0;@$t1<@$t5;r$t1=@$t1+1){eb2000001+@$t4*@$t1 7c;e1fffffe+@$t4*(1+@$t1) 7c;j2<@$t0'.for(r$t2=@$t1;@$t2>=0;r$t2=@$t2-3){e2000002+@$t4*@$t1+@$t2 5c;e1fffffd+@$t4*(1+@$t1)-@$t2 2f}'};da/c@$t4 8<<16 L@$t4*@$t5

Input is done by setting the pseudo-register $t0.

I feel like there should be a way to combine the two for loops into one... maybe some other golfing opportunities too...

This one works by filling the entire area with road, then replacing all but the last row with space, and finally building the columns and cables.

r$t4 = @$t0+4;                                * Set width to input+4
.block                                        * Code block, needed for some reason...
{                                             * and .block+j is shorter than .if/.else
    j 3>@$t0                                  * If input is less than 3...
    '
        r$t5 = 1                              * ...set height to 1
    ';                                        * Implicit else...
        r$t5 = (@$t0-1)/2                     * ...set height to (input-1)/2
};
f 8<<16 L@$t4*@$t5 2d;                        * Fill area with -
f 8<<16 L@$t4*(@$t5-1) 20;                    * Fill all but last row with space
.for(r$t1=0; @$t1<@$t5; r$t1=@$t1+1)          * For each row
{
    eb 2000001+@$t4*@$t1 7c;                  * Build the left column with |
    e 1fffffe+@$t4*(1+@$t1) 7c;               * Build the right column (e is the same as last e* call, ie- eb)
    j 2<@$t0                                  * If input is more than 2...
    '
        .for(r$t2=@$t1; @$t2>=0; r$t2=@$t2-3) * ...Enumerate from counter back to 0
        {
            e 2000002+@$t4*@$t1+@$t2 5c;      * Build left cables with \
            e 1fffffd+@$t4*(1+@$t1)-@$t2 2f   * Build right cables with /
        }
    '
};
da /c@$t4 8<<16 L@$t4*@$t5                    * Print the string in lines of length width

Sample output of 1-15:

0:000> .for(r$t0=1;@$t0<10;r$t0=@$t0+1){.printf"%d\n",@$t0;r$t4=@$t0+4;.block{j3>@$t0'r$t5=1';r$t5=(@$t0-1)/2};f8<<16 L@$t4*@$t5 2d;f8<<16 L@$t4*(@$t5-1) 20;.for(r$t1=0;@$t1<@$t5;r$t1=@$t1+1){eb2000001+@$t4*@$t1 7c;e1fffffe+@$t4*(1+@$t1) 7c;j2<@$t0'.for(r$t2=@$t1;@$t2>=0;r$t2=@$t2-3){e2000002+@$t4*@$t1+@$t2 5c;e1fffffd+@$t4*(1+@$t1)-@$t2 2f}'};da/c@$t4 8<<16 L@$t4*@$t5}
1
Filled 0x5 bytes
Filled 0x0 bytes
02000000  "-|-|-"
2
Filled 0x6 bytes
Filled 0x0 bytes
02000000  "-|--|-"
3
Filled 0x7 bytes
Filled 0x0 bytes
02000000  "-|\-/|-"
4
Filled 0x8 bytes
Filled 0x0 bytes
02000000  "-|\--/|-"
5
Filled 0x12 bytes
Filled 0x9 bytes
02000000  " |\   /| "
02000009  "-|-\-/-|-"
6
Filled 0x14 bytes
Filled 0xa bytes
02000000  " |\    /| "
0200000a  "-|-\--/-|-"
7
Filled 0x21 bytes
Filled 0x16 bytes
02000000  " |\     /| "
0200000b  " | \   / | "
02000016  "-|--\-/--|-"
8
Filled 0x24 bytes
Filled 0x18 bytes
02000000  " |\      /| "
0200000c  " | \    / | "
02000018  "-|--\--/--|-"
9
Filled 0x34 bytes
Filled 0x27 bytes
02000000  " |\       /| "
0200000d  " | \     / | "
0200001a  " |  \   /  | "
02000027  "-|\--\-/--/|-"
10
Filled 0x38 bytes
Filled 0x2a bytes
02000000  " |\        /| "
0200000e  " | \      / | "
0200001c  " |  \    /  | "
0200002a  "-|\--\--/--/|-"
11
Filled 0x4b bytes
Filled 0x3c bytes
02000000  " |\         /| "
0200000f  " | \       / | "
0200001e  " |  \     /  | "
0200002d  " |\  \   /  /| "
0200003c  "-|-\--\-/--/-|-"
12
Filled 0x50 bytes
Filled 0x40 bytes
02000000  " |\          /| "
02000010  " | \        / | "
02000020  " |  \      /  | "
02000030  " |\  \    /  /| "
02000040  "-|-\--\--/--/-|-"
13
Filled 0x66 bytes
Filled 0x55 bytes
02000000  " |\           /| "
02000011  " | \         / | "
02000022  " |  \       /  | "
02000033  " |\  \     /  /| "
02000044  " | \  \   /  / | "
02000055  "-|--\--\-/--/--|-"
14
Filled 0x6c bytes
Filled 0x5a bytes
02000000  " |\            /| "
02000012  " | \          / | "
02000024  " |  \        /  | "
02000036  " |\  \      /  /| "
02000048  " | \  \    /  / | "
0200005a  "-|--\--\--/--/--|-"
15
Filled 0x85 bytes
Filled 0x72 bytes
02000000  " |\             /| "
02000013  " | \           / | "
02000026  " |  \         /  | "
02000039  " |\  \       /  /| "
0200004c  " | \  \     /  / | "
0200005f  " |  \  \   /  /  | "
02000072  "-|\--\--\-/--/--/|-"
\$\endgroup\$
2
\$\begingroup\$

Java 8, 423, 412 bytes

11 bytes saved thanks to Kritixi Lithos

golfed:

void f(int n){int i,j,k,t=n/2+n%2,u=t-2,q;char v=45;char[][]a=new char[t-1][n+4];for(char[]c:a)Arrays.fill(c,' ');a[u][0]=v;a[u][n+3]=v;for(q=0;q<t-1;q++){a[q][1]='|';a[q][n+2]='|';}for(i=t+1;i>1;i--){if((t-i)%3==0){k=u;for(j=i;j>1;j--)a[k--][j]='\\';}else a[u][i]=v;}for(i=n/2+2;i<n+2;i++){if((i-n/2-3)%3==0){k=u;for(j=i;j<n+2;j++)a[k--][j]='/';}else a[u][i]=v;}for(char[]w:a)System.out.println(new String(w));}

ungolfed:

void f(int n){
    int i,j,k,t=n/2+n%2,u=t-2;
    char v=45;
    char[][] a=new char[t-1][n+4];
    for (char[]c : a) Arrays.fill(c,' ');
    a[u][0]=v;
    a[u][n+3]=v;

    // left and right columns
    for (int q=0;q<t-1;q++){
        a[q][1]='|';
        a[q][n+2]='|';
    }
    // left part of base
    for (i=t+1;i>1;i--){
        if ((t-i)%3==0){
            k=u;
            for (j=i;j>1;j--)
                a[k--][j]='\\';
        }
        else a[u][i]=v;
    }
    // right part of base
    for (i=n/2+2;i<n+2;i++){
        if ((i-n/2-3)%3==0){
            k=u;
            for (j=i;j<n+2;j++)
                a[k--][j]='/';
        }
        else a[u][i]=v;
    }
    for (char[]w : a) System.out.println(new String(w));
}
\$\endgroup\$
2
  • \$\begingroup\$ You can golf this answer in many ways, first, you can have all your int declarations in one statement, something like int i,j,k,t=n/2+n%2,u=t-2,q=0 and instead of having char v="-"; you can use char v=45; and you can change the abc%xyz==0s to abc%xyz<1 (haven't tested it) \$\endgroup\$
    – user41805
    Commented Jan 11, 2017 at 19:30
  • \$\begingroup\$ @KritixiLithos thx! edited the first 2 the last one didn't work \$\endgroup\$
    – Bobas_Pett
    Commented Jan 12, 2017 at 0:43

Your Answer

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

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