Leer texto de arte ASCII


34

Inspirado por Golf me, un alfabeto ASCII , del cual este desafío es (casi) un inverso directo.


Tarea:

Tome una cadena de texto de arte ASCII y envíe el contenido del texto como texto ASCII normal.


Entrada:

Cadena de texto ASCII-art.

La entrada solo contendrá instancias de caracteres ASCII #, espacios y 4 o 5 líneas nuevas (una línea nueva es opcional). Todas las líneas tienen la misma longitud. (Es decir, la última carta de arte ASCII se rellena con espacios finales.) Puede usar algún otro carácter ASCII imprimible en lugar de #en la entrada si lo desea.

La entrada contendrá letras A-ZASCII-art y espacios ASCII-art (un bloque de espacios en blanco de 5x5). Sin puntuación Solo hay una línea de texto ASCII-art (5 líneas reales). No habrá espacios de arte ASCII finales o iniciales, ni habrá espacios de arte ASCII adyacentes.

El tamaño de la letra es de 5x5 caracteres. Hay un espacio de 1x5 entre cada letra. El espacio entre palabras es un bloque de espacios en blanco de 5x5 (+ 1x5 de espacio en cada lado, porque es solo otra letra). No habrá espacio 1x5 al final o al principio, solo entre letras ASCII-art.


Salida:

Cadena que contiene el texto como caracteres ASCII A-Z+ espacios. La salida también puede estar en minúsculas, si eso es de alguna manera más fácil para su solución. También se permiten mayúsculas y minúsculas.


Las letras del arte ASCII:

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

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

El espacio:

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

Ejemplos:

Entrada:

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

Salida: HELLO WORLD

Entrada:

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

Salida: ASCII

Entrada:

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

Salida: PPCG


Este es el , por lo que gana la respuesta más corta en bytes.


10
Estoy pensando que la solución a esto podría involucrar algún tipo de función hash ...
Neil

66
¡Recompense si hace esto convirtiendo la entrada en una imagen y resuelve esto usando el procesamiento de imágenes! (La solución también se debe jugar al golf, por supuesto)
Stewie Griffin

3
Si es de ayuda para alguien: la segunda fila, la cuarta fila o la columna central de las letras se pueden soltar sin perder información relevante.
Martin Ender

1
@JungHwanMin Hmm. Creo que no, porque ese no sería un texto ASCII-art muy legible .
Steadybox

1
@ JonathanAllan Supongo que eso también estaría bien.
Steadybox

Respuestas:


13

Jalea ,  50 44  42 bytes

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

Pruébalo en línea! (tenga en cuenta que el argumento no requiere la nueva línea inicial, pero dado que las nuevas líneas iniciales y finales no tienen ningún efecto, incluí una para hacer que la cadena de varias líneas sea más legible para los humanos)

Los resultados son mixtos (según lo permitido por el OP en un comentario ).

¿Cómo?

Se divide en nuevas líneas, se transpone y une subgrupos de (hasta) seis para obtener las representaciones de los caracteres y revierte cada uno (igualando la conversión de base posterior para el carácter final de longitud 25 a todos los demás de longitud 30). Luego asigna '#'y ' 'a uno y cero respectivamente, usando el hecho de que '#'tiene un ordinal impar mientras que ' 'tiene uno par. Lee cada uno como si fuera un número base siete. Efectivamente toma el módulo 81 de cada uno (para obtener 27 valores únicos para los 27 casos posibles), y finalmente se indexa en una "cadena mágica" con los caracteres correctos en los índices correctos (la indexación de módulo se usa con una cadena mágica de longitud 81 para guardar 2 bytes).

Aquí está la "cadena mágica" que creé junto con un patrón de expresiones regulares (que no distingue entre mayúsculas y minúsculas) que necesitaba para coincidir (agregué "ed" para que tuviera una longitud de 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, puede estar comprimido, buscando once sub-cortes como palabras en el diccionario de Jelly (la mayoría de los cuales usa el espacio inicial predeterminado):

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

que da como resultado la cadena comprimida Jelly, “¥ŒƲVĊ⁾|W£⁼³ƭÇuʋụzḢĖ0ḢẆẠØsĠỌỊ»

El resto del código funciona de la siguiente manera:

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

Pruébalo en línea!


Finalmente más corto que JS


El uso inteligente del módulo, pero no puedo pensar ayuda tiene que haber una manera de hacerlo: [0,2,3,7,...]y ' UBGOTA...repartirlo, y utilizar algún tipo de mapeo. 0:' ',2:'U',3:'V'...parece tan largo, hay tantos :'',. (Sé que tenías algo similar en la publicación original, pero con números muy largos.
Stewie Griffin

1
@StewieGriffin es mejor ahora
ovs

11

JavaScript (ES6), 204 186 184 182 bytes

Guardado 18 bytes gracias a Neil
Guardado 2 bytes gracias a ETHproductions
Guardado 2 bytes gracias a YairRand

Descompostura:

  • Tabla de búsqueda 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])

Manifestación


1
Puede guardar una gran cantidad de bytes usando (a=s.split`\n`)[0].replace(/......?/g,con substr(n,5)y sin, joinpor supuesto.
Neil

Creo que se puede guardar un byte con c=>0|c>' ', y otro conp+='0b'+...
ETHproductions

Como mencionó @Steadybox en la sección de Comentarios del Desafío, la \nentrada no es válida. Sin embargo, creo que puede usar la plantilla literal con la nueva línea real como entrada, tal como lo hace en el splitmétodo.
Arjun

1
@ DobbyTheFree-Elf De hecho, podría usar una plantilla literal, que incidentalmente perjudicaría la legibilidad debido a la cita principal. Pero agregar una restricción en la forma en que los datos de entrada se formatean antes de pasar a la función está fuera de tema, en mi humilde opinión (siempre que el contenido real de la entrada sea válido).
Arnauld

1
@ DobbyTheFree-Elf Me temo que mi comentario fue un poco ambiguo, y es posible que haya entendido mal la pregunta que estaba respondiendo. El uso \nde un literal de cadena en el sitio de la llamada en el código está bien, porque la cadena real que se pasa a la función incluye solo el carácter de nueva línea, no tanto \` and n . Passing a string that contains \ ' ncomo caracteres adyacentes separados no estaría bien.
Steadybox

9

Bash + ImageMagick + Tesseract , 161 bytes

Quería probar el enfoque sugerido por @ stewie-griffin y elegí bash + ImageMagick (para convertir una cadena en una imagen) y Tesseract (para hacer el OCR). Aquí está mi código, que funciona para el caso de prueba 'HELLO WORLD', pero falla los otros. Tal vez sea útil algún ajuste en los parámetros (fuente, tamaño de fuente, interletraje, espaciado).

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

Simplemente copie y pegue el arte ascii en la línea de comandos después de ejecutar el comando. Termine su entrada presionando ^ d.

Salida actual para los casos de prueba:

  • HOLA MUNDO: HOLA MUNDO
  • ASCII: H5511
  • PPCG: PPOG

6

Scala, 184 181 bytes

Una solución de cadena mágica + módulo basada en 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

Probar en línea (Scalafiddle)

Más legible:

(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

Explicaciones

  • La cadena inicial (arte ASCII) se divide en 5 líneas (altura del carácter ASCII)
  • Cada línea se divide en elementos de 6 caracteres (ancho del carácter ASCII + 1 espacio)
  • Solo se conservan los primeros 5 caracteres (el espacio al final es inútil)
  • Las líneas se transponen (cada carácter ASCII se representa como una secuencia de 25 caracteres (5x5), que contiene '#'o ' ')
  • Cada representación de caracteres ASCII (secuencia) se convierte en String y se calcula un código hash absoluto para esa String (absoluta necesaria debido al siguiente módulo)
  • % 106 % 79 % 47Se aplican 3 módulos consecutivos ( ) para asociar un número ∈ [0; 47[para cada carácter ASCII (ver explicaciones a continuación)
  • Este número se utiliza como índice de la cadena mágica.

¿Cómo obtener la cuerda mágica?

Primero, representé todas las letras como esta:

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

Luego, creé un alfabeto que contenía representaciones ASCII de todos los caracteres:

Ejemplo:

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

se convierte

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

Para cada letra, se calculó un código hash absoluto (todos los códigos hash son 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))

Luego intenté disminuir cada código, pero siempre respetando el hecho de que cada código debe ser único (la lista agrupada por el código debe tener 27 elementos, 1 por cada letra). Así que probé los primeros 200 módulos:

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

Encontré 106como el primer módulo que se aplicará:

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

Repetí los pasos anteriores hasta el módulo más pequeño. Encontré :

  • 79
  • 47
  • 44
  • 42

Nota: El último módulo que elegí ( 47) no es el más pequeño aquí:

  • Encontré 44, pero si hubiera elegido 44, la cadena mágica tendría un tamaño de 44 (en lugar de 47) pero tendría que escribir %106%79%47%44(13 caracteres en lugar de %106%79%47= 10 caracteres). Entonces, en bytes, el código debería haber tenido el mismo tamaño que el que obtuve
  • También hay 42, pero entonces el código debería haber tenido 1 byte más que el que obtuve

Luego, apliqué el módulo consecutivo ( % 79 % 47) al último codes, para obtener los códigos definitivos asociados 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 la cuerda 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"

Ejemplo: la letra Aanterior está asociada a 46 ( 380997542 % 106 % 79 % 47), y el elemento 46 de la cadena mágica es A :)

Casos de prueba

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

HOLA MUNDO :

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

f(asciiArt)    // HELLO WORLD

ASCII:

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

f(asciiArt)    // ASCII

PPCG:

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

f(asciiArt)    // PPCG

Ediciones

  • Guardado 3 bytes eliminando .antes map, toArrayymkString

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;

Pruébalo en línea!

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

Convertir la entrada a un formato de imagen

@ Stevie Griffin busca una solución para obtener esto de una imagen. Creo que él no quiere realmente el formato de imagen que 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>';

SVG puede contener partes HTML si luego se incluye en un ForeignObject. Así que puse un elemento pre en un SVG.

Salida de imagen

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

Resolviendo a partir de cambios de imagen

SVG es legible por máquina, por lo que después de guardar el SVG como "i.svg" solo necesita reemplazarlo $_GET[0]con preg_replace("#(^.*e>)(.*)(</p.*$)#s","$2",join(file("i.svg")))la 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 prueba:

$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 @"
       ###  ####   ###  ####  ##### #####  ###  #   # ##### ##### #   # #     #   # #   #  ###  ####   ###  ####   ###  ##### #   # #   # #   # #   # #   # #####
      #   # #   # #   # #   # #     #     #     #   #   #     #   #  #  #     ## ## ##  # #   # #   # #   # #   # #       #   #   # #   # #   #  # #   # #     # 
      ##### ####  #     #   # ####  ####  #  ## #####   #     #   ###   #     # # # # # # #   # ####  #   # ####   ###    #   #   #  # #  # # #   #     #     #  
      #   # #   # #   # #   # #     #     #   # #   #   #   # #   #  #  #     #   # #  ## #   # #     #  #  #   #     #   #   #   #  # #  ## ##  # #    #    #   
      #   # ####   ###  ####  ##### #      ###  #   # ##### ###   #   # ##### #   # #   #  ###  #      ## # #   #  ###    #    ###    #   #   # #   #   #   #####
"@

Salida:

HELLO WORLD
ASCII
PPCG
 ABCDEFGHIJKLMNOPQRSTUVWXYZ

Nota:

  1. $t|% s*g $c,5|% t*y|%{$s+=$s+$_} es atajo para $t.substring($c,5).toCharArray()|%{$s+=$s+$_}
  2. ("abcd","efgh").substring(1,2) devuelve la matriz ("bc","de")
  3. ("bc","de").toCharArray() devuelve la matriz ('b','c','d','e')

2

C,  225  209 bytes

¡Gracias a @ceilingcat por guardar 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);}}

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.