Generate a one-path maze

12

1

Given an odd integer N (5 <= N <= 51), generate a maze with side length N that follows the following requirements:

The maze must be composed of the characters | - and +. It must use the | character as a vertical wall, the - character as a horizontal wall, and if that wall turns, the character + should be used.

The width of the path must be one character.

The maze must turn at least four times.

The maze must have outer walls, that break at two points: the start and the end.

The maze must consist of one non-breaking path, from the start to the end.

For example, the following is a valid maze: (N = 5)

+---+
|   |
| | |
  |  
--+--

And for N = 7:

--+---+
  |   |
| | | |
| | | |
| | | |
|   |  
+---+--

Remember, this is , so the code with the fewest number of bytes wins.

Oliver Ni

Posted 2016-10-30T20:50:26.833

Reputation: 9 650

9

It's not a maze, it's a labyrinth http://english.stackexchange.com/a/144103/199361

– edc65 – 2016-10-30T20:54:51.333

@edc65 Actually, its nighter. – Oliver Ni – 2016-10-30T21:23:03.433

I'm not clear on "The maze must consist of one non-breaking path, from the start to the end." Does this mean that there is only one-path and it's from start to end, or that the number of paths from start to end is 1? Can there be other paths with dead ends? Separate loops? – xnor – 2016-10-30T22:39:24.797

Odd integer should be <50, <=49 – pinkfloydx33 – 2016-10-31T00:41:18.817

2@edc65 I assume OP means neither. – orlp – 2016-10-31T10:15:05.930

@edc65 Welcome to [tag:labyrinth]! – Erik the Outgolfer – 2016-10-31T17:29:04.257

Do both the width AND height have to be size N? I could comply to all your specified requirements, but only have either one size N and the other not. – Kevin Cruijssen – 2016-11-10T07:49:53.243

@KevinCruijssen Yes. – Oliver Ni – 2016-11-10T15:23:09.233

Answers

10

Jelly, 36 35 34 33 32 bytes

2*×5H_2Bị⁾ |
_3”-ẋ”+;;Çsẋ2U3¦ṁµY

TryItOnline!

Builds a nighter™ the other way around to the examples like:

+---- |
|     |
| ----+
|     |
+---- |
|     |
| ----+

How?

2*×5H_2Bị⁾ | - Link 1, pipes & spaces: n      e.g. 7
2*           - 2 raised to the nth power      e.g. 128
  ×5         - multiply by 5                  e.g. 640
    H        - halve                          e.g. 320
     _2      - subtract 2                     e.g. 318
       B     - convert to binary              e.g. [1,0,0,1,1,1,1,1,0]
        ị    - index into (1-based)
         ⁾ | - char list " |"                 e.g. " ||     |"

_3”-ẋ”+;;Çsẋ2U3¦ṁµY - Main link: n            e.g. 7
_3                  - n - 3                   e.g. 4
  ”-                - char list "-"
    ẋ               - repeat                  e.g. "----"
     ”+             - char list "+"
       ;            - concatenate             e.g. "+----"
         Ç          - call last link (1) as a monad
        ;           - concatenate             e.g. "+---- ||     |"" 
          s         - split into chunks of n  e.g. ["+---- |","|     |"]
           ẋ2       - repeat 2 times          e.g. ["+---- |",
                                                    "|     |",
                                              +-->  "+---- |",
                                              |     "|     |"]
              3¦    - apply to index 3:       |
             U      -    upend                +---  "| ----+"
                ṁ   - mould like n (i.e. repeat to fill)
                 µ  - monadic chain separation
                  Y - join with line feeds

(each byte saved involved fairly non-trivial changes, see the edit history if you're interested, although I just noticed that Link 1 is the same byte count as the more conventional repeat and join: _2⁶ẋ“ ||“|”j)

Jonathan Allan

Posted 2016-10-30T20:50:26.833

Reputation: 67 804

5

JavaScript (ES6), 86 92 116

Almost a kolmogorv-complexity challenge ... With a little lateral thinking (inspired by @Neil's answer), it can be very shorter. Just turn 90°

n=>`|${s=' '[r='repeat'](n-2)}|
| ${h='-'[r](n-3)}+
|${s}|
+${h} |
`[r](n).slice(n*~n)

Test

f=
n=>`|${s=' '[r='repeat'](n-2)}|
| ${h='-'[r](n-3)}+
|${s}|
+${h} |
`[r](n).slice(n*~n)

function update() {
  var i=+I.value
  O.textContent=i&1? f(i): 'even'
}

update()
<input id=I value=7 min=5 max=49 step=2 type=number oninput="update()"><pre id=O><pre>

edc65

Posted 2016-10-30T20:50:26.833

Reputation: 31 086

@Neil wow every day I learn something new. Thanks – edc65 – 2016-10-30T22:03:12.653

Amazing! I count 86 bytes, btw

– ETHproductions – 2016-10-31T16:40:53.863

@ETHproductions right. Thanks – edc65 – 2016-10-31T17:39:25.733

4

Batch, 216 bytes

@echo off
set s=
for /l %%i in (4,1,%1)do call set s=-%%s%%
set b= %s:-= %
set r=! %s%+
set s=+%s% !
call:e
for /l %%i in (5,2,%1)do call:l
:l
echo ^|%b%^|
set t=%s%
set s=%r%
set r=%t%
:e
echo %s:!=^|%

|s are awkward in Batch so I reflected rotated the examples instead.

Neil

Posted 2016-10-30T20:50:26.833

Reputation: 95 035

Do you mean rotate 90°? I tried it and saved a lot in JS. Thanks again – edc65 – 2016-10-30T22:28:31.853

@edc65 I was originally going for a reflection, but you're right in that I ended up with a rotation instead. – Neil – 2016-10-31T00:39:20.007

3

PHP, 99 Bytes

up to down gates

for($s=str_pad("\n| ",$c=$argv[1],"-")."+\n";$i++<$c;)echo$i%2?$s=strrev($s):str_pad("|",$c-1)."|";

PHP, 157 Bytes

left right gates

<?=($p=str_pad)($n="\n",$c=1+$argv[1],"+---").$p($n,$c-1,"|   ")." #|"[$c%4].str_repeat($p($n,$c,"| "),$c-5).$p($n,$c-1,"  | ")."|# "[$c%4].$p($n,$c,"--+-");

@Titus Thank you for minialize the bytes

Jörg Hülsermann

Posted 2016-10-30T20:50:26.833

Reputation: 13 026

1save 3 bytes by assigning `$n="\n" – Titus – 2016-10-30T22:55:21.240

1$p("",$c*($c-4),...) instead of str_repeat(...,$c-4) (-2) – Titus – 2016-10-30T22:59:04.480

1... and 3 more bytes with $p($n,$c-1," | ") instead of $p("\n ",$c-1," | ") – Titus – 2016-10-30T23:03:18.750

1unnecessary parens at ($c)%4 (-2), remove $g from the code (-1) – Titus – 2016-10-30T23:11:02.873

1up-to-down-version; unnecessary 3rd parameter for str_pad (-4), $c=$argv[1]-1 instead of ($c=$argv[1])-1, <=$c instead of <$c and $c instead of $c-1 (-3) – Titus – 2016-10-30T23:21:22.223

1... and, if a leading newline is accepted: undo the other tip, replace ($c=$argv[1])-1 with $c=$argv[1], "| " with "\n| ", "+" with "+\n" and remove ,"\n" (-2) – Titus – 2016-10-30T23:31:52.550

@Titus left right Thank You! the space after the new line is necessary for the gate line and I could it not change and replace str_repeat with str_pad I have count the same bytes – Jörg Hülsermann – 2016-10-30T23:32:48.280

1Yes, but you can move the space to the beginning of the padding string and cut one space from the end. – Titus – 2016-10-30T23:34:25.163

@Titus for the up an down version you have seen that I am use strrev? And in my opinion that can not work with your suggestion with the leading new lines – Jörg Hülsermann – 2016-10-30T23:44:03.697

1My new $s has a leading and a trailing newline; that´s why you don´t need a newline for the other string anymore. – Titus – 2016-10-30T23:46:35.250

@Titus okay that have not realize in the moment – Jörg Hülsermann – 2016-10-30T23:56:16.710

Use real newline instead of \n. It will save you one byte twice. – Blackhole – 2016-10-31T18:10:00.290

3

JavaScript (ES6), 87 bytes

A recursive function. Outputs a few trailing spaces.

f=(n,w=n,s=' -'[n&1].repeat(w-3),c='|+'[n&1])=>n?`
`+(n&2?c+s+' |':'| '+s+c)+f(n-1,w):s

Test

f=(n,w=n,s=' -'[n&1].repeat(w-3),c='|+'[n&1])=>n?`
`+(n&2?c+s+' |':'| '+s+c)+f(n-1,w):s

console.log(f(9));

Arnauld

Posted 2016-10-30T20:50:26.833

Reputation: 111 334

Oh wow, I just tried recursion and ended up 9 bytes longer. Well done :-) – ETHproductions – 2016-10-31T15:37:45.373

2

Ruby 72 or 69 bytes

Lambda function. As shown, returns a newline-separated string. Delete the *$/ to return an array of strings.

->n{(1..n).map{|i|"|%s |+%s || %s|| %s+"[i%4*5,5]%(" -"[i%2]*(n-3))}*$/}

Draws a maze rotated 90 degrees from the examples. For each line, a format string is selected (for example +%s | for the 1st line (there is no zeroth line) and the %s is substituted with an appopriate number of - or spaces using the % operator (equivalent to sprintf, but shorter.)

Level River St

Posted 2016-10-30T20:50:26.833

Reputation: 22 049

2

Java 7, 228 bytes

String c(int n){String a="+x |",b="|y|\n",x,y,r=x=y="";int i=0;for(;i++<n-2;){x+=i>1?"-":"";y+=" ";}a=a.replace("x",x);b=b.replace("y",y);for(i=0;i<n;i++)r+=i%4<1?a+"\n":(i-2)%4==0?new StringBuffer(a).reverse()+"\n":b;return r;}

Used a similar vertical output as @JonathanAllan's Jelly answer.

Ungolfed & test code:

Try it here.

class M{
  static String c(int n){
    String a = "+x |",
           b = "|y|\n",
           x = "",
           y = "",
           r = "";
    int i = 0;
    for (; i++ < n-2;){
      x += i > 1
            ? "-"
            : "";
      y += " ";
    }
    a = a.replace("x", x);
    b = b.replace("y", y);
    for(i = 0; i < n; i++){
      r += i % 4 < 1
            ? a+"\n"
            : (i-2) % 4 == 0
               ? new StringBuffer(a).reverse()+"\n"
               : b;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(7));
    System.out.println();
    System.out.println(c(25));
  }
}

Output:

+---- |
|     |
| ----+
|     |
+---- |
|     |
| ----+


+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |
|                       |
| ----------------------+
|                       |
+---------------------- |

Kevin Cruijssen

Posted 2016-10-30T20:50:26.833

Reputation: 67 575

excuse, but Given an odd integer N (5 <= N <= 51), generate a maze with side length N. You seem to have a different top and bottom side length for yours... – Destructible Lemon – 2016-11-09T23:38:46.410

@DestructibleWatermelon I read past that. My code still complied to all rules/requirements though. Ah well, I've roll-backed to my original answer which used the same width as height. – Kevin Cruijssen – 2016-11-10T15:55:56.637

1

Python 2, 89 bytes

def f(n):x='+'+'-'*(n-3)+' |';y='|'+' '*(n-2)+'|';print'\n'.join(([x,y,x[::-1],y]*n)[:n])

repl.it

Builds an internal wall, x, like '+---- |' and an internal corridor, y, like '| |'
Then builds a list of [x,y,x[::-1],y] (x[::-1] is a reverse of x)
Then repeats that list n times (as a single list), with *n, and truncates it to the first n entries, with (...)[:n], joins the list with line feeds, with '\n'.join(...), and prints the result.

Jonathan Allan

Posted 2016-10-30T20:50:26.833

Reputation: 67 804

1

Racket 187 bytes

Using display pattern by @JonathanAllan

(let*((u "+---- |")(v "|     |")(sr(λ(s)(list->string(reverse(string->list s)))))(g #t)(d displayln)
(p(λ()(d(if g u(sr u)))(set! g(if g #f #t)))))(for((i(ceiling(/ n 2))))(p)(d v))(p))

Ungolfed:

(define (f n)
  (let* ((sr (lambda(s)
               (list->string
                (reverse
                 (string->list s)))))
         (u "+---- |")
         (v "|     |")
         (g #t)
         (d displayln)
         (p (lambda()
              (d (if g u (sr u)))
              (set! g (if g #f #t)))))
    (for ((i (ceiling (/ n 2))))
      (p)
      (d v))
    (p)))

Testing:

(f 10)

Output:

+---- |
|     |
| ----+
|     |
+---- |
|     |
| ----+
|     |
+---- |
|     |
| ----+

rnso

Posted 2016-10-30T20:50:26.833

Reputation: 1 635

1

T-SQL, 123/79 bytes

Golfed:

DECLARE @i INT=7

,@ INT=0z:PRINT
STUFF(CHOOSE(@%4+1,'+- |','|  |','| -+','|  |'),3,0,REPLICATE(IIF(@%2=0,'-',' '),@i))SET
@+=1IF @<@i GOTO z

Ungolfed:

DECLARE @i INT = 9

DECLARE @i INT=7

,@ INT=0
z:
  PRINT 
    STUFF(CHOOSE(@%4+1,'+- |','|  |','| -+','|  |'),3,0,
      REPLICATE(IIF(@%2=0,'-',' '),@i))
  SET @+=1
IF @<@i GOTO z

If you cheat and only make a narrow labyrinth the script can be golfed down to 79 bytes:

Golfed:

DECLARE @i INT = 9

,@ INT=0z:PRINT CHOOSE(@%4+1,'+- |','|  |','| -+','|  |')SET @+=1IF @<@i GOTO z

Ungolfed:

DECLARE @i INT = 9

,@ INT=0
z:
  PRINT CHOOSE(@%4+1,'+- |','|  |','| -+','|  |')
  SET @+=1
IF @<@i GOTO z

Fiddle for the long answer

t-clausen.dk

Posted 2016-10-30T20:50:26.833

Reputation: 2 874

1

GNU sed 140 bytes

Includes +1 for -r

s/1{5}//
h
s/^/+---+\n|   |\n| | |\n  |  \n--+--/
/1/!b
:w
s/^..(..)[^$]*/\1&/gm
s/11//
/1/bw
G
:h
s/\n[^\n]*\n([^\n]*\n)/&\1/
s/1//
/1/bh

Try it Online!

Takes input in unary (see this consensus).

Basically it inserts the size 5 maze, then appends the 2nd and 3rd character of each line to the beginning as many times as needed. Then duplicates the 3rd line (alternating | and ) as many times as needed.

The only interesting thing that I used is the m option on line 6 which allows ^ and $ to match respectively (in addition to the normal behavior) the empty string after a newline, and the empty string before a newline.

Riley

Posted 2016-10-30T20:50:26.833

Reputation: 11 345

0

JavaScript (ES6), 96 bytes

f=(n,w=n-3)=>(h="-".repeat(w),n&2?`+${h} |`:`| ${h}+`)+(n>1?`
| ${" ".repeat(w)}|
`+f(n-2,w):"")

I was hoping recursion would turn out to be the shortest route, and apparently it is...

ETHproductions

Posted 2016-10-30T20:50:26.833

Reputation: 47 880