阅读复古展示


22

什么地方偷来的艺术品


可以使用_|字符以ASCII表示7段数字。这是数字0-9

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|

您的工作是将艺术作品解析为正常数字。

数字注释

  • 每个数字都有不同的宽度。
    • 1 宽度为 1
    • 3而且72
    • 245689而且03

每个数字之间还有一个填充字符。这是完整的字符集:

 // <-应该是一个空格,但是SE格式将其弄乱了
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

| _ |
  |
-------------
 _ 
| _ 
 _ |
-------------
 _ 
| _ 
| _ |
-------------
_ 
 |
 |
-------------
 _ 
| _ |
| _ |
-------------
 _ 
| _ |
 _ |
-------------
 _ 
| |
| _ |

输入项

输入可以从控制台输入,也可以作为函数的字符串arg输入。

输出量

输出要么放到控制台,要么从函数返回。

例子:

  _  _   _ 
|  |  | |_ 
|  |  | |_|
1776

 _   _     _ 
 _| | | | |_ 
|_  |_| | |_|
2016

   _       _ 
| |_| |_| |_ 
|  _|   |  _|
1945

   _   _   _   _   _   _ 
| | | | | | | | | | | | |
| |_| |_| |_| |_| |_| |_|
1000000

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|
0123456789

这是代码高尔夫球,因此最短的字节数获胜!



我有兴趣学习解决此类问题的最佳算法,但我很难从这里的答案中学习(它们很好,非常简洁)。您可以在哪里找到我的详细解释,最好是附有图片?

好吧,我的工作方式非常简单。它转置列表并在其上循环。然后,它在空行上分割。根据每个号码的指纹表检查每个号码。其他人的工作方式与我的相似,除了他们基本上使用哈希表代替指纹表之外。
J Atkin

在计算机科学中,这种问题是否有更通用的名称?

我不知道;)
J Atkin

Answers:


4

Pyth,33个 30字节

sm@."/9Àøw"%%Csd409hTcC.z*3d

这是一个主意:一旦我们对输入进行转置并划分为数字,就可以对各个数字字符串进行哈希处理,并将它们分配给它们的值。

sm@."/9Àøw"%%Csd409hTcC.z*3d     Implicit: z=input
                      C.z        Transpose input.
                     c   *3d     Split that on "   ", a space between digits.
 m@."/9Àøw"%%Csd409hT            Map the following lambda d over that. d is a digit string.
             Csd                   Flatten the digit string, and convert from base 256.
            %   409                Modulo that by 409
           %       hT              and then by 11. All digits go to a distinct num mod 11.
   ."/9Àøw"                        The compressed string "03924785/61".
  @                                Index into that string.
s                                Flatten and implicitly output.

在这里尝试。


很酷,基本上看起来像我的方法,但是要短得多!
林恩

@林恩抱歉 在Pyth中,基本上是最短的方法。
lirtosiast

4

Ruby,184个字节

a=0
l=$<.map{|x|x.bytes.map{|y|y==32?0:1}+[0]*2}
(0..l[0].count-1).map{|i|l[0][i]+2*l[1][i]+4*l[2][i]}.each{|x|
x>0?(a=x+2*a):(p Hash[[40,6,32,20,18,26,42,8,44,64].zip(0..9)][a];a=0)}

说明

  • 接受标准输入
  • 将字符串转换为二进制序列,1/0用于段开/关
  • 将列编码为3位二进制数
  • 将3位数字序列编码为9位数字,使用“ 0”列作为停止符号
  • 使用查找表将9位数字转换为数字

这是我的第一个代码高尔夫球。感谢您的乐趣!


2
欢迎来到PPCG!在您的第一篇文章上做得很好!
J阿特金


2

Japt,119个字节

Ur"[|_]"1 z r" +
"R x1 qR² £"11
1 1
1151151
111
 15111
115 1
 1
115 1
111
1511
111
15  1
11511
111
115 1
111
11"q5 bXÃq

Try it here!

哎呀,这真的很长。我认为我还没有打完高尔夫球。

说明

制备

我们接受输入并将任何内容转换|_1。然后我们转置,去除结尾的空格,并沿双换行符分割。

翻译

我们映射到结果数组,并找到索引在引用数组中出现的位置的索引。这是一个帮助图:

MAPITEM
  11
  1 1 --> This same form appears at index 0 in the reference array
  11                            |
                                |
                                V
                        change the mapitem to 0!

之后,我们加入数字数组并输出!

注意:您可能想知道为什么我们必须将每个美术角色更改为一系列的1。这是因为似乎存在一个错误(或类似的错误),该错误使我无法按原样存储字符|_


我注意到了该_错误,但我不知道是什么原因引起的。
ETHproductions 2016年

OK,"\n\n"可以替换,并"\\||_""%||_"。我想你也可以节省在基地4(改变各4个disinctive字符的编码的长字符串一些字节012或者3,填充为4的倍数的长度,然后运行r"...."_n4 d}在它),但由于某种原因,我还没有开始工作。
ETHproductions 2016年

2

Python2,299个 261 244字节

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
p=lambda l:['95572431508448853268'.find(`sum(ord(c)**i for i,c in enumerate("".join(n)))%108`)/2for n in s(l.split('\n'))]

我真的很喜欢这个挑战,干得好!

说明

该函数s以三行作为输入,它试图找到一个数字分隔符(所有字符都是空格)。找到这样的分隔符后,它将s与其余三行一起调用,并将调用返回的值添加到组成该数字的三行中。如果没有分隔符,则意味着只有一位数字。

该函数p是入口点,因此它采用代表数字的字符串。这些数字以“哈希”形式存储,sum(ord(c)**i for i,c in enumerate("".join(n)))%108用于节省空间(感谢其他答案!)。

例子

digits="""
 _     _ 
| | |  _|
|_| | |_ """[1:]  # remove the '\n' at the beginning

p(digits)  # [0, 1, 2]

其他版本

261个字节(py3):

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
def p(l):[print([91,21,84,31,58,76,88,41,80,68].index(sum(ord(c)**i%20 for i,c in enumerate("".join(n)))),end="")for n in s(l.split('\n'))]

249个字节,这一行转置行(py2):

f="".join
s=lambda a,i=0:[a]if i==len(a)else[a[:i]]+s(a[i+1:])if all(c==' 'for c in a[i])else s(a,i=i+1)
h=lambda s:ord(s[0])**len(s)+h(s[1:])if s else 0
p=lambda l:["10220907112527153129".index(`h(f(map(f,n)))%34`)/2for n in s(zip(*l.split('\n')))]

2

JavaScript(ES6),169字节

a=>[...(a=a.split`
`)[0]].map((b,c)=>(d={' ':0,'|':1,'_':2})[b]+d[a[1][c]]*2+d[a[2][c]]).join``.split(0).map(b=>[343,3,182,83,243,281,381,23,383,283].indexOf(+b)).join``

首先分为三行,将每列重新映射为一个值,然后根据这些值为每列建立唯一标识。然后将其除以0(各列之间的空格的标识),最后将每个标识映射到其数字值,并进行连接和输出。


非常好!我希望python具有列表拆分功能...
J Atkin

@JAtkin我整理join成一个字符串,以便可以拆分它。我相信您也可以在Python中做到这一点?
Mwr247 '16

0

Python 3中,281个 254字节

编辑

我只是看了另一个python答案的代码,发现很多代码是相似的。这是独立达成的。

(为“可读性”添加了换行符)

def p(i):
 n=[[]]
 for l in zip(*i.split('\n')):
  if all(i==" "for i in l):n+=[[]]
  else:n[-1]+=l
 return''.join(map(lambda l:str([''.join(l[2:])==x for x in
             "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"
                     .split(',')].index(1)),n))

取消高尔夫:

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]
    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst
    return ''.join(map(digit, numbers))

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(num[2:]) == y for y in fingerprint].index(True))

测试:

assert (parse("   _   _   _   _   _   _ \n| | | | | | | | | | | | |\n| |_| |_| |_| |_| |_| |_|") == '1000000')
assert (parse("   _       _ \n| |_| |_| |_ \n|  _|   |  _|") == '1945')
assert (parse(" _   _     _ \n _| | | | |_ \n|_  |_| | |_|") == '2016')
assert (parse(" _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|") == '0123456789')
assert (parse("  _  _   _ \n|  |  | |_ \n|  |  | |_|") == '1776')

怎么运行的

(注意:我在这里解释ungolf程序,因为它更具可读性,并且具有完全相同的代码,不同之处在于该digit函数内联到lambda中)

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]

主要功能是parse。它首先将输入分成几行并创建numbers数组。

    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst

这是我最喜欢的部分(因为花了很长时间才弄清楚)。在这里,我们zip画线,以便我们基本上可以垂直遍历输入。当行上有字符时,我们将其添加到numbers数组中的最后一个数字。如果没有任何字符,我们向数组添加一个新数字。

    return ''.join(map(digit, numbers))

确实很简单,numbers它与digit函数映射并转换为字符串。

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(x[2:]) == y for x, y in zip([num]*10, fingerprint)].index(True))

这(很)简单。fingerprint是上面创建的数字的字符串表示形式减去前两个字符(这是我能找到的最小指纹)。我们返回第一个匹配项的索引。


0

Haskell中,270个 207字节

不要太努力,这是我有史以来第一个haskell程序;)我几乎可以肯定它可以进一步发展,但是由于我有限的语言知识,我不知道该怎么做。

import Data.Lists
b n=map c$splitOn["   "]$transpose$lines n
c n|e<-drop 2$concat n,Just r<-elemIndex True[e==f|f<-splitOn",""|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"]=(show r)!!0

取消高尔夫:

module Main where
import Data.Lists

main :: IO ()
main = print $ parse " _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|"

parse :: String -> String
parse n = let lst = transpose $ lines n
              numbers = splitOn ["   "] lst --"   " lst
              number = map digit numbers
          in number

digit :: [String] -> Char
digit n | e <- drop 2 $ intercalate "" n
        , fingerprint <- ["|_ _ ||","|","|___ | ","_ ||","  _  ||"," ___  |","|___  |","  ||","|___ ||"," ___ ||"]
        , Just res <- elemIndex True [e == finger | finger <- fingerprint]
        = head $ show res

非常感谢@nimi的提示!


坏消息优先:恐怕您必须import Data.List在字节数中包含。好消息:a)如果已Data.Lists安装,则可以导入它,并替换asplitOn...map c$splitOn[" "]$transpose......f<-splitOn",""|_...。b)intercalate "" nconcat nid=<<n。c)res用一个字母名称代替。d)使用模式保护人民,而不是let ... inc n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0
nimi

呵呵呵,哎呀!导入在复制/粘贴中丢失了;)感谢所有提示!
J Atkin

@nimi抱歉打扰您,但是您介意解释什么=<<吗?糟糕的文档或类型签名对我都没有帮助。
J Atkin

=<<在list上下文中是concatMap,即它将给定的函数映射到列表上,并将结果组合到一个列表中。>>=一样,只是参数被翻转了。id =<< n(或n >>= id)将标识函数映射到列表(的列表)上,即对子列表不执行任何操作并将其串联。因此与相同concat
nimi
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.