Converter desenho de caixa ASCII em Unicode


16

Estou descaradamente postando uma solicitação de algo que eu realmente consideraria útil. A tarefa é pegar um desenho de caixa ascii arbitrário como este

     |
+----+----+
| state A +---+
+---------+   |
              |
         +----v----+
         | state B |
         +---------+

... e transformá-lo em algo mais bonito usando caracteres de desenho de caixa unicode, por exemplo

     │
╭────┴────╮
│ state A ├───╮
╰─────────╯   │
              │
         ╭────v────╮
         │ state B │
         ╰─────────╯

Em mais detalhes:

  • converter apenas + - | caracteres - outros caracteres devem permanecer inalterados
  • usar

    • DESENHOS DE CAIXA VERTICAL CLAROS (U + 2502) │
    • DESENHOS DE CAIXA HORIZONTAIS (U + 2500) ─
    • DESENHOS DA CAIXA ARCO CLARO PARA BAIXO E DIREITO (U + 256D) ╭
    • DESENHOS DA CAIXA ARCO CLARO PARA BAIXO E ESQUERDO (U + 256E) ╮
    • DESENHOS DA CAIXA ILUMINAR O ARCO PARA CIMA E ESQUERDA (U + 256F) ╯
    • DESENHOS DE CAIXA ARCO CLARO PARA CIMA E PARA A DIREITA (U + 2570) ╰
    • DESENHOS DE CAIXA CLARA VERTICAL E ESQUERDA (U + 2524) ┤
    • DESENHOS DE CAIXA CLARA VERTICAL E DIREITA (U + 251C) ├
    • DESENHOS DA CAIXA ILUMINAM-SE E HORIZONTAIS (U + 252C) ┬
    • DESENHOS DE CAIXA ILUMINAM-SE E HORIZONTAIS (U + 2534) ┴
    • DESENHOS DE CAIXA CLARA VERTICAL E HORIZONTAL (U + 253C) ┼

    • - sempre substituído por U + 2500

    • | sempre substituído por U + 2502
    • + é substituído por um caractere unicode que depende dos 4 caracteres norte, sul, leste e oeste (se existirem)
    • <e> são tratados como segmentos verticais da parede se estiverem ao norte ou sul de um + (para que você possa ter setas terminando nas paredes verticais de uma caixa)
    • v e ^ são tratados como segmentos de parede horizontal se leste ou oeste de um + (para que você possa ter setas terminando nas paredes horizontais de uma caixa)
    • + é tratado como um segmento de parede se norte, sul, leste ou oeste de um + (para que as linhas possam se conectar ao lado de um canto da caixa)

Casos de teste

+-+     +---+   +---+   |
| +--   |ABC|  -+   |  +++
+-+     ++--+   +---+  +-+
         |
         +--->
  |           +--+
+-v+   +---+  |  |  +-----+
|Hi|  ->   |  +^-+  |world<-----+
+--+   +---+   |    +-----+     |
               |                +--
   |
---+---
   |

Torna-se

╭─╮     ╭───╮   ╭───╮   │
│ ├──   │ABC│  ─┤   │  ╭┴╮
╰─╯     ╰┬──╯   ╰───╯  ╰─╯
         │
         ╰───>
  │           ╭──╮
╭─v╮   ╭───╮  │  │  ╭─────╮
│Hi│  ─>   │  ╰^─╯  │world<─────╮
╰──╯   ╰───╯   │    ╰─────╯     │
               │                ╰──
   │
───┼───
   │

O código mais curto vence!


1
Onde está a "interseção", ou seja, se +houver linhas em todo lugar?
Freira Furada

1
Você provavelmente significa Unicode em vez de UTF-8
Luis Mendo

1
Poderíamos ter alguns casos de teste? Especialmente para casos de borda, como onde duas caixas tocam em uma borda ou canto (ou esclarecimento de que isso nunca acontecerá).
Trichoplax # 25/16

2
Seria bom publicar as saídas necessárias para esses casos de teste.
manatwork 25/05

2
Ugh, eu estava apenas compondo uma resposta :-(
Neil

Respostas:


2

JavaScript (ES6), 236 bytes

s=>`
${s}
`.split`
`.map((l,i,a)=>l.replace(/[+-|]/g,(c,j)=>c>`-`?`│`:c>`+`?`─`:`┼┬├╭┤╮??┴?╰?╯`[g(a[i-1][j])+g(l[j-1],1)*2+g(l[j+1],1)*4+g(a[i+1][j])*8]),g=(c,f)=>(f?`+-^v`:`+<>|`).indexOf(c)<0).slice(1,-1).join`
`
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.