Gerador de interseção de 4 vias

26

Aqui está uma arte ASCII de uma interseção de quatro vias:

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

(Observe como as estradas horizontais têm 3 linhas de altura, enquanto as estradas verticais têm 5 colunas de largura. Isso ocorre por razões estéticas, devido à fonte retangular.)

Seu desafio é produzir essa arte ASCII. No entanto, como tenho certeza de que todos sabem, nem todo cruzamento tem uma estrada que sai em todas as direções. Essa interseção específica ocorre NESW, mas algumas interseções podem ocorrer, por exemplo NW:

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

Ou pode ser SWE:

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

Ou pode até seguir E, apenas uma única direção (embora você dificilmente possa chamar isso de interseção , mas tente evitar ser excessivamente pedante):

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

Você precisa escrever um programa ou função que possa gerar facilmente qualquer uma dessas combinações. Mais especificamente, seu desafio é escrever um programa ou função que siga uma sequência de instruções, consistindo em NESW, como entrada e produza ou retorne essa arte ASCII de um cruzamento com estradas apontando nessas direções. Essas direções podem aparecer em qualquer ordem, mas a entrada não irá conter quaisquer caracteres, exceto para N, E, S, ou W. Se desejar, você pode solicitar que as entradas sejam minúsculas, mas você deve especificar isso na sua resposta. Você também pode assumir que todas as entradas conterão pelo menos uma direção.

O último exemplo tinha espaços à esquerda em cada linha, porque não há estrada indo para o oeste. Se você não tem uma estrada que vai para o oeste, esses espaços à esquerda são opcionais. Este:

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

Também seria uma saída aceitável. Da mesma forma, se Nou Sse foi, linhas vazias no local são opcionais. Uma nova linha final é permitida e os espaços finais são permitidos desde que a saída seja visualmente a mesma.

Você pode receber entrada e saída em qualquer formato razoável, como STDIN / STDOUT, argumentos de linha de comando, arquivos, argumentos de função / valores de retorno, etc.

Como de costume, isso é , então tente obter a resposta mais curta possível em qualquer idioma que você usar!

IO de amostra:

NESW:

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


NS:

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

S:

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

EW:

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

SE:
+-----+-----
|     |     
|     |- - -
|     |     
+-----+-----
|  |  |
|     |
|  |  |
|     |
|  |  |
DJMcMayhem
fonte
Os espaços à direita também são permitidos (se não houver E, por exemplo)? As linhas em branco à esquerda e à direita são permitidas se não houver Nou S?
Greg Martin
@GregMartin Sim, são permitidos. Veja minha edição.
DJMcMayhem
vagamente relacionados, você me lembrou este código Eu, principalmente, escreveu, por cruzamentos em um jogo roguelike: github.com/CleverRaven/Cataclysm-DDA/blob/master/src/...
Sparr

Respostas:

10

Javascript (ES6), 190 187 185 bytes

Esta é uma tentativa de criar esse caractere de arte ASCII por caractere, iterando em uma matriz 17x15. Portanto, a saída é sempre composta por 15 linhas de 17 colunas com a interseção das estradas centralizadas no meio.

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)]")

Ungolfed e comentou

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 '+')

Matriz

Abaixo está a matriz com as coordenadas usadas no código.

matriz

Demo

O seguinte snippet permite tentar qualquer configuração de estrada.

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>

Arnauld
fonte
8

PowerShell v3 +, 226 204 192 191 bytes

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)

Recebe a entrada como uma sequência de letras maiúsculas e a lança explicitamente como uma charmatriz. Constrói o segmento "Norte" via loop de 0para 4. Cada loop, constrói uma sequência de 5 espaços (se W/ 87está presente na entrada), armazena isso em $x, então | |(armazenado em $w) ou | | |, dependendo se estamos par ou ímpares no momento. Essa matriz de seqüências de caracteres é armazenada $ne multiplicada por N/ 78é -ina entrada. Isso determinará se $né colocado no pipeline ou não.

Então, construímos a parte do meio. A primeira linha $zé o "topo" da rota leste-oeste, usando a mesma lógica para We E/ 69e cercada por parênteses para também colocar uma cópia no pipeline. Usamos a variável auxiliar $ypara salvar um byte nas -----seções.

A próxima linha é apenas o número apropriado de espaços (ou seja, $x) concatenados com os tubos de largura correta (ou seja $w). Em seguida, a linha listrado meio, novamente com We Elógica e $wrecheio no meio. Então $x+$we $znovamente.

Finalmente, como a estrada sul é a mesma do norte, coloque $nno oleoduto se S/ 83é -in $a.

Todas essas cadeias resultantes são coletadas do pipeline e a saída é implícita no final da execução do programa. Abusa o Write-Outputdelimitador padrão para inserir uma nova linha entre elementos.


Exemplos

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'
-----+-----+-----
     |     |
- - -|     |- - -
     |     |
-----+-----+-----
AdmBorkBork
fonte
4

C ++ 317 280 276 bytes

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');
}
David Schwartz
fonte
1
Operadores ternários aninhados, Batman!
Sempre soubemos que eles serviriam para alguma coisa.
David Schwartz
Substituir strchrpor indexirá reduzir um pouco mais. Definir xe yjuntos forloops externos .
Wojciech Migda 11/03/19
2

Python 3, 186 bytes

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)])

Um lambda anônimo chamado com uma sequência de instruções, por exemplo, 'NWS'

Explicação a seguir

RootTwo
fonte
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

Ele apenas cria as diferentes partes se o caractere adequado estiver em jogo.
Usa em @vez de \ne \nretorna novamente no final.
As partes norte e sul são idênticas, então eu uso o que é basicamente uma função para inseri-las.

Riley
fonte
2

Lote, 351 344 341 bytes

@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%^|  ^|  ^|

Nota: A linha set t=termina em cinco espaços e a linha if "%i:e=%"=="%i%" set r=termina em um espaço. Recebe entrada sem distinção entre maiúsculas e minúsculas de STDIN. Editar: salvou 7 bytes, eliminando a dvariável. Salva 3 bytes usando um forloop para imprimir a seção do meio. Se eu tiver permissão para separar parâmetros de linha de comando, em seguida, para 326 319 316 bytes:

@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
Neil
fonte
1

Python 2, 290 bytes

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)
Daniel
fonte
m,t,s=[],[],[]poderia ser m=t=s=[].
Yytsi 7/09/16
range(5)pode ser salvo em uma variável e usado duas vezes, em vez de digitar range(5)duas vezes.
Yytsi 7/09/16
Para que serve m?
Oliver Ni
@TuukkaX, por algum motivo, ter t=s=[]messes tudo para cima
Daniel
1
Agora estou certo de que, ao fazê-lo m=t=s=[], todos apontam para a mesma referência.
Yytsi 8/09/16
1

GolfScript, 154 bytes

{a?1+}:x;'-'5*:e;' '5*:b;"+"e+"+"+:f;{b'|'b'|'b n}:k;{'W'x{e}{b}if\'E'x{e}{}if n}:y;{x{b"|  |  |
"+:c k c k c}{}if}:z;1/:a;'N'z f y k'|'b+'|'+ y k f y'S'z

Experimente online!

FedeWar
fonte
Impressionante, não faço ideia de como isso não tem votos.
Magic Octopus Urn
1

Pitão ( 385 380 373 353 bytes)

Golfe:

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 ""

Claro, se houver alguma melhoria, por favor me diga.

Economizou 5 bytes graças a Maltysen

Você pode tentar aqui

Nick o codificador
fonte
você pode usar Kem vez de Ne, em seguida, ao atribuir, pela primeira vez, você não tem que usar um =, poupando-lhe um byte
Maltysen
também, N[:-1]éP
Maltysen
0

Groovy (274 bytes)

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

Golfe

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

Experimente: https://groovyconsole.appspot.com/script/5082600544665600

Urna de polvo mágico
fonte