读取ASCII文字


34

Golf启发,我使用了ASCII字母,对此挑战(几乎)是直接逆运算。


任务:

取一串ASCII文字文本,然后将文本内容输出为常规ASCII文本。


输入:

ASCII艺术字的字符串。

输入将仅包含ASCII字符#,空格和4或5个换行符的实例(结尾的换行符是可选的)。所有行的长度相同。(也就是说,最后一个ASCII字母后缀空格。)如果需要,可以使用其他一些可打印的ASCII字符代替#输入。

输入将包含ASCII字母A-Z和ASCII空格(5x5的空白块)。没有标点符号。只有一行ASCII美术文字(实际5行)。将没有尾随或前导的ASCII艺术空间,也没有相邻的ASCII艺术空间。

字母大小为5x5个字符。每个字母之间有1x5的间隔。单词之间的间隔是5x5的空白块(每边+ 1x5的间隔,因为它只是另一个字母)。在结尾或开头将没有1x5空格,只有在ASCII字母之间。


输出:

包含文本的字符串,为ASCII字符A-Z+空格。如果您的解决方案更容易些,则输出也可以小写。混合大小写也是允许的。


ASCII字母:

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

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

空间:

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

例子:

输入:

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

输出: HELLO WORLD

输入:

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

输出: ASCII

输入:

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

输出: PPCG


这是,因此最短的答案以字节为单位。


10
我在想解决此问题的方法可能涉及某种哈希函数……
Neil

6
如果您通过将输入转换为图像并使用图像处理解决此问题,这对我有帮助!(当然,解决方案也必须打高尔夫球)
Stewie Griffin

3
如果对任何人有帮助:可以删除字母的第二行,第四行或中间列,而不会丢失相关信息。
Martin Ender

1
@JungHwanMin嗯。我认为不是,因为那不是人类可读的 ASCII文字。
Steadybox

1
@JonathanAllan我想也可以。
Steadybox'4

Answers:


13

果冻 50 44  42 字节

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

在线尝试!(请注意,该参数不需要开头的换行符,但是由于开头和结尾的换行符无效,因此我添加了一个以使多行字符串更易于理解)

结果是大小写混合的(OP允许在注释中)。

怎么样?

在新行上分割,转置并将(最多)六个子片段连接在一起,以获得字符表示并反转每个字符表示(将后面的基本转换(长度25的最终字符等同于长度30的所有其他字符))。然后映射'#'' '以1和0分别使用的事实'#'具有奇数序而' '具有偶数之一。读取每个值,就好像它是一个以7为底的数字一样。有效地对每个取模81(以在27个可能的情况下产生27个唯一值),最后在正确的索引处将索引与具有正确字符的“魔术字符串”(模索引与长度为81的魔术字符串一起使用以保存2个字节)。

这是我创建的“魔术字符串”以及需要匹配的(不区分大小写)正则表达式模式(我添加了“ ed”使其长度为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.*'

因此,它可以被压缩,在Jelly词典中查找十一个子切片作为单词(其中大多数使用前导空格默认值):

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

结果是Jelly压缩的字符串, “¥ŒƲVĊ⁾|W£⁼³ƭÇuʋụzḢĖ0ḢẆẠØsĠỌỊ»

其余代码的工作方式如下:

Ỵ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字节

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

在线尝试!


最后比JS短


巧妙地利用了模数的,但我忍不住想,必须有办法做到:[0,2,3,7,...]' UBGOTA...拆分它,使用某种映射。0:' ',2:'U',3:'V'...看起来很长,,,有那么多:'',。(我知道你有在原岗位类似的东西,但很长的数字。
Stewie新

1
@StewieGriffin现在好了
ovs '17

11

的JavaScript(ES6),204个 186 184 182字节

Neil节省了18个
字节ETHproductions 节省了2个字节YairRand
节省了2个字节

分解:

  • 42字节查找表
  • 162个 144 142 140字节的代码
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])

演示版


1
您可以使用节省一大堆的字节(a=s.split`\n`)[0].replace(/......?/g,substr(n,5)和没有join当然的。
尼尔

我认为您可以使用保存一个字节c=>0|c>' ',以及使用p+='0b'+...
–ETHproductions

如@Steadybox在“挑战”的“注释”部分所述,\n输入无效。但是,我认为您可以使用带有实际换行符的模板文字作为输入,就像您在split方法中所做的一样。
Arjun

1
@ DobbyTheFree-Elf我确实可以使用模板文字-由于前引号的缘故,这会损害可读性。但是,在将输入数据传递给函数之前,对格式进行格式化的方式增加了一种限制,即主题恕我直言(只要输入的实际内容有效)。
Arnauld

1
@ DobbyTheFree-Elf恐怕我的评论有点模棱两可,而且我可能对我正在回答的问题略有误解。\n在代码中的调用位置使用字符串文字是可以的,因为传递给函数的实际字符串仅包含换行符,而不是\` and n . Passing a string that contains \`和n作为单独的相邻字符都将不可行。
Steadybox

9

Bash + ImageMagick + Tesseract,161字节

我想尝试@ stewie-griffin建议的方法,并使用bash + ImageMagick(将字符串转换为图像)和Tesseract(进行OCR)。这是我的代码,适用于“ HELLO WORLD”测试用例,但未通过其他测试用例。也许对参数进行一些调整(字体,字体大小,字距,间距)会有所帮助。

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

运行命令后,只需将ascii art复制粘贴到命令行即可。按^ d完成输入。

测试用例的电流输出:

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

6

Scala中,184个 181字节

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

在线尝试(Scalafiddle)

更具可读性:

(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

说明

  • 初始字符串(ASCII文字)分为5行(ASCII字符的高度)
  • 每行分为6个字符的元素(ASCII字符的宽度+ 1个空格)
  • 仅保留前5个字符(末尾的空格无用)
  • 换行了(每个ASCII字符表示为25个字符(5x5)的序列,包含'#'' '
  • 每个ASCII字符表示形式(序列)都将转换为String,并为该String计算一个绝对哈希码(由于下一个模数而需要使用绝对值)
  • 应用3个连续的模数(% 106 % 79 % 47[0; 47[为每个ASCII字符关联一个数字ε (请参见下面的说明)
  • 该数字用作魔术弦的索引

如何获得魔术弦?

首先,我代表了所有这样的字母:

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

然后,我创建了一个包含所有字符的ASCII表示形式的字母:

范例:

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

变成

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

对于每个字母,都会计算一个绝对的哈希码(所有哈希码都是不同的):

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

然后,我尝试减少每个代码,但始终尊重每个代码必须唯一的事实(按代码分组的列表必须包含27个元素,每个字母1个)。所以我尝试了前200个模数:

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

我发现106这是要应用的第一个模:

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

我重复了前面的步骤,直到最小的模数。我发现 :

  • 79
  • 47
  • 44
  • 42

注意:我选择的最后一个模(47)在这里不是最小的:

  • 我找到了44,但是如果我选择了44,则魔术字符串的大小将为44(而不是47),但是我必须写%106%79%47%44(13个字符而不是%106%79%4710个字符)。因此,以字节为单位,代码应该与我得到的代码具有相同的大小
  • 也有42个,但是代码应该比我得到的多1个字节

接下来,我将连续模数(% 79 % 47)应用于last codes,以获得与每个字母相关的确定代码:

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

最后,构造魔术字符串:

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"

示例:A上面的字母与46(380997542 % 106 % 79 % 47)相关联,并且魔术弦的第46个元素是A :)

测试用例

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

你好,世界 :

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

f(asciiArt)    // HELLO WORLD

ASCII:

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

f(asciiArt)    // ASCII

PPCG:

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

f(asciiArt)    // PPCG

编辑

  • 通过去除保存3个字节.maptoArraymkString

3

PHP,294字节

<?$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;

在线尝试!

展开式

$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

将输入转换为图像格式

@Stevie Griffin搜索解决方案以从图像中获取此信息。我认为他真的不想要我使用的图像格式。

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包含在foreignObject中,则可以包含HTML部分。所以我在SVG中放了一个前置元素。

影像输出

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

解决图像变化

SVG是机器可读的,因此在将SVG保存为“ i.svg”之后,只需用普通输入+ 55字节的方式替换$_GET[0]preg_replace("#(^.*e>)(.*)(</p.*$)#s","$2",join(file("i.svg")))


2

的powershell,152个 146字节

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

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

输出:

HELLO WORLD
ASCII
PPCG
 ABCDEFGHIJKLMNOPQRSTUVWXYZ

注意:

  1. $t|% s*g $c,5|% t*y|%{$s+=$s+$_} 是的快捷方式 $t.substring($c,5).toCharArray()|%{$s+=$s+$_}
  2. ("abcd","efgh").substring(1,2) 返回数组 ("bc","de")
  3. ("bc","de").toCharArray() 返回数组 ('b','c','d','e')

2

C, 225个  209字节

感谢@ceilingcat节省了16个字节!

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

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.