레트로 디스플레이 읽기


22

숫자가 도난당한 예술 은?


7 세그먼트 숫자는 _|문자를 사용하여 ASCII로 표시 할 수 있습니다 . 숫자는 다음과 같습니다 0-9.

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

당신의 임무는 예술을 정상적인 숫자로 파싱하는 것입니다.

숫자에 대한 메모

  • 각 숫자는 너비가 다릅니다.
    • 1 너비가 1
    • 3하고 7있는 2다양한
    • 245689그리고 0모두 3넓다

또한 각 숫자 사이에는 하나의 패딩 문자가 있습니다. 전체 문자 세트는 다음과 같습니다.

 // <-공백이되어야하지만 SE 형식이 엉망이되었습니다.
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

입력

콘솔에서 입력하거나 함수에 대한 문자열 인수로 입력 할 수 있습니다.

산출

출력은 콘솔로 보내지거나 함수에서 리턴됩니다.

예 :

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

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

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

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

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

이것은 코드 골프이므로 가장 짧은 바이트 수가 이깁니다!



나는 이런 종류의 문제를 해결하기위한 최고의 알고리즘에 대해 배우고 싶습니다. 여기서 답변을 배우는 데 어려움을 겪고 있습니다 (좋아요, 간결합니다). 더 긴 설명, 바람직하게는 그림을 볼 수있는 장소가 있습니까?

글쎄, 내 작업 방식은 매우 간단합니다. 그것은 이항 목록을 그리고 그 위에 반복합니다. 그런 다음 빈 줄로 나뉩니다. 각 번호는 각 번호의 지문 테이블과 비교하여 확인됩니다. 다른 것들은 지문 테이블 대신 기본적으로 그들이 사용하는 해시 테이블을 가지고 있다는 점을 제외하고는 내 것과 약간 비슷하게 작동합니다.
J Atkin

컴퓨터 과학에서 이러한 유형의 문제에 대한 더 일반적인 이름이 있습니까?

나는 전혀 모른다;)
J Atkin

답변:


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.

여기에서 시도 하십시오 .


쿨, 기본적으로 내 접근 방식처럼 보이지만 훨씬 짧습니다!
Lynn

@Lynn 죄송합니다. Pyth에는 기본적으로 가장 짧은 방법이 있습니다.
lirtosiast

4

루비, 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)}

설명

  • stdin에서 입력을받습니다.
  • 문자열을 이진 시퀀스로 변환합니다 (세그먼트 켜기 / 끄기의 경우 1/0).
  • 열을 3 비트 이진수로 인코딩
  • 3 비트 숫자에서 9 비트 숫자의 시퀀스를 인코딩하고 '0'열을 정지 기호로 사용
  • 조회 테이블을 사용하여 9 비트 숫자를 숫자로 변환

이것이 나의 첫 번째 코드 골프입니다. 재미 주셔서 감사합니다!


2
PPCG에 오신 것을 환영합니다! 첫 번째 게시물에서 아주 좋은 직업!
J Atkin


2

apt, 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!

오 이런, 이건 정말 길다. 골프를 마치지 않았다고 생각합니다.

설명

예비

입력을 받아서 any |_로 변환합니다 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

확인 "\n\n"으로 대체 할 수있다 , 및 "\\||_""%||_". 당신도 할 수 기본 4 (위해 4 개 disinctive 문자의 각 변화에 긴 문자열을 인코딩하여 일부 바이트 저장 생각 0, 1, 2, 또는 34의 배수의 길이에 패딩, 다음 실행 r"...."_n4 d}위에), 그러나 어떤 이유 , 나는 아직 작동하지 않았습니다.
ETHproductions

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

자바 스크립트 (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``

먼저 세 줄로 분할하여 각 열을 값으로 다시 매핑 한 다음 해당 값에서 각 열의 고유 한 ID를 작성합니다. 그런 다음 0(열 사이의 공백에 대한 ID) 로 나누고 마지막으로 각 ID를 숫자 값에 매핑하여 연결하고 출력합니다.


아주 좋아요! 나는 파이썬이리스트 분할 기능
J Atkin

@JAtkin 나는 join그것을 나눌 수 있도록 문자열에 썼다 . 파이썬에서도 그렇게 할 수 있다고 생각합니까?
Mwr247

0

파이썬 3, 281 254 바이트

편집하다

방금 다른 파이썬 답변의 코드를 살펴본 결과 많은 코드가 비슷하다는 것을 알았습니다. 이것은 독립적으로 도착했습니다.

( "가독성"을 위해 추가 된 줄 바꿈)

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

작동 원리

(참고 : digit함수가 람다에 인라인되어있는 것을 제외하고는 더 읽기 쉽고 코드가 동일하기 때문에 ungolfed 프로그램을 여기에서 설명하고 있습니다 )

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위에 생성 된 숫자의 문자열 표시에서 처음 2자를 뺀 것입니다 (이것은 내가 찾을 수있는 가장 작은 지문이었습니다). 첫 번째 일치 색인을 반환합니다.


0

하스켈 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 n또는 id=<<n입니다. c) res단일 문자 이름으로 대체하십시오 . d) 다음 대신 패턴 가드를 사용 let ... in하십시오 c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
nimi

헤 헤헤, 으악! 복사 / 붙여 넣기에서 가져 오기가 손실되었습니다.) 모든 팁에 감사드립니다!
J Atkin

@nimi 귀찮게해서 미안하지만, 무엇을 설명하는 =<<것이 좋습니까? hoogle 문서 나 형식 서명은 나에게 큰 도움이되지 않습니다.
J Atkin

=<<리스트 컨텍스트 concatMap에서는 즉, 주어진 함수를리스트에 맵핑하고 결과를 단일리스트로 결합합니다. >>=인수가 뒤집혀도 동일하지만 동일합니다. id =<< n(또는 n >>= id)는 (목록의) 목록 위에 항등 함수를 매핑합니다. 즉, 하위 목록과 관련이 없으며 연결합니다. 따라서와 동일합니다 concat.
nimi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.