Leia o texto ASCII-Art


34

Inspirado por Golf me um alfabeto ASCII , do qual esse desafio é (quase) um inverso direto.


Tarefa:

Pegue uma sequência de texto de arte ASCII e produza o conteúdo do texto como texto ASCII comum.


Entrada:

Sequência de texto de arte ASCII.

A entrada conterá apenas instâncias de caracteres ASCII #, espaços e 4 ou 5 novas linhas (uma nova linha à direita é opcional). Todas as linhas têm o mesmo comprimento. (Ou seja, a última letra da arte ASCII é preenchida com espaços à direita.) Você pode usar algum outro caractere ASCII imprimível em vez da #entrada, se desejar.

A entrada conterá letras da arte A-ZASCII e espaços da arte ASCII (um bloco de espaço em branco 5x5). Sem pontuação. Há apenas uma linha de texto de arte ASCII (5 linhas reais). Não haverá espaços de arte ASCII à direita ou à direita, nem espaços de arte ASCII adjacentes.

O tamanho da letra é de 5x5 caracteres. Há um espaço de 1x5 entre cada letra. O espaço entre as palavras é um bloco 5x5 de espaço em branco (+ 1x5 de espaço em cada lado, porque é apenas mais uma letra). Não haverá espaço 1x5 no final ou no início, apenas entre as letras da arte ASCII.


Saída:

String contendo o texto como caracteres ASCII A-Z+ espaços. A saída também pode estar em minúscula, se for mais fácil para a sua solução. Caso misto também é permitido.


As cartas de arte ASCII:

 ###  ####   ###  ####  ##### #####  ###  #   # ##### ##### #   # #     #   #
#   # #   # #   # #   # #     #     #     #   #   #     #   #  #  #     ## ##
##### ####  #     #   # ####  ####  #  ## #####   #     #   ###   #     # # #
#   # #   # #   # #   # #     #     #   # #   #   #   # #   #  #  #     #   #
#   # ####   ###  ####  ##### #      ###  #   # ##### ###   #   # ##### #   #

#   #  ###  ####   ###  ####   ###  ##### #   # #   # #   # #   # #   # #####
##  # #   # #   # #   # #   # #       #   #   # #   # #   #  # #   # #     # 
# # # #   # ####  #   # ####   ###    #   #   #  # #  # # #   #     #     #  
#  ## #   # #     #  #  #   #     #   #   #   #  # #  ## ##  # #    #    #   
#   #  ###  #      ## # #   #  ###    #    ###    #   #   # #   #   #   #####

O espaço:

     |
     | A 5x5 square of spaces.
     | (Padded with |s to make it appear in this post.)
     |
     |

Exemplos:

Entrada:

#   # ##### #     #      ###        #   #  ###  ####  #     #### 
#   # #     #     #     #   #       #   # #   # #   # #     #   #
##### ####  #     #     #   #       # # # #   # ####  #     #   #
#   # #     #     #     #   #       ## ## #   # #   # #     #   #
#   # ##### ##### #####  ###        #   #  ###  #   # ##### #### 

Saída: HELLO WORLD

Entrada:

 ###   ###   ###  ##### #####
#   # #     #   #   #     #  
#####  ###  #       #     #  
#   #     # #   #   #     #  
#   #  ###   ###  ##### #####

Saída: ASCII

Entrada:

####  ####   ###   ### 
#   # #   # #   # #    
####  ####  #     #  ##
#     #     #   # #   #
#     #      ###   ### 

Saída: PPCG


Isso é , então a resposta mais curta em bytes vence.


10
Estou pensando a solução para isso pode envolver algum tipo de hash de função ...
Neil

6
Recompensa de mim se você fizer isso convertendo a entrada em uma imagem e resolver isso usando o processamento de imagem! (A solução deve ser também claro golfed)
Stewie Griffin

3
Se for de ajuda a alguém: a segunda linha, a quarta linha ou a coluna do meio das letras podem ser descartadas sem perder informações relevantes.
Martin Ender

1
@JungHwanMin Hmm. Acho que não, porque isso não seria um texto de arte ASCII muito legível para humanos .
Steadybox

1
@ JonathanAllan Acho que também ficaria bem.
Steadybox

Respostas:


13

Geléia ,  50 44  42 bytes

ỴZ;6/UOḂḅ7‘ị“¥ŒƲVĊ⁾|W£⁼³ƭÇuʋụzḢĖ0ḢẆẠØsĠỌỊ»

Experimente online! (observe que o argumento não requer a nova linha principal, mas como as novas e iniciais não têm efeito, eu incluí uma para tornar a sequência multilinha mais legível por humanos)

Os resultados são caso misto (conforme permitido pelo OP em um comentário ).

Quão?

Divide em novas linhas, transpõe e une sub-fatias de (até) seis para obter as representações de caracteres e reverte cada uma (igualando a conversão base posterior para o caractere final de comprimento 25 a todos os outros de comprimento 30). Em seguida, mapeia '#'e ' 'para um e zero, respectivamente, usando o fato de que '#'um ordinal ímpar enquanto ' 'um igual. Lê cada um como se fosse um número sete básico. Efetivamente pega o módulo 81 de cada (para gerar 27 valores exclusivos para os 27 casos possíveis) e, finalmente, indexa em uma "string mágica" com os caracteres corretos nos índices corretos (a indexação do módulo é usada com uma string mágica de comprimento 81 para salvar 2 bytes).

Aqui está a "string mágica" que eu criei junto com um padrão de regex (sem distinção entre maiúsculas e minúsculas) que ele precisava corresponder (eu adicionei "ed" para torná-lo o comprimento 81):

 ' affectedly Azerbaijan rewaxed naganas jiujitsudankly pase UVB freqHaarlemcoacted'
'^ ..f...e.....z......a..r.w.x...n.g......iuj....d..kly.p.s...vb....qh.....m.o.ct.*'

Como tal, pode ser compactado, procurando onze sub-fatias como palavras no dicionário de Jelly (a maioria delas usa o padrão de espaço inicial):

' affectedly Azerbaijan rewaxed naganas jiujitsudankly pase UVB freqHaarlemcoacted'
 ^          ^          ^       ^       ^        ^     ^    ^   ^    ^      ^

o que resulta na cadeia comprimida Jelly, “¥ŒƲVĊ⁾|W£⁼³ƭÇuʋụzḢĖ0ḢẆẠØsĠỌỊ»

O restante do código funciona da seguinte maneira:

ỴZ;6/UOḂḅ7‘ị“...» - Main link: multi-line string, s   e.g. HI as the #s and spaces
Ỵ                 - split on new lines                     ["#   # #####","#   #   #  ","#####   #  ","#   #   #  ","#   # #####"] (each is actually a list)
 Z                - transpose                              ["#####","  #  ","  #  ","  #  ","#####","     ","#   #","#   #","#####","#   #","#   #"] (each is actually a list)
   6/             - six-wise reduce by
  ;               -     concatenation                      ["#####  #    #    #  #####     ","#   ##   #######   ##   #"] (each is actually a list)
     U            - upend (reverse each)                   ["     #####  #    #    #  #####","#   ##   #######   ##   #"] (each is actually a list)
                  -     note: all except the last will be length 30 and like "     ...", which will become [0,0,0,0,0,...], while the last will be length 25 without those five leading zeros.
      O           - cast to ordinals ('#' -> 35, ' '-> 32) [[32,32,...],[35,32,...]]
       Ḃ          - modulo 2 ('#' -> 1, ' ' -> 0)          [000001111100100001000010011111, 1000110001111111000110001] (each is actually a list)
        ḅ7        - convert from base 7 (vectorises)       [223498370543967315553, 191672428080864454753] (these are now integers)
          ‘       - increment                              [223498370543967315554, 191672428080864454754]
                  -  (modulo 81 these would be [68, 41])
           ị      - index into (modulo & 1-indexed):                        
            “...» -     the "magic string" described above ' affectedly Azerbaijan rewaxed naganas jiujitsudankly pase UVB freqHaarlemcoacted'
                                                           "Hi"                                   41^                        68^

14

Python 2 , 405 335 234 182 171 bytes

lambda s,j=''.join:j(' QPVXU_O__FBLK_JMD_CSYZWIENH_AG___TR'[int(j(`ord(y)%2`for y in j(s.split('\n')[x][i:i+5]for x in range(5))),2)%13836%37]for i in range(0,len(s)/5,6))

Experimente online!


Finalmente menor que JS


Inteligente uso do módulo, mas não ajuda o pensamento pode, deve haver uma maneira de fazer: [0,2,3,7,...]e ' UBGOTA...dividi-lo, e usar algum tipo de mapeamento. 0:' ',2:'U',3:'V'...parece tão longo ,,, há tantos :'',. (Eu sei que você tinha algo semelhante no post original, mas com números muito longos.
Stewie Griffin

1
@StewieGriffin é melhor agora
ovs 07/04

11

JavaScript (ES6), 204 186 184 182 bytes

Economizou 18 bytes graças a Neil
Economizou 2 bytes graças a ETHproductions
Economizou 2 bytes graças a YairRand

Demolir:

  • Tabela de pesquisa de 42 bytes
  • 162 144 142 140 bytes de código
s=>(a=s.split`
`)[0].replace(/.{6}/g,(_,n)=>' H_JM__WDCSORLU___QKG_P_AFT_N_EI_XBV____YZ'[[0,1,2,4].reduce((p,r,i)=>p+='0b'+a[r].substr(n,5).replace(/./g,c=>1^1-c)<<i*6,0)%178%69%43])

Demo


1
Você pode salvar um monte de bytes usando (a=s.split`\n`)[0].replace(/......?/g,com substr(n,5)e sem o joincurso.
711 Neil

Eu acho que você pode salvar um byte com c=>0|c>' ', e outro comp+='0b'+...
ETHproductions

Conforme mencionado por @Steadybox na seção Comentário do desafio, a \nentrada de entrada é inválida. No entanto, acho que você pode usar o modelo literal com nova linha real como entrada, assim como você está fazendo no splitmétodo.
Arjun #

1
@ DobbyTheFree-Elf Eu realmente poderia usar um literal de modelo - que aliás prejudicaria a legibilidade por causa da citação principal. Mas adicionar uma restrição à forma como os dados de entrada são formatados antes de serem passados ​​para a função está fora de tópico, IMHO (desde que o conteúdo real da entrada seja válido).
Arnauld

1
@ DobbyTheFree-Elf Acho que meu comentário foi um pouco ambíguo e posso ter entendido um pouco a pergunta que eu estava respondendo. O uso \nde uma literal de cadeia no site da chamada no código é bom, porque a cadeia real que é passada para a função inclui apenas o caractere de nova linha, não \` and n . Passing a string that contains \ `e ncomo caracteres adjacentes separados não seria aceitável.
Steadybox

9

Bash + ImageMagick + Tesseract , 161 bytes

Eu queria tentar a abordagem sugerida por @ stewie-griffin e usei o bash + ImageMagick (para converter uma string em uma imagem) e o Tesseract (para fazer o OCR). Aqui está o meu código, que funciona para o caso de teste 'HELLO WORLD', mas falha nos outros. Talvez alguns ajustes nos parâmetros (fonte, tamanho da fonte, kerning, espaçamento) ajudem.

convert -font Courier-Bold -pointsize 8 -interline-spacing -3 -kerning -3 label:"$(</dev/stdin)" -bordercolor White -border 5%x20% png:- | tesseract stdin stdout

Basta copiar e colar a arte ascii na linha de comando após executar o comando. Termine sua entrada pressionando ^ d.

Saída atual para os casos de teste:

  • OLÁ MUNDO: OLÁ MUNDO
  • ASCII: H5511
  • PPCG: PPOG

6

Scala, 184 181 bytes

Uma solução de string + módulo mágico baseada em hashCode:)

(a:String)=>a.split("\n").map(_.grouped(6)map(_.take(5))toArray).transpose.map(l=>"Q__WLUY_XOI_ZN_GEFR_P__JKBMV_S__ __C__D__H_T__A"(Math.abs(l.mkString.hashCode)%106%79%47))mkString

Experimente online (Scalafiddle)

Mais legível:

(a:String) => a.split("\n")
                .map(_.grouped(6)map(_.take(5))toArray)
                .transpose
                .map ( l => 
                    "Q__WLUY_XOI_ZN_GEFR_P__JKBMV_S__ __C__D__H_T__A"(
                        Math.abs(l.mkString.hashCode)%106%79%47
                    )
                )mkString

Explicações

  • A String inicial (arte ASCII) é dividida em 5 linhas (altura do caractere ASCII)
  • Cada linha é dividida em elementos de 6 caracteres (largura do caractere ASCII + 1 espaço)
  • Apenas os 5 primeiros caracteres são mantidos (o espaço no final é inútil)
  • As linhas são transpostas (cada caractere ASCII é representado como uma sequência de 25 caracteres (5x5), contendo um '#'ou ' ')
  • Cada representação de caractere ASCII (sequência) é convertida em String e um código de hash absoluto é calculado para essa String (absoluto necessário por causa do próximo módulo)
  • 3 módulos consecutivos ( % 106 % 79 % 47) são aplicados para associar um número ∈ [0; 47[para cada caractere ASCII (ver explicações abaixo)
  • Este número é usado como um índice da string mágica

Como obter a corda mágica?

Primeiro, eu representei todas as letras assim:

case class Letter(letter: Char, ascii: Seq[Char])

Então, criei um alfabeto contendo representações ASCII de todos os caracteres:

Exemplo:

 ### 
#   #  
#####  
#   #  
#   #

torna-se

Letter('A', " ### #   #######   ##   #") // 25 characters from top-left to bottom-right

Para cada letra, um código hash absoluto foi calculado (todos os códigos hash são distintos):

val codes = alphabet.map { case Letter(l, a) => (l, Math.abs(a.mkString.hashCode)) }
// codes: Seq[(Char, Int)] = List(( ,253243360), (A,380997542), (B,1221679148), (C,1573119535), (D,307929190), (E,858088672), (F,857996320), (G,750155628), (H,897290147), (I,1518088099), (J,928547488), (K,1184149391), (L,519601059), (M,741735953), (N,2139154001), (O,1625960980), (P,1307658950), (Q,92382816), (R,1221771494), (S,1689301359), (T,1515228067), (U,1390718627), (V,386730851), (W,733134481), (X,628338619), (Y,23919695), (Z,2081560145))

Tentei diminuir cada código, mas sempre respeitando o fato de que cada código deve ser único (a lista agrupada pelo código deve ter 27 elementos, 1 para cada letra). Então, eu tentei o primeiro módulo de 200:

val mod = (1 to 200).find(modulo => codes.map { case (a,b) => (a, b % modulo) }.groupBy(_._2).size==27).get

Encontrei 106como o primeiro módulo a ser aplicado:

val codes2 = codes.map { case (l, c) => (l, c%mod) }
val codes = codes2
// codes: Seq[(Char, Int)] = List(( ,32), (A,46), (B,104), (C,35), (D,38), (E,16), (F,96), (G,94), (H,41), (I,89), (J,102), (K,71), (L,83), (M,105), (N,13), (O,56), (P,20), (Q,0), (R,18), (S,29), (T,43), (U,5), (V,27), (W,3), (X,87), (Y,53), (Z,91))

Repeti as etapas anteriores até o menor módulo. Eu encontrei :

  • 79
  • 47
  • 44
  • 42.

Nota: O último módulo que escolhi ( 47) não é o menor aqui:

  • Encontrei 44, mas se eu tivesse escolhido 44, a sequência mágica teria o tamanho 44 (em vez de 47), mas teria que escrever %106%79%47%44(13 caracteres em vez de %106%79%47= 10 caracteres). Assim, em bytes, o código deveria ter o mesmo tamanho que o que obtive
  • Também há 42, mas o código deveria ter 1 byte a mais do que o que recebi

Em seguida, apliquei o módulo consecutivo ( % 79 % 47) até o último codes, para obter os códigos definitivos associados a cada letra:

codes: Seq[(Char, Int)] = List(( ,32), (A,46), (B,25), (C,35), (D,38), (E,16), (F,17), (G,15), (H,41), (I,10), (J,23), (K,24), (L,4), (M,26), (N,13), (O,9), (P,20), (Q,0), (R,18), (S,29), (T,43), (U,5), (V,27), (W,3), (X,8), (Y,6), (Z,12))

Finalmente, para construir a string mágica:

val initialMap = (0 until 47).map(i => (i, '_')).toMap
val codesMap = codes.map(i => (i._2, i._1)).toMap

val magicString = (initialMap ++ codesMap).toSeq.sortBy(_._1).map(_._2).mkString
// magicString: String "Q__WLUY_XOI_ZN_GEFR_P__JKBMV_S__ __C__D__H_T__A"

Exemplo: a letra Aacima está associada a 46 ( 380997542 % 106 % 79 % 47) e o 46º elemento da string mágica é A :)

Casos de teste

// assign function to f
val f = (a:String)=>a.split("\n").map(_.grouped(6)map(_.take(5))toArray).transpose.map(l=>"Q__WLUY_XOI_ZN_GEFR_P__JKBMV_S__ __C__D__H_T__A"(Math.abs(l.mkString.hashCode)%106%79%47))mkString

OLÁ MUNDO :

val asciiArt = """|#   # ##### #     #      ###        #   #  ###  ####  #     #### 
                  |#   # #     #     #     #   #       #   # #   # #   # #     #   #
                  |##### ####  #     #     #   #       # # # #   # ####  #     #   #
                  |#   # #     #     #     #   #       ## ## #   # #   # #     #   #
                  |#   # ##### ##### #####  ###        #   #  ###  #   # ##### #### """.stripMargin

f(asciiArt)    // HELLO WORLD

ASCII:

val asciiArt = """| ###   ###   ###  ##### #####
                  |#   # #     #   #   #     #  
                  |#####  ###  #       #     #  
                  |#   #     # #   #   #     #  
                  |#   #  ###   ###  ##### #####""".stripMargin

f(asciiArt)    // ASCII

PPCG:

val asciiArt = """|####  ####   ###   ### 
                  |#   # #   # #   # #    
                  |####  ####  #     #  ##
                  |#     #     #   # #   #
                  |#     #      ###   ### """.stripMargin

f(asciiArt)    // PPCG

Edições

  • Salvo 3 bytes por remoção .antes map, toArrayemkString

3

PHP, 294 bytes

<?$l=" 00000YE00G0000R000A0Q0000C0BW000K00000000000LT00000J00000000MU0000Z0000DI000000V0000000P00H0000ONF000S00X";preg_match_all("#(.{5})\s#s","$_GET[0] ",$t);for($i=0;$i<$c=count($a=$t[1])/5;$i++)$s.=$l[bindec(strtr($a[$i].$a[$i+$c].$a[$i+2*$c].$a[$i+3*$c].$a[$i+4*$c]," #","01"))%106];echo$s;

Experimente online!

Expandido

$l=" 00000YE00G0000R000A0Q0000C0BW000K00000000000LT00000J00000000MU0000Z0000DI000000V0000000P00H0000ONF000S00X"; # search string mod 106
preg_match_all("#(.{5})\s#s","$_GET[0] ",$t); # Regex take each group of five chars followed by a whitespace
for($i=0;$i<$c=count($a=$t[1])/5;$i++)
  $s.=$l[bindec(strtr($a[$i].$a[$i+$c].$a[$i+2*$c].$a[$i+3*$c].$a[$i+4*$c]," #","01"))%106]; # join each groups make a binaray make a decimal mod 106  
echo$s; # Output

Convertendo a entrada em um formato de imagem

A @Stevie Griffin procura uma solução para obter isso de uma imagem. Eu acho que ele não quer realmente o formato de imagem que eu uso.

echo'<svg xmlns="http://www.w3.org/2000/svg" width="100%"><switch><foreignObject x="0" y="0" width="100%" height="300"><body xmlns="http://www.w3.org/1999/xhtml"><pre>'.$_GET[0].'</pre></body></foreignObject></switch></svg>';

O SVG pode conter partes HTML se for incluído em um ForeignObject. Então eu coloquei um elemento pré em um SVG.

Saída de imagem

<svg xmlns="http://www.w3.org/2000/svg" width="100%"><switch><foreignObject x="0" y="0" width="100%" height="300"><body xmlns="http://www.w3.org/1999/xhtml"><pre>#   # ##### #     #      ###        #   #  ###  ####  #     #### 
#   # #     #     #     #   #       #   # #   # #   # #     #   #
##### ####  #     #     #   #       # # # #   # ####  #     #   #
#   # #     #     #     #   #       ## ## #   # #   # #     #   #
#   # ##### ##### #####  ###        #   #  ###  #   # ##### #### </pre></body></foreignObject></switch></svg>

Solução de alterações de imagem

O SVG é legível por máquina. Depois de salvar o SVG como "i.svg", você só precisa substituí-lo $_GET[0]pela preg_replace("#(^.*e>)(.*)(</p.*$)#s","$2",join(file("i.svg")))entrada normal + 55 bytes


2

Powershell, 152 146 bytes

-join$(for($t=$args-split'
';$c-lt$t[0].Length;$c+=6){$s=0;$t|% s*g $c,5|% t*y|%{$s+=$s+$_}
'_ISRJ_BK_HFQPL_MYNCE _TXDAO_VWUZ__G'[$s%578%174%36]})

Script de teste:

$f = {

-join$(for($t=$args-split'
';$c-lt$t[0].Length;$c+=6){$s=0;$t|% s*g $c,5|% t*y|%{$s+=$s+$_}
'_ISRJ_BK_HFQPL_MYNCE _TXDAO_VWUZ__G'[$s%578%174%36]})

}

&$f @"
#   # ##### #     #      ###        #   #  ###  ####  #     #### 
#   # #     #     #     #   #       #   # #   # #   # #     #   #
##### ####  #     #     #   #       # # # #   # ####  #     #   #
#   # #     #     #     #   #       ## ## #   # #   # #     #   #
#   # ##### ##### #####  ###        #   #  ###  #   # ##### #### 
"@

&$f @"
 ###   ###   ###  ##### #####
#   # #     #   #   #     #  
#####  ###  #       #     #  
#   #     # #   #   #     #  
#   #  ###   ###  ##### #####
"@

&$f @"
####  ####   ###   ### 
#   # #   # #   # #    
####  ####  #     #  ##
#     #     #   # #   #
#     #      ###   ### 
"@

&$f @"
       ###  ####   ###  ####  ##### #####  ###  #   # ##### ##### #   # #     #   # #   #  ###  ####   ###  ####   ###  ##### #   # #   # #   # #   # #   # #####
      #   # #   # #   # #   # #     #     #     #   #   #     #   #  #  #     ## ## ##  # #   # #   # #   # #   # #       #   #   # #   # #   #  # #   # #     # 
      ##### ####  #     #   # ####  ####  #  ## #####   #     #   ###   #     # # # # # # #   # ####  #   # ####   ###    #   #   #  # #  # # #   #     #     #  
      #   # #   # #   # #   # #     #     #   # #   #   #   # #   #  #  #     #   # #  ## #   # #     #  #  #   #     #   #   #   #  # #  ## ##  # #    #    #   
      #   # ####   ###  ####  ##### #      ###  #   # ##### ###   #   # ##### #   # #   #  ###  #      ## # #   #  ###    #    ###    #   #   # #   #   #   #####
"@

Saída:

HELLO WORLD
ASCII
PPCG
 ABCDEFGHIJKLMNOPQRSTUVWXYZ

Nota:

  1. $t|% s*g $c,5|% t*y|%{$s+=$s+$_} é um atalho para $t.substring($c,5).toCharArray()|%{$s+=$s+$_}
  2. ("abcd","efgh").substring(1,2) retorna a matriz ("bc","de")
  3. ("bc","de").toCharArray() retorna a matriz ('b','c','d','e')

2

C,  225  209 bytes

Obrigado a @ceilingcat por salvar 16 bytes!

i,j,k,l,n,m;f(char*s){l=index(s,10)-s+1;for(i=0;i<l/6;++i){for(m=j=0;j<5;m+=n*(exp10(j++)+.1))for(n=k=0;k<5;)n+=(s[i*6+j+k*l]==35)<<k++;for(j=0;"Qi Y$>W);Xa%d^F4K-]7jcMAG="[j++]-32-m%77;);putchar(n?64+j:32);}}

Experimente online!

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.