Przeczytaj wyświetlacz retro

22

Sztuka skradziona z Jakiego rozmiaru jest cyfra?


7-segmentowe cyfry mogą być reprezentowane w ASCII za pomocą _|znaków. Oto cyfry 0-9:

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

Twoim zadaniem jest parsowanie sztuki w normalne liczby.

Uwagi na temat liczb

  • Każda cyfra ma inną szerokość.
    • 1 ma szerokość 1
    • 3i 72szerokie
    • 245689i 0wszystkie są 3szerokie

Również między każdą cyfrą jest jeden znak wypełnienia. Oto pełny zestaw znaków:

 // <- powinna być jedna spacja, ale pomieszane zostało formatowanie SE
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

Wkład

Dane wejściowe mogą być albo z konsoli, albo jako ciąg argumentu do funkcji.

Wydajność

Dane wyjściowe są umieszczane w konsoli lub zwracane przez funkcję.

Przykłady:

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

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

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

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

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

To jest golf golfowy, więc wygrywa najkrótsza liczba bajtów!

J Atkin
źródło
Powiązane
J Atkin,
Interesuje mnie nauka najlepszych algorytmów do rozwiązania tego rodzaju problemów i mam trudności z uczeniem się na podstawie odpowiedzi tutaj (są dobre, po prostu bardzo zwięzłe). Czy jest miejsce, do którego możesz mnie odesłać, aby zobaczyć dłuższe wyjaśnienia, najlepiej ze zdjęciami?
Sposób, w jaki działa mój, jest dość prosty. To transponuje listę i pętle nad nim. Następnie dzieli się na puste linie. Każdy numer jest porównywany z tabelą odcisków palców dla każdego numeru. Inne działają trochę jak moje, z tym wyjątkiem, że zamiast tabeli odcisków palców mają po prostu tabelę skrótów, której używają.
J Atkin
Czy istnieje bardziej ogólna nazwa tego rodzaju problemu w informatyce?
Nie mam pojęcia;)
J Atkin

Odpowiedzi:

4

Pyth, 33 30 bajtów

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

Oto pomysł: kiedy transponujemy dane wejściowe i podzielimy je na cyfry, możemy sortować poszczególne ciągi cyfr i przypisywać je do ich wartości.

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.

Wypróbuj tutaj .

lirtosiast
źródło
Fajnie, w zasadzie wygląda jak moje podejście, ale znacznie krótsze!
Lynn
@ Lynn Przepraszamy za to; jest w zasadzie jeden najkrótszy sposób, aby to zrobić w Pyth.
lirtosiast
4

Rubinowy, 184 bajty

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

Wyjaśnienie

  • pobiera dane wejściowe ze standardowego wejścia
  • konwertuje ciągi na sekwencje binarne, 1/0 dla włączenia / wyłączenia segmentu
  • koduje kolumny do 3-bitowej liczby binarnej
  • koduje sekwencje liczb od 3 do 9 bitów, użyj kolumn „0” jako symboli stop
  • użyj tabeli odnośników, aby przekonwertować 9-bitowe liczby na cyfry

To mój pierwszy golf. Dzięki za zabawę!

bagno
źródło
2
Witamy w PPCG! Bardzo dobra robota na twoim pierwszym poście!
J Atkin
2

Japt, 119 bajtów

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!

O rany, ten jest naprawdę długi. Chyba nie skończyłem grać w golfa.

Wyjaśnienie

Przygotowanie

Pobieramy dane wejściowe i przekształcamy dowolne |_na 1. Następnie dokonujemy transpozycji, usuwamy spacje końcowe i dzielimy wzdłuż podwójnych linii.

Tłumaczenie

Mapujemy wynikową tablicę i znajdujemy indeks, w którym formularz pojawia się w tablicy referencyjnej. Oto schemat, który pomoże:

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

Następnie dołączamy do tablicy liczb i wyników!

UWAGA : Być może zastanawiasz się, dlaczego musimy zmienić każdą postać graficzną na serię 1. Jest tak, ponieważ wydaje się, że występuje błąd (lub coś w tym rodzaju), który nie pozwala mi przechowywać znaków w takim stanie, w jakim są |_.

Mama Fun Roll
źródło
Zauważyłem _błąd, ale nie wiem, co go spowodowało.
ETHprodukcje
OK, "\n\n"można zastąpić , i "\\||_"z "%||_". Myślę, że może także zaoszczędzić trochę bajtów poprzez zakodowanie długi ciąg w bazie 4 (zmiana każdego z 4 disinctive zwęgla się 0, 1, 2, lub 3, wyściółka o długości do wielokrotności 4, następnie działa r"...."_n4 d}na niego), ale z jakiegoś powodu , Nie udało mi się jeszcze tego uruchomić.
ETHprodukcje
2

Python2, 299 261 244 bajtów

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

Naprawdę podobało mi się to wyzwanie, dobra robota!

Wyjaśnienie

Funkcja sprzyjmuje trzy wiersze jako dane wejściowe, próbuje znaleźć separację cyfr (wszystkie znaki są spacjami). Po znalezieniu takiego rozdziału wzywas resztę trzech wierszy i dodaje wartość zwracaną przez wywołanie do trzech wierszy składających się na cyfrę. Jeśli nie ma separacji, oznacza to, że jest tylko jedna cyfra.

Ta funkcja pjest punktem wejścia, więc wymaga ciągu reprezentującego cyfry. Cyfry są przechowywane jako „skrót” obliczony w sum(ord(c)**i for i,c in enumerate("".join(n)))%108celu zaoszczędzenia miejsca (dzięki innym odpowiedziom!).

Przykład

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

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

Inne wersje

261 bajtów (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 bajtów, ten transponuje linie (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')))]
Dica
źródło
2

JavaScript (ES6), 169 bajtów

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

Zaczyna się od podziału na trzy linie, ponownego mapowania każdej kolumny na wartość, a następnie budowania unikatowej tożsamości dla każdej kolumny na podstawie tych wartości. Następnie dzieli się według 0(tożsamość przestrzeni między kolumnami) i ostatecznie mapuje każdą tożsamość na wartości liczbowe, które konkatenuje i wyprowadza.

Mwr247
źródło
Bardzo dobrze! Chciałbym, żeby python miał funkcję podziału listy ...
J Atkin
@JAtkin Zredagowałem joinsznurek, aby móc go podzielić. Wierzę, że możesz to zrobić również w Pythonie?
Mwr247,
0

Python 3, 281 254 bajtów

Edytować

Właśnie spojrzałem na kod dla drugiej odpowiedzi Pythona i zauważyłem, że znaczna część kodu jest podobna. Zostało to osiągnięte niezależnie.

(dodano nowe linie dla „czytelności”)

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

Nie golfowany:

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

Testy:

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

Jak to działa

(Uwaga: wyjaśniam tutaj program bez golfa, ponieważ jest bardziej czytelny i ma dokładnie ten sam kod, z wyjątkiem tego, że digitfunkcja jest wbudowana w lambda)

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

Główną funkcją jest parse. Najpierw dzieli dane wejściowe na linie i tworzy numberstablicę.

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

To moja ulubiona część (ponieważ tyle czasu zajęło jej zrozumienie). Tutaj mamy ziplinie, dzięki czemu możemy zasadniczo pionowo przechodzić dane wejściowe. Gdy wiersz zawiera znaki, dodajemy go do ostatniej liczby w numberstablicy. Jeśli nie ma na nim żadnych znaków, dodajemy nowy numer do tablicy.

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

Bardzo proste, numbersjest mapowane za pomocą digitfunkcji i konwertowane na ciąg znaków.

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

To jest (dość) proste. fingerprintto ciąg znaków cyfr utworzonych powyżej minus 2 pierwsze znaki (był to najmniejszy odcisk palca, jaki udało mi się znaleźć). Zwracamy indeks pierwszego dopasowania.

J Atkin
źródło
0

Haskell, 270 207 bajtów

Nie bądź zbyt trudny, to mój pierwszy program haskell;) Jestem prawie pewien, że można dalej grać w golfa, ale nie wiem, skąd moja ograniczona znajomość języka.

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

Nie golfowany:

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

Ogromne podziękowania dla @nimi za wskazówki!

J Atkin
źródło
najpierw złe wiadomości: obawiam się, że musisz uwzględnić import Data.Listliczbę bajtów. Dobre wiadomości: a) jeśli zostały Data.Listszainstalowane można go importować i zastąpić zamiast az splitOn: ...map c$splitOn[" "]$transpose...a ...f<-splitOn",""|_.... b) intercalate "" njest concat nlub id=<<n. c) zastąpić resjedną literą. d) stosowanie wzorca strzeże zamiast let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
nimi
Hehehe, Ups! Import został utracony w kopiowaniu / wklejaniu;) Dzięki za wszystkie wskazówki!
J Atkin
@nimi Przepraszam, że przeszkadzam, ale czy masz coś przeciwko wytłumaczeniu, co =<<robi? Ani dokumenty hoogle, ani podpis typu nie są dla mnie bardzo pomocne.
J Atkin
=<<w kontekście listy jest to concatMap, że mapuje daną funkcję na liście i łączy wyniki w jedną listę. >>=robi to samo, ale z odrzuconymi argumentami. id =<< n(lub n >>= id) odwzorowuje funkcję tożsamości na liście (listach), tzn. nie robi nic z listami podrzędnymi i łączy je. Więc to jest tak samo jak concat.
nimi