# Draw an ASCII meandering curve

For the purpose of this question a meandering curve is one that follows the general direction from left to right, but makes repeatedly n+1 turns at 90 degrees to the left and then n+1 turns to the right (for n>0).

In fact the meander itself will have n segments.

The turns are denoted with +.

The width of the meanders (the distance between two +) is 3 at the horizon (---) and 1 at the vertical (|)

Here are the single segments a meandering curve with sizes n from 1 to 5:

                                                           +-------------------+
|                   |
+---------------+   |   +-----------+   |
|               |   |   |           |   |
+-----------+   |   +-------+   |   |   |   +---+   |   |
|           |   |   |       |   |   |   |   |   |   |   |
+-------+   |   +---+   |   |   +---+   |   |   |   +---+   |   |   |
|       |   |   |   |   |   |       |   |   |   |           |   |   |
+---+   +---+   |   +---+   |   |   +-------+   |   |   +-----------+   |   |
|   | 1     |   | 2         |   | 3             |   | 4                 |   | 5
---+   +-------+   +-----------+   +---------------+   +-------------------+   +


## Challenge:

Given two positive numbers n and m, draw m segments of a meandering curve with size n. You can write a full program or a function.

## Input:

n > 0 The size of the curve

m > 0 Number of segments to draw

## Output:

An ASCII representation of the meandering curve.

## Examples:

n = 3
m = 2
+-----------+   +-----------+
|           |   |           |
|   +---+   |   |   +---+   |
|   |   |   |   |   |   |   |
+---+   |   |   +---+   |   |
|   |           |   |
-----------+   +-----------+   +

n = 2
m = 5
+-------+   +-------+   +-------+   +-------+   +-------+
|       |   |       |   |       |   |       |   |       |
+---+   |   +---+   |   +---+   |   +---+   |   +---+   |
|   |       |   |       |   |       |   |       |   |
-------+   +-------+   +-------+   +-------+   +-------+   +

n = 4
m = 4
+---------------+   +---------------+   +---------------+   +---------------+
|               |   |               |   |               |   |               |
|   +-------+   |   |   +-------+   |   |   +-------+   |   |   +-------+   |
|   |       |   |   |   |       |   |   |   |       |   |   |   |       |   |
|   +---+   |   |   |   +---+   |   |   |   +---+   |   |   |   +---+   |   |
|       |   |   |   |       |   |   |   |       |   |   |   |       |   |   |
+-------+   |   |   +-------+   |   |   +-------+   |   |   +-------+   |   |
|   |               |   |               |   |               |   |
---------------+   +---------------+   +---------------+   +---------------+   +


## Winning criteria:

This is , so the shortest code in bytes in each language wins. Please explain your code, if you have time to do it.

• Suggestion for future challenge: plot the first figure (the one with increasing meanders), allowing graphical output – Luis Mendo Jun 27 '18 at 14:13
• Isn't it n left turns? – LiefdeWen Jun 27 '18 at 14:35
• @LuisMendo Yes, when I composed the 1-5 image, I realised that there is a good challenge within it - given a list L of positive integers, compose a meandering curve with segments of size L(i) – Galen Ivanov Jun 27 '18 at 19:45
• @LiefdeWen It depends on where you start counting. I think it's n+1 when looking at the examples, especially between the single segments.. – Galen Ivanov Jun 27 '18 at 19:54

# Charcoal, 5234 33 bytes

Ｎθ↶ＦＮＦ⊗⊕θ«+⊖⊗×⊕﹪κ²∨↔⁻θ∧κ⊖κ¹¿›κθ↷↶


Try it online! Link is to verbose version of code. Explanation:

Ｎθ


Input the size of the meander.

↶


Pivot upwards as the drawing starts at the right and works left.

ＦＮ


Loop over the desired number of meanders.

Ｆ⊗⊕θ«


Loop over the segments of the meander.

+


Print a +.

∨↔⁻θ∧κ⊖κ¹


Compute the kth element of the list $n, n, n-1, n-2 ... 3, 2, 1, 1, 1, 2, 3, ... n$.

⊖⊗×⊕﹪κ²...


Alternate between doubling and quadrupling the lengths since the horizontal lines are twice as long, but decrement the result before printing to take account of the + that was just printed.

¿›κθ↷↶


Pivot appropriately for the next segment.

# APL (Dyalog Classic), 108101 95 bytes

' -+|'[⊃,/⎕⍴⊂b/⍨3 1⍴⍨≢⍉b←⌽⊖2@a⌽1@(a←⊂0 0)⊖0,⊃{((4|-⊖⍉⍵),⍉¯2↑⍉⍵)⍪(2/⍪⍳2),¯2↑⍵}/⎕⍴⊂46 16 47⊤⍨3⍴4]


Try it online!

• I can confidently say I have never seen an APL answer like this one. – Razetime Sep 9 '20 at 10:42
• @Razetime thanks – ngn Sep 9 '20 at 16:39

# Python 3, 371354346328298 290 bytes

import sys
v=sys.argv
s=int(v[1])
n=range
r="   |"
t="   +---"
h="-"*4
e=" "*4
def C(l):print(l*int(v[2]))
for i in n(-(-s//2)):q=s-i+~i;R=r*i;C(R+t+h*q+"+"+R);C(R+r+e*q+R+r)
for i in n(s//2):q=s//2-i;R=r*~-q;w=2*i+s%2;C(R+t+h*~-w+"+"+r*(q+((i>0)|s%2)));C(R+e*-~w+R+2*r)
C(h*~-s+"---+   +")


-20B Thanks to ceilingcat

Try it online!

Pre-golfing:


import sys

import math

def draw_curve(curve_size, curve_count, out=sys.stdout):
for i in range(math.ceil(curve_size / 2)):
for j in range(curve_count):
out.write("   |" * i)
out.write("   +---")
out.write("----" * (curve_size - 2 * i - 1))
out.write("+")
out.write("   |" * i)

out.write("\n")

for j in range(curve_count):
out.write("   |" * (i + 1))
out.write("    " * (curve_size - 2 * i - 1))
out.write("   |" * (i + 1))

out.write("\n")

for i in range(curve_size // 2):
for j in range(curve_count):
out.write("   |" * (curve_size // 2 - i - 1))
out.write("   +---")
out.write("----" * (2 * i - (0 if curve_size % 2 else 1)))
out.write("+")
out.write("   |" * (curve_size // 2 - i + (1 if i or curve_size % 2 else 0)))

out.write("\n")

for j in range(curve_count):
out.write("   |" * (curve_size // 2 - i - 1))
out.write("    " * (2 * i + (2 if curve_size % 2 else 1)))
out.write("   |" * (curve_size // 2 - i + 1))

out.write("\n")

for j in range(curve_count):
out.write("----" * (curve_size - 1))
out.write("---+   +")

if __name__ == "__main__":
draw_curve(int(sys.argv[1]), int(sys.argv[2]))


# C (gcc), 559 540 523 511 494 484 476 468 456 447 443 bytes

#define S memset
l,o,p,q,r;g(c,d,n)char*d;{q=~c;for(p=n*2;q%2*p;bcopy(n*2-p--?"|   |":"+---+",d-q*l*p,5));p=n-1;c--%2?S(S(d-~l-r*!q,45,r++)-2*l,45,r=n*4-1),d[r*=q-1]='|',d[r-l]=d[r+l]=43,p&&g(c%4,memcpy(q?d+p*4+l:d-l-n*4,q?"+   |":"|   +",5),p):p&&g(c%4,d,p,d[-q]=45,d[q*=l]=43,*(d-=q*(n*2*l-l-2)-2)=32);}f(n,m){char b[(o=n-~n)*(l=n*4+5)];g(0,strcpy(S(S(b,32,l*o),45,l)+l-6,"+   +"),n);for(o*=m;b[o/m*l-1]=0,o--;o%m||puts(""))printf(b+o/m*l);}


Try it online!

Slightly less golfed

#define S memset
l,o,p,q,r;
g(c,d,n)char*d;{
q=~c;
for(p=n*2;q%2*p;bcopy(n*2-p--?"|   |":"+---+",d-q*l*p,5));
p=n-1;
c--%2?
S(S(d-~l-r*!q,45,r++)-2*l,45,r=n*4-1),
d[r*=q-1]='|',
d[r-l]=d[r+l]=43,
p&&
g(c%4,memcpy(q?d+p*4+l:d-l-n*4,q?"+   |":"|   +",5),p)
:
p&&
g(c%4,d,p,d[-q]=45,d[q*=l]=43,*(d-=q*(n*2*l-l-2)-2)=32);
}
f(n,m){
char b[(o=n-~n)*(l=n*4+5)];
g(0,strcpy(S(S(b,32,l*o),45,l)+l-6,"+   +"),n);
for(o*=m;b[o/m*l-1]=0,o--;o%m||puts(""))
printf(b+o/m*l);
}


# Dash - POSIX Shell script, 528 bytes

Try it online!

golfed:

Y=0;p(){ eval A${1}_${2}='$3';};for Z in seq$2;do case $1 in 1)L='r3 u1 r3 d1';;2)L='r7 u1 l3 u1 r7 d3';;3)L='r11 u3 l3 d1 l3 u3 r11 d5';;4)L='r15 u5 l7 d1 r3 d1 l7 u5 r15 d7';;5)L='r19 u7 l11 d3 r3 u1 r3 d3 l11 u7 r19 d9' esac;for A in$L;do d(){ C=-;case "$1" in r*)X=$((X+1));;l*)X=$((X-1));;u*)Y=$((Y+1));C=\|;;d*)Y=$((Y-1));C=\|;;esac;p$X $Y$2 $C;};for I in seq${A#*[a-z]};do d $A;done;d$A +;done;done;for Y in seq 20 -1 0;do for X in seq 0 99;do eval F="\"$A{X}_{Y}\"";L={L}{F:- };done;echo "L";L=;done  ungolfed: #!/bin/sh # helper function for emulating an array, the language does not know it p(){ eval A{1}_{2}='3';} Y=0 for Z in seq 2;do # define the possible patterns: # list="direction+count direction+count ..." case 1 in 1)L='r3 u1 r3 d1';; 2)L='r7 u1 l3 u1 r7 d3';; 3)L='r11 u3 l3 d1 l3 u3 r11 d5';; 4)L='r15 u5 l7 d1 r3 d1 l7 u5 r15 d7';; 5)L='r19 u7 l11 d3 r3 u1 r3 d3 l11 u7 r19 d9' esac for A in L;do # helper function for going into needed direction # and plot char into array d(){ C=- case "1" in r*)X=((X+1));; l*)X=((X-1));; u*)Y=((Y+1));C=\|;; d*)Y=((Y-1));C=\|;; esac p X Y 2 C } # write char as long as needed into array, # append in the same direction as last element the '+' for I in seq {A#*[a-z]};do d A done d A + done done # echo the array linewise for Y in seq 20 -1 0;do for X in seq 0 99;do eval F="\"$A${X}_${Y}\"";L=${L}${F:- }
done
echo "\$L";L=
done


# Python 2, 261 bytes

n,m=input()
i=0;h,v,p,s=map(tuple,'hv+ ');k=p;R=[h+s]
exec"h,v=v,h;R=zip(*R)[::-1];R=[s+R[0][:-1]+k+h+p]+[s+r+s+v for r in R[1:]]+[h*2*i+h+p+s+p];i+=1;k=v;"*n
for r in[[(3-i%2*2)*{h[0]:'-',v[0]:'|'}.get(c,c)for i,c in enumerate(l)]*m for l in R]:print''.join(r)


Try it online!

5 bytes from this tip by Esolanging Fruit.