4-х полосный генератор пересечений


26

Вот ASCII-искусство пересечения с 4 путями:

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

(Обратите внимание, что горизонтальные дороги имеют 3 строки в высоту, а вертикальные дороги - 5 столбцов. Это из эстетических соображений из-за прямоугольного шрифта.)

Ваша задача - создать это искусство ASCII. Однако, как я уверен, вы все знаете, не на каждом перекрестке есть дорога, которая движется в каждом направлении. Это конкретное пересечение идет NESW, но некоторые пересечения могут идти, например NW:

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

Или это может пойти SWE:

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

Или это может даже пойти E, только одно направление (хотя вы вряд ли можете назвать это пересечением , но постарайтесь не быть чрезмерно педантичным):

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

Вам нужно написать программу или функцию, которая может легко генерировать любую из этих комбинаций. Более конкретно, ваша задача состоит в том, чтобы написать программу или функцию, которая принимает строку направлений, состоящую из NESWвходных данных, и выводит или возвращает это искусство ASCII пересечения с дорогами, указывающими в этих направлениях. Эти направления могут появляться в любом порядке, но вход не будет содержать любые символы , за исключением N, E, Sили W. Если хотите, вы можете запросить ввод данных в нижнем регистре, но вы должны указать это в своем ответе. Вы также можете предположить, что все входные данные будут содержать хотя бы одно направление.

В последнем примере были пробелы в каждой строке, потому что на запад нет дороги. Если у вас нет дороги, ведущей на запад, эти пробелы не обязательны. Это:

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

Также будет приемлемый вывод. Точно так же, если Nили Sушел, пустые строки там не являются обязательными. Разрешается одна конечная новая строка, а конечные пробелы допускаются, если результат визуально одинаков.

Вы можете принимать ввод и вывод в любом приемлемом формате, таком как STDIN / STDOUT, аргументы командной строки, файлы, аргументы функций / возвращаемые значения и т. Д.

Как обычно, это , поэтому постарайтесь получить максимально короткий ответ на любом языке, который вы используете!

Образец ввода-вывода:

NESW:

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


NS:

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

S:

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

EW:

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

SE:
+-----+-----
|     |     
|     |- - -
|     |     
+-----+-----
|  |  |
|     |
|  |  |
|     |
|  |  |

Разрешены ли конечные пробелы (например, если их нет E)? Разрешены ли начальные и конечные пустые строки, если нет Nили S?
Грег Мартин

@GregMartin Да, это разрешено. Смотрите мое редактирование.
DJMcMayhem

смутно связанные, вы напомнили мне об этом коде, который я в основном написал, для пересечения дорог в игре типа roguelike: github.com/CleverRaven/Cataclysm-DDA/blob/master/src/…
Sparr

Ответы:


10

Javascript (ES6), 190 187 185 байт

Это попытка построить этот художественный символ ASCII для каждого символа путем итерации матрицы 17x15. Поэтому выход всегда состоит из 15 рядов из 17 столбцов с пересечением дорог по центру посередине.

p=>eval("for(y=15,s='';y--;s+=`\n`)for(x=17;x--;)s+=' |-+'[+[a=y>4,b=y<10,c=x>4,d=x<12].every((c,i)=>c|p.search('SNEW'[i])+1)&&!((z=x-8||y&1|a&b)&&z*z-9)+2*!((z=y-7||x&1|c&d)&&z*z-4)]")

Разоблаченный и прокомментированный

for(y = 15, s = ''; y--; s += `\n`)   // iterate on y, from 14 to 0 / append line feeds
  for(x = 17; x--;)                   // iterate on x, from 16 to 0
    s += ' |-+' [                     // append next character to string
      +[ a = y > 4,                   // a = outside South area?
         b = y < 10,                  // b = outside North area?
         c = x > 4,                   // c = outside East area?
         d = x < 12 ]                 // d = outside West area?
      .every((c, i) =>                // for each area, see if either:
        c |                           //   - we're currently outside it
        p.search('SNEW' [i]) + 1      //   - or it's an allowed area (p = function param.)
      )                               // if all tests pass, add a:
      &&                              //   - vertical bar (encoded as 1) if:
      !((z = x - 8 || y & 1 | a & b)  //     - x=8, y is even and we're not in the middle
      && z * z - 9)                   //     - OR x=5 OR x=11 (<=> (x-8)*(x-8) = 9)
      + 2 *                           //   - horizontal bar (encoded as 2) if:
      !((z = y - 7 || x & 1 | c & d)  //     - y=7, x is even and we're not in the middle
      && z * z - 4)                   //     - OR y=5 OR y=9 (<=> (y-7)*(y-7) = 4)
    ]                                 // (vertical + horizontal = 3, which leads to '+')

матрица

Ниже приведена матрица с координатами, используемыми в коде.

матрица

демонстрация

Следующий фрагмент позволяет попробовать любую конфигурацию дороги.

let f =
p=>eval("for(y=15,s='';y--;s+=`\n`)for(x=17;x--;)s+=' |-+'[+[a=y>4,b=y<10,c=x>4,d=x<12].every((c,i)=>c|p.search('SNEW'[i])+1)&&!((z=x-8||y&1|a&b)&&z*z-9)+2*!((z=y-7||x&1|c&d)&&z*z-4)]")

function update() {
  document.getElementById("o").innerHTML = f(document.getElementById("s").value);
}
update();
<input id="s" size=4 value="NSEW" oninput="update()">
<pre id="o" style="font-size:9px"></pre>


8

PowerShell v3 +, 226 204 192 191 байт

param([char[]]$a)($n=0..4|%{($x=' '*5*($b=87-in$a))+('|  |  |',($w='|     |'))[$_%2]})*(78-in$a)
($z=($y='-'*5)*$b+"+$y+"+$y*($c=69-in$a))
$x+$w
'- - -'*$b+$w+'- - -'*$c
$x+$w
$z
$n*(83-in$a)

Принимает ввод как строку заглавных букв, явно преобразует ее в charмассив. Создает сегмент «Север» с помощью цикла от 0до 4. Каждый цикл создает строку из 5 пробелов (если W/ 87присутствует во входных данных), сохраняет ее в $x, затем либо | |(хранит в $w), либо | | |, в зависимости от того, четны мы или нет. Этот массив строк сохраняется $nи умножается на N/ 78является -inвходом. Это будет определять, $nнаходится ли на конвейере или нет.

Затем мы строим среднюю часть. Первая строка $z- это «верх» маршрута восток-запад, использующий ту же логику для Wи E/ 69и заключенный в скобки, чтобы также разместить копию на конвейере. Мы используем вспомогательную переменную $yдля сохранения байта на -----разделах.

Следующая строка - это просто соответствующее количество пробелов (т. Е. $x) Конкатенированных строк с трубами правильной ширины (т. Е. $w). Затем, в середине полосатой линии, снова Wи Eлогики и $wзаполнении в середине. Потом $x+$wи $zснова.

Наконец, поскольку южная дорога совпадает с северной, включите $nтрубопровод, если S/ 83есть -in $a.

Все эти результирующие строки собираются из конвейера и вывод неявен в конце выполнения программы. Злоупотребляет Write-Outputразделителем по умолчанию для вставки новой строки между элементами.


Примеры

PS C:\Tools\Scripts\golfing> .\4-way-intersection.ps1 'EN'
|  |  |
|     |
|  |  |
|     |
|  |  |
+-----+-----
|     |
|     |- - -
|     |
+-----+-----

PS C:\Tools\Scripts\golfing> .\4-way-intersection.ps1 'SNW'
     |  |  |
     |     |
     |  |  |
     |     |
     |  |  |
-----+-----+
     |     |
- - -|     |
     |     |
-----+-----+
     |  |  |
     |     |
     |  |  |
     |     |
     |  |  |

PS C:\Tools\Scripts\golfing> .\4-way-intersection.ps1 'WE'
-----+-----+-----
     |     |
- - -|     |- - -
     |     |
-----+-----+-----

4

C ++ 317 280 276 байт

int i(char*j){for(int y=0;y<15;++y)for(int x=0;x<18;++x)putchar(x-17?y<5&!strchr(j,'N')|y>9&!strchr(j,'S')|x<5&!strchr(j,'W')|x>11&!strchr(j,'E')?' ' :x==5|x==11?y==5|y==9?'+':'|':y==5|y==9?x==5|x==11?'+':'-':x==8&y%2|y==7&x%2?' ':x==8&(y/5-1)?'|':y==7&(x/6-1)?'-':' ':'\n');}

Ungolfed:

int i (char* j)
{
  for (int y=0; y<15; ++y)
    for (int x=0; x<18; ++x)
      putchar(
        x-17 ? 
        y<5 & !strchr(j,'N') |
        y>9 & !strchr(j,'S') |
        x<5 & !strchr(j,'W') |
        x>11 & !strchr(j,'E') ? ' ' :
        x==5 | x==11 ? y==5 | y==9 ? '+' : '|' : 
        y==5 | y==9 ? x==5 | x==11 ? '+' : '-' : 
        x==8 & y%2 | y==7 & x%2 ? ' ' : 
        x==8 & (y / 5 - 1) ? '|' :
        y==7 & (x / 6 - 1) ? '-' :
        ' ' : '\n');
}

1
Святые вложенные троичные операторы, Бэтмен!

Мы всегда знали, что они будут хороши для чего-то.
Дэвид Шварц

Замена strchrс indexбудет сбрить несколько больше. Определите xи yвместе наружные forпетли.
Войцех Мигда

2

Python 3, 186 байт

S=' -- -  -- -  --'
lambda d:'\n'.join(S[r//4:15*('W'in d):3]+'||+  -  -| -  -  -||+'[r%4::3]+S[r//4:15*('E'in d):3]for r in[0,1,0,1,0,6,1,9,1,6,0,1,0,1,0][5-5*('N'in d):10+5*('S'in d)])

Анонимная лямбда, называемая строкой указаний, например, «NWS»

Объяснение следовать


2

сед 234

s,$,@+-----+@|     |@!     !@|     |@+-----+@,
:l;tl
/N/s,^,#,;t
:r
/S/s,@$,#,;t
/E/{s,!@,|- - -@,;s,+@,+-----@,g}
/W/{s,@!,@- - -|,;s,@+,@-----+,g;s,@|,@     |,g}
y,@!NSEW,\n|    ,
q
:
s,#,@|  |  |@|     |@|  |  |@|     |@|  |  |,
tr

Он просто строит разные части, если в строке есть правильный символ.
Использует @вместо \nи \nвозвращается в конце.
Северная и южная части идентичны, поэтому я использую то, что в основном является функцией для их вставки.


2

Пакетный, 351 344 341 байт

@echo off
set/pi=
set t=     
if not "%i:n=%"=="%i%" call:l
set l=-----
set r=%l%
if "%i:w=%"=="%i%" set l=%t%
if "%i:e=%"=="%i%" set r= 
for %%s in (%l%+-----+%r% "%t%|%t%|" "%l:--=- %|%t%|%r:--=- %" "%t%|%t%|" %l%+-----+%r%) do echo %%~s
if "%i:s=%"=="%i%" exit/b
:l
call :m
call :n
:n
echo %t%^|%t%^|
:m
echo %t%^|  ^|  ^|

Примечание. Строка set t=заканчивается пятью пробелами, а строка if "%i:e=%"=="%i%" set r=заканчивается пробелами. Принимает регистронезависимый ввод из STDIN. Редактировать: Сохранение 7 байтов путем исключения dпеременной. Сохранено 3 байта с помощью forцикла для печати средней части. Если вместо этого мне разрешены отдельные параметры командной строки, то для 326 319 316 байт:

@echo off
set t=%*
set/an=s=e=w=5,%t: ==%=0
set t=     
call:%n%
set r=-----%t%
call set l=%%r:~%w%,5%%
call set r=%%r:~%e%%%
for %%s in (%l%+-----+%r% "%t%|%t%|" "%l:--=- %|%t%|%r:--=- %" "%t%|%t%|" %l%+-----+%r%) do echo %%~s
goto %s%
:0
call :1
call :2
:2
echo %t%^|%t%^|
:1
echo %t%^|  ^|  ^|
:5

1

Python 2, 290 байт

t,s,r,i=[],[],range(5),raw_input()
for n in r:t+=[" "*5*("W"in i)+"|  "+("|"," ")[n%2]+"  |"]
exec"s+=['-'*5];s[:1]+=' '*5,;"*2;s[:2]+="- - -",
if"N"in i:print'\n'.join(t)
print'\n'.join([s[n]*("W"in i)+("|     |","+-----+")[`n`in"04"]+s[n]*("E"in i)for n in r])
if"S"in i:print'\n'.join(t)

m,t,s=[],[],[]может быть m=t=s=[].
Yytsi

range(5)может быть сохранен в переменную и использован дважды, вместо ввода range(5)дважды.
Yytsi

Для чего m?
Оливер Ни

@TuukkaX, по какой-то причине t=s=[]все испортилось
Даниэль

1
Теперь я уверен, что все m=t=s=[]они указывают на одну и ту же ссылку.
Yytsi


1

Pyth ( 385 380 373 353 байта)

Golfed:

K"     |  |  |\n     |     |\n"?}\Nz++KKPKk?}\Wz?}\Ez+++*5\-*2+\+*5\-"\n     |     |\n- - -|     |- - -\n     |     |\n"+*5\-*2+\+*5\-++*2+*5\-\+"\n     |     |\n- - -|     |\n     |     |\n"*2+*5\-\+?}\Ez+"     "+*2+\+*5\-"\n     |     |\n     |     |- - -\n     |     |\n     +-----+-----"++"     +-----+\n"*3"     |     |\n""     +-----+"?}\Sz++KKPKk

Ungolfed:

K"     |  |  |\n     |     |\n"  //sets K to first two lines of north
?}\Nz                            //if north in the input 
  ++KKPK                         //then: return K + K + K[:-1]
  k                              //else: return ""
?}\Wz                            //if West in input
  ?}\Ez                          //if East in input
    +++*5\-*2+\+*5\-"\n     |     |\n- - -|     |- - -\n     |     |\n"+*5\-*2+\+*5\-    //then: Return E+W string
    ++*2+*5\-\+"\n     |     |\n- - -|     |\n     |     |\n"*2+*5\-\+         //else: Return W string
  ?}\Ez                          //else: if east in input (and not W)
    +"     "+*2+\+*5\-"\n     |     |\n     |     |- - -\n     |     |\n     +-----+-----" //return East without West String
    ++"     +-----+\n"*3"     |     |\n""     +-----+" \\Return empty left and right intersection
?}\Sz                            //if south in input
  ++KKPK                         //return north string
  k                              //return ""

Конечно, если есть какие-либо улучшения, пожалуйста, сообщите мне.

Сохранено 5 байтов благодаря Maltysen

Вы можете попробовать это здесь


Вы можете использовать Kвместо, Nа затем при назначении в первый раз, вам не нужно использовать =, сохраняя вам байт
Maltysen

также, N[:-1]этоP
Maltysen

0

Groovy (274 байта)

Ungolfed

r{
    l->
    t='+-----+'
    s='     ';
    m='|     |'
    x='-----'
    v=(1..5).collect{s}
    nsR=(1..5).collect{[s,((it%2)?'|  |  |':m),s]}
    ewR=[x,s,'- - -',s,x]
    c=[l[3]?ewR:v,[t,m,m,m,t],l[1]?ewR:v]
    (l[0]?nsR.collect{it}:[])+((0..4).collect{x->((0..2).collect{y->c[y][x]})}​)​+​(l[2]?nsR.collect{it}:[])
}

Golfed

def i(l) {t='+-----+';s='     ';m='|     |';x='-----';v=(1..5).collect{s};n=(1..5).collect{[s,((it%2)?'|  |  |':m),s]};e=[x,s,'- - -',s,x];c=[l[3]?e:v,[t,m,m,m,t],l[1]?e:v];(l[0]?n.collect{it}:[])+((0..4).collect{x->((0..2).collect{y->c[y][x]})}​)​+​(l[2]?n.collect{it}:[])}

Попробуйте это: https://groovyconsole.appspot.com/script/5082600544665600

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.