Baca ASCII-Seni Teks


34

Terinspirasi oleh Golf saya alfabet ASCII , yang tantangannya (hampir) terbalik langsung.


Tugas:

Ambil string teks ASCII-art dan output konten teks sebagai teks ASCII biasa.


Memasukkan:

String teks ASCII-art.

Input hanya akan berisi instance karakter ASCII #, spasi, dan 4 atau 5 baris baru (baris tambahan tambahan opsional). Semua garis memiliki panjang yang sama. (Yaitu, huruf ASCII-art terakhir diisi dengan spasi tambahan.) Anda dapat menggunakan beberapa karakter ASCII yang dapat dicetak lainnya alih-alih# dalam input jika diinginkan.

Input akan berisi huruf A-ZASCII-art dan spasi ASCII-art (blok spasi 5x5). Tidak ada tanda baca. Hanya ada satu baris teks ASCII-art (5 baris aktual). Tidak akan ada jejak atau ruang seni ASCII terkemuka, juga tidak akan ada ruang seni ASCII yang berdekatan.

Ukuran huruf adalah 5x5 karakter. Ada spasi 1x5 antara setiap huruf. Spasi antar kata adalah blok spasi 5x5 (spasi + 1x5 di setiap sisi, karena itu hanya huruf lain). Tidak akan ada ruang 1x5 di akhir atau di awal, hanya di antara huruf ASCII-art.


Keluaran:

String yang berisi teks sebagai karakter ASCII A-Z+ spasi. Outputnya bisa dalam huruf kecil juga, jika itu entah bagaimana lebih mudah untuk solusi Anda. Kasing campuran juga diperbolehkan.


Surat-surat ASCII-art:

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

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

Ruang angkasa:

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

Contoh:

Memasukkan:

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

Keluaran: HELLO WORLD

Memasukkan:

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

Keluaran: ASCII

Memasukkan:

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

Keluaran: PPCG


Ini adalah , jadi jawaban tersingkat dalam byte menang.


10
Saya pikir solusi untuk ini mungkin melibatkan semacam fungsi hash ...
Neil

6
Hadiah dari saya jika Anda melakukan ini dengan mengonversi input ke gambar dan menyelesaikan ini menggunakan pemrosesan gambar! (Solusinya juga harus golf)
Stewie Griffin

3
Jika ini dapat membantu siapa saja: baris kedua, baris keempat, atau kolom tengah dari huruf-huruf itu dapat dijatuhkan tanpa kehilangan informasi yang relevan.
Martin Ender

1
@JungHwanMin Hmm. Saya kira tidak, karena itu bukan teks ASCII-art yang sangat bisa dibaca manusia .
Steadybox

1
@ Jonathan Allan Saya kira itu akan baik-baik saja.
Steadybox

Jawaban:


13

Jelly ,  50 44  42 byte

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

Cobalah online! (perhatikan argumen tidak memerlukan baris baru, tetapi karena memimpin dan mengikuti baris baru tidak berpengaruh, saya memasukkan satu untuk membuat string multiline lebih mudah dibaca oleh manusia)

Hasil adalah kasus campuran (sebagaimana diizinkan oleh OP dalam komentar ).

Bagaimana?

Pisahkan pada baris baru, transpos, dan bergabung bersama sub-irisan dari (hingga) enam bersama-sama untuk mendapatkan representasi karakter dan membalikkan masing-masing (menyamakan konversi basis kemudian untuk karakter akhir dari panjang 25 ke yang lain dari panjang 30). Kemudian peta '#'dan ' 'ke satu dan nol masing-masing menggunakan fakta yang '#'memiliki ordinal aneh sementara ' 'memiliki satu genap. Membaca masing-masing seolah-olah itu adalah angka tujuh dasar. Secara efektif mengambil modulo 81 dari masing-masing (untuk menghasilkan 27 nilai unik untuk 27 kasus yang mungkin), dan akhirnya indeks menjadi "string ajaib" dengan karakter yang benar pada indeks yang benar (pengindeksan modulo digunakan dengan string ajaib panjang 81 untuk menyimpan 2 byte).

Berikut adalah "string ajaib" yang saya buat bersama dengan pola regex (case-insensitive) yang diperlukan untuk mencocokkan (saya menambahkan "ed" untuk membuatnya panjang 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.*'

Karena itu dapat dikompresi, cari sebelas sub-irisan sebagai kata-kata dalam kamus Jelly (sebagian besar menggunakan standar ruang terdepan):

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

yang menghasilkan string terkompresi Jelly, “¥ŒƲVĊ⁾|W£⁼³ƭÇuʋụzḢĖ0ḢẆẠØsĠỌỊ»

Sisa kode berfungsi sebagai berikut:

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

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

Cobalah online!


Akhirnya lebih pendek dari JS


Clever use of the modulus, but I can't help thinking there must be a way to do: [0,2,3,7,...] and ' UBGOTA... split it, and use some sort of mapping. 0:' ',2:'U',3:'V'... looks so long,,, there are so many :'',. (I know you had something similar in the original post, but with very long numbers.
Stewie Griffin

1
@StewieGriffin it is better now
ovs

11

JavaScript (ES6), 204 186 184 182 bytes

Saved 18 bytes thanks to Neil
Saved 2 bytes thanks to ETHproductions
Saved 2 bytes thanks to YairRand

Breakdown:

  • 42-byte lookup table
  • 162 144 142 140 bytes of code
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
You can save a whole bunch of bytes using (a=s.split`\n`)[0].replace(/......?/g, with substr(n,5) and without the join of course.
Neil

I think you can save a byte with c=>0|c>' ', and another with p+='0b'+...
ETHproductions

As mentioned by @Steadybox in the Comment section of the Challenge, taking \n in input is invalid. However, I think you can use template literal with actual newline as input, just like you are doing in the split method.
Arjun

1
@DobbyTheFree-Elf I could indeed use a template literal -- which incidentally would impair the readability because of the leading quote. But adding a constraint on the way the input data is formatted before being passed to the function is out of topic, IMHO (as long as the actual content of the input is valid).
Arnauld

1
@DobbyTheFree-Elf I'm afraid my comment was a bit ambiguous, and I may have slightly misunderstood the question I was answering. Using \n in a string literal at the call site in the code is okay, because the actual string that is passed to the function includes only the newline character, not both \` and n. Passing a string that contains \` and n as separate adjacent characters would not be okay.
Steadybox

9

Bash + ImageMagick + Tesseract, 161 bytes

I wanted to try the approach suggested by @stewie-griffin and went for bash + ImageMagick (to convert a string to an image) and Tesseract (to do the OCR). Here's my code, which works for the 'HELLO WORLD' testcase, but fails the other ones. Maybe some tweaking to the parameters (font, font size, kerning, spacing) helps.

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

Just copy-paste the ascii art into the commandline after running the command. Finish your input by pressing ^d.

Current output for the test cases:

  • HELLO WORLD: HELLO WORLD
  • ASCII: H5511
  • PPCG: PPOG

6

Scala, 184 181 bytes

A magic string + modulo solution based on 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

Try online (Scalafiddle)

More readable :

(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

Explanations

  • The initial String (ASCII art) is split into 5 lines (height of ASCII character)
  • Each line is split in 6-characters elements (width of ASCII character + 1 space)
  • Only the first 5 characters are kept (the space at the end is useless)
  • The lines are transposed (each ASCII character is represented as a sequence of 25 characters (5x5), containing either '#' or ' ')
  • Each ASCII character representation (sequence) is converted to String and an absolute hashcode is computed for that String (absolute needed because of next modulus)
  • 3 consecutive modulus (% 106 % 79 % 47) are applied to associate a number ∈ [0; 47[ for each ASCII character (see explanations below)
  • This number is used as an index of the magic string

How to get the magic string ?

First, I represented all letters like this :

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

Then, I created an alphabet containing ASCII representations of all characters :

Example :

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

becomes

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

For each letter, an absolute hashcode was computed (all hashcodes are distinct) :

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

Then I tried to decrease each code, but always respecting the fact that each code must be unique (the list grouped by the code must have 27 elements, 1 for each letter). So I tried the first 200 modulus :

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

I found 106 as the first modulo to be applied :

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

I repeated the previous steps until the smallest modulo. I found :

  • 79
  • 47
  • 44
  • 42

Note : The last modulo I chose (47) is not the smallest here :

  • I found 44, but if I had chosen 44, the magic string would have size 44 (instead of 47) but I would have to write %106%79%47%44 (13 characters instead of %106%79%47 = 10 characters). So in bytes, the code should have had the same size as the one I got
  • There is also 42, but then the code should have had 1 byte more than the one I got

Next, I applied the consecutive modulus (% 79 % 47) to the last codes, to get the definitive codes associated to each letter :

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

Finally, to construct the magic string :

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"

Example : The letter A above is associated to 46 (380997542 % 106 % 79 % 47), and the 46th element of the magic string is A :)

Test cases

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

HELLO WORLD :

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

f(asciiArt)    // HELLO WORLD

ASCII :

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

f(asciiArt)    // ASCII

PPCG :

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

f(asciiArt)    // PPCG

Edits

  • Saved 3 bytes by removing . before map, toArray and mkString

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;

Try it online!

Expanded

$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

Converting the Input to an image format

@Stevie Griffin search a solution to get this from an image. I think he want not really the image format I have use.

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 can contains HTML parts if then included in a foreignObject. So I put a pre Element in a SVG.

Image Output

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

Solving from Image Changes

SVG is machine readable so after saving the SVG as "i.svg" you need only replace $_GET[0] with preg_replace("#(^.*e>)(.*)(</p.*$)#s","$2",join(file("i.svg"))) in the way with normal input + 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]})

Test script:

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

Output:

HELLO WORLD
ASCII
PPCG
 ABCDEFGHIJKLMNOPQRSTUVWXYZ

Note:

  1. $t|% s*g $c,5|% t*y|%{$s+=$s+$_} is shortcut for $t.substring($c,5).toCharArray()|%{$s+=$s+$_}
  2. ("abcd","efgh").substring(1,2) returns the array ("bc","de")
  3. ("bc","de").toCharArray() returns the array ('b','c','d','e')

2

C,  225  209 bytes

Thanks to @ceilingcat for saving 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);}}

Try it online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.