4-ходовий генератор перехрестя


26

Ось ASCII-мистецтво чотиристороннього перехрестя:

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

(Зверніть увагу, як горизонтальні дороги мають 3 ряди у висоту, тоді як вертикальні дороги шириною 5 колон. Це з естетичних міркувань через прямокутний шрифт.)

Ваше завдання - створити це мистецтво ASCII. Однак, як я впевнений, ви всі знаєте, не кожне перехрестя має дорогу, яка від'їжджає в кожному напрямку. Цей перехрест іде NESW, але деякі перехрестя можуть йти, наприклад NW:

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

Або може піти SWE:

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

Або навіть може йти Eлише одним напрямком (хоча це перехрестя навряд чи можна назвати , але намагайтеся уникати надто педантичного):

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

Вам потрібно написати програму або функцію, яка може легко генерувати будь-яку з цих комбінацій. Більш конкретно, ваше завдання полягає в тому, щоб написати програму або функцію, яка займає рядок напрямків, що складається з NESWвхідних даних і видає або повертає це мистецтво ASCII перехрестя з дорогами, що вказують у цих напрямках. Ці напрямки можуть з'являтися в будь-якому порядку, але вхід НЕ буде містити будь-які символи , за винятком N, E, Sабо W. Якщо вам подобається, ви можете попросити натомість вводити малі літери, але ви повинні вказати це у своїй відповіді. Ви також можете припустити, що всі вхідні дані будуть містити принаймні один напрямок.

Останній приклад мав провідні пробіли на кожній лінії, оскільки на захід немає дороги. Якщо у вас немає дороги на захід, ці провідні простори необов’язкові. Це:

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

Було б також прийнятним результатом. Точно так же, якщо Nабо Sнемає, порожні рядки там місця НЕ є обов'язковими. Допускається одна затримка нового рядка, і пробіли дозволені до тих пір, поки вихід візуально однаковий.

Ви можете приймати введення та вихід у будь-якому розумному форматі, наприклад, STDIN / STDOUT, аргументи командного рядка, файли, аргументи функції / значення повернення тощо.

Як завжди, це , тому постарайтеся отримати якомога коротший відповідь будь-якою мовою, якою ви користуєтесь!

Зразок IO:

NESW:

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


NS:

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

S:

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

EW:

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

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

Чи дозволені також пробіли для трейлінгу (якщо таких немає E, наприклад)? Чи дозволені провідні та проміжні порожні рядки, якщо немає Nчи S?
Грег Мартін

@GregMartin Так, це дозволено. Дивіться мою редакцію.
DJMcMayhem

смутно пов'язане, ви нагадали мені цей код, про який я здебільшого писав, для перехресть доріг у шахрайській
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');}

Безголівки:

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

Пітон 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

sed 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 байт)

Гольф:

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

Безголівки:

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 байт завдяки Малтісену

Ви можете спробувати тут


ви можете використовувати Kзамість цього, Nа потім при першому призначенні вам не доведеться використовувати =байт, економлячи байт
Maltysen

також, N[:-1]єP
Мальтісен

0

Groovy (274 байт)

Безумовно

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}:[])
}

Гольф

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.