19
\$\begingroup\$

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.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Suggestion for future challenge: plot the first figure (the one with increasing meanders), allowing graphical output \$\endgroup\$
    – Luis Mendo
    Jun 27, 2018 at 14:13
  • 3
    \$\begingroup\$ Isn't it n left turns? \$\endgroup\$
    – LiefdeWen
    Jun 27, 2018 at 14:35
  • 1
    \$\begingroup\$ @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) \$\endgroup\$ Jun 27, 2018 at 19:45
  • \$\begingroup\$ @LiefdeWen It depends on where you start counting. I think it's n+1 when looking at the examples, especially between the single segments.. \$\endgroup\$ Jun 27, 2018 at 19:54

6 Answers 6

6
\$\begingroup\$

Charcoal, 52 34 33 bytes

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

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

Nθ

Input the size of the meander.

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

FN

Loop over the desired number of meanders.

F⊗⊕θ«

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.

\$\endgroup\$
5
\$\begingroup\$

APL (Dyalog Classic), 108 101 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!

\$\endgroup\$
1
  • \$\begingroup\$ I can confidently say I have never seen an APL answer like this one. \$\endgroup\$
    – Razetime
    Sep 9, 2020 at 10:42
2
\$\begingroup\$

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);
}
\$\endgroup\$
2
\$\begingroup\$

Python 3, 371 354 346 328 298 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]))
\$\endgroup\$
0
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$

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.