Lesen Sie ein Retro-Display


22

Kunst gestohlen von Wie groß ist die Ziffer?


7-Segment-Ziffern können in ASCII mit _|Zeichen dargestellt werden. Hier sind die Ziffern 0-9:

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

Ihre Aufgabe ist es, die Kunst in normale Zahlen zu zerlegen.

Hinweise zu Zahlen

  • Jede Ziffer hat eine andere Breite.
    • 1 hat eine Breite von 1
    • 3und 7sind 2breit
    • 245689und 0sind alle 3breit

Außerdem steht zwischen jeder Ziffer ein Zeichen zum Auffüllen. Hier ist der vollständige Zeichensatz:

 // <- sollte ein Leerzeichen sein, aber die SE-Formatierung hat es durcheinander gebracht
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

Eingang

Die Eingabe kann entweder über die Konsole oder als String-Argument für eine Funktion erfolgen.

Ausgabe

Die Ausgabe wird entweder an die Konsole gesendet oder von der Funktion zurückgegeben.

Beispiele:

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

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

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

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

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

Das ist Code-Golf, also gewinnt die kürzeste Anzahl an Bytes!



Ich bin daran interessiert, die besten Algorithmen zur Lösung dieses Problems zu lernen, und ich habe Schwierigkeiten, aus den Antworten hier zu lernen (sie sind gut, nur sehr präzise). Gibt es einen Ort, an den Sie mich verweisen können, um ausführlichere Erklärungen, vorzugsweise mit Bildern, zu sehen?

Nun, meine Arbeitsweise ist ziemlich einfach. Es transponiert die Liste und durchläuft sie. Es wird dann in leere Zeilen aufgeteilt. Jede Nummer wird mit einer Fingerabdrucktabelle für jede Nummer verglichen. Die anderen funktionieren ein bisschen wie meine, nur dass sie anstelle einer Fingerabdrucktabelle grundsätzlich eine Hash-Tabelle verwenden.
J Atkin

Gibt es einen allgemeineren Namen für diese Art von Problem in der Informatik?

Ich habe keine Ahnung;)
J Atkin

Antworten:


4

Pyth, 33 30 Bytes

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

Hier ist die Idee: Sobald wir die Eingabe transponiert und in Ziffern aufgeteilt haben, können wir die einzelnen Ziffernfolgen sortieren und ihnen ihre Werte zuweisen.

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.

Probieren Sie es hier aus .


Cool, sieht im Grunde nach meiner Herangehensweise aus, ist aber viel kürzer!
Lynn

@Lynn Entschuldigung; Es gibt im Grunde einen kürzesten Weg, dies in Pyth zu tun.
Lirtosiast

4

Ruby, 184 Bytes

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

Erläuterung

  • nimmt die Eingabe von stdin
  • wandelt die Strings in binäre Sequenzen um, 1/0 für Segment ein / aus
  • codiert Spalten in 3-Bit-Binärzahlen
  • Codiert Sequenzen von 3-Bit-Nummern bis 9-Bit-Nummern. Verwenden Sie '0'-Spalten als Stoppsymbole
  • Verwenden Sie eine Nachschlagetabelle, um die 9-Bit-Zahlen in Ziffern umzuwandeln

Dies ist mein erster Code-Golf. Danke für den Spaß!


2
Willkommen bei PPCG! Sehr schöne Arbeit bei Ihrem ersten Beitrag!
J Atkin


2

Japt, 119 Bytes

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!

Oh meine Güte, das ist wirklich lang. Ich glaube nicht, dass ich mit dem Golfen fertig bin.

Erläuterung

Vorbereitung

Wir nehmen die Eingabe auf und konvertieren sie |_in 1. Dann transponieren wir, entfernen endende Leerzeichen und teilen sie entlang doppelter Zeilenumbrüche.

Übersetzung

Wir ordnen das resultierende Array zu und finden den Index, in dem das Formular in einem Referenz-Array erscheint. Hier ist ein Diagramm, um zu helfen:

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

Danach verbinden wir die Zahlenreihe und geben aus!

HINWEIS : Sie fragen sich möglicherweise, warum wir jedes Kunstzeichen in eine Reihe von Einsen ändern müssen. Das liegt daran, dass es einen Bug (oder so etwas) zu geben scheint, der es mir nicht erlaubt, die Zeichen so zu speichern, wie sie sind |_.


Ich habe den _Fehler bemerkt , aber ich weiß nicht, was ihn verursacht hat.
ETHproductions

OK, "\n\n"kann durch und "\\||_"durch ersetzt werden "%||_". Ich denke , man könnte auch einige Bytes speichern durch Codieren der langen Schnur in der Basis 4 (jeder der 4 disinctive Zeichen Wechsel auf 0, 1, 2, oder 3, Polsterung auf eine Länge von einem Vielfachen von 4, dann läuft r"...."_n4 d}über sie), aber aus irgendeinem Grund Ich habe das noch nicht zum Laufen bekommen.
ETHproductions

2

Python2, 299 261 244 Bytes

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

Diese Herausforderung hat mir sehr gut gefallen, gute Arbeit!

Erläuterung

Die Funktion verwendet sdie drei Zeilen als Eingabe und versucht, eine Zifferntrennung zu finden (alle Zeichen sind Leerzeichen). Wenn eine solche Trennung gefunden wird, ruft es smit den übrigen drei Zeilen auf und addiert den vom Aufruf zurückgegebenen Wert zu den drei Zeilen, aus denen sich die Ziffer zusammensetzt. Wenn es keine Trennung gibt, bedeutet dies, dass es nur eine Ziffer gibt.

Die Funktion pist der Einstiegspunkt, daher wird eine Zeichenfolge verwendet, die die Ziffern darstellt. Die Ziffern werden als "Hash" gespeichert sum(ord(c)**i for i,c in enumerate("".join(n)))%108, um Platz zu sparen (dank anderer Antworten!).

Beispiel

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

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

Andere Versionen

261 Bytes (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 Bytes, dieses transponiert die Zeilen (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 Byte

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

Beginnt mit der Aufteilung in drei Zeilen, dem erneuten Zuordnen jeder Spalte zu einem Wert und dem Erstellen einer eindeutigen Identität für jede Spalte aus diesen Werten. Es teilt sich dann durch 0(die Identität für den Raum zwischen den Spalten) und ordnet schließlich jede Identität ihren Zahlenwerten zu, die es verkettet und ausgibt.


Sehr schön! Ich wünschte, Python hätte eine Listensplit-Funktion ...
J Atkin

@JAtkin Ich habe joineine Zeichenfolge erstellt, damit ich sie teilen kann. Ich glaube, Sie könnten das auch in Python tun?
Mwr247

0

Python 3, 281 254 Bytes

Bearbeiten

Ich habe mir gerade den Code für die andere Python-Antwort angesehen und festgestellt, dass ein Großteil des Codes ähnlich ist. Dies wurde unabhängig erreicht.

(Zeilenumbrüche für "Lesbarkeit" hinzugefügt)

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

Ungolfed:

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

Tests:

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

Wie es funktioniert

(Hinweis: Ich erkläre das ungolfed Programm hier, da es besser lesbar ist und genau denselben Code hat, mit der Ausnahme, dass die digitFunktion in ein Lambda eingebettet ist. )

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

Die Hauptfunktion ist parse. Zunächst wird die Eingabe in Zeilen aufgeteilt und das numbersArray erstellt.

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

Dies ist mein Lieblingsteil (da es so lange gedauert hat, es herauszufinden). Hier haben wir zipdie Linien, so dass wir die Eingabe im Grunde vertikal durchlaufen können. Wenn die Zeile Zeichen enthält, fügen wir sie zur letzten Zahl im numbersArray hinzu. Wenn es keine Zeichen enthält, fügen wir dem Array eine neue Nummer hinzu.

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

Wirklich einfach, numberswird mit der digitFunktion abgebildet und in einen String umgewandelt.

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

Das ist (ziemlich) einfach. fingerprintist die Zeichenfolgendarstellung der oben erstellten Ziffern abzüglich der ersten zwei Zeichen (dies war der kleinste Fingerabdruck, den ich finden konnte). Wir geben den Index des ersten Matches zurück.


0

Haskell, 270 207 Bytes

Seien Sie nicht zu hart, dies ist mein erstes Haskell-Programm;) Ich bin mir fast sicher, dass dies weiter verbessert werden kann, aber ich weiß nicht, wie ich es tun soll, wenn ich nur begrenzte Sprachkenntnisse habe.

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

Ungolfed:

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

Vielen Dank an @nimi für die Tipps!


schlechte Nachrichten zuerst: Ich fürchte, Sie müssen das import Data.Listin Ihre Byteanzahl einschließen . Gute Nachrichten: a) wenn Sie Data.Listsinstalliert haben , können sie stattdessen importieren und ersetzen amit splitOn: ...map c$splitOn[" "]$transpose...und ...f<-splitOn",""|_.... b) intercalate "" nist concat noder id=<<n. c) durch reseinen einzelnen Buchstaben ersetzen . d) Verwendung Muster schützen statt let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
Nimi

Hehehe, Hoppla! Der Import ging beim Kopieren / Einfügen verloren;) Danke für alle Tipps!
J Atkin

@nimi Tut mir leid, Sie zu stören, aber haben Sie etwas dagegen zu erklären, was =<<tut? Weder die Google-Dokumente noch die Typensignatur sind für mich sehr hilfreich.
J Atkin

=<<im Listenkontext heißt concatMap, es bildet die gegebene Funktion über die Liste ab und fasst die Ergebnisse zu einer einzigen Liste zusammen. >>=macht das selbe aber mit umgedrehten argumenten. id =<< n(oder n >>= id) ordnet die Identitätsfunktion der Liste (der Listen) zu, dh es wird nichts mit den Unterlisten und den verketteten Listen gemacht. So ist es das gleiche wie concat.
nimi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.