Lire un affichage rétro

22

Art volé De quelle taille est le chiffre?


Les chiffres à 7 segments peuvent être représentés en ASCII à l'aide de _|caractères. Voici les chiffres 0-9:

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

Votre travail consiste à analyser l'art en nombres normaux.

Remarques sur les chiffres

  • Chaque chiffre a une largeur différente.
    • 1 a une largeur de 1
    • 3et 7sont 2larges
    • 245689et 0sont tous 3larges

Entre chaque chiffre se trouve également un caractère de remplissage. Voici l'ensemble complet de caractères:

 // <- devrait être un espace, mais le formatage SE l'a gâché
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

Contribution

L'entrée peut être soit à partir de la console, soit sous forme d'argument de chaîne vers une fonction.

Production

La sortie est soit placée dans la console, soit renvoyée par la fonction.

Exemples:

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

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

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

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

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

C'est le golf par code donc le nombre d'octets le plus court gagne!

J Atkin
la source
En relation
J Atkin
Je suis intéressé à découvrir les meilleurs algorithmes pour résoudre ce type de problème, et j'ai du mal à apprendre des réponses ici (elles sont bonnes, juste très concises). Y a-t-il un endroit où vous pouvez me référer pour voir des explications plus longues, de préférence avec des photos?
Eh bien, la façon dont la mienne fonctionne est assez simple. Il transpose la liste et boucle dessus. Il se divise ensuite sur des lignes vides. Chaque numéro est comparé à une table d'empreintes digitales pour chaque numéro. Les autres fonctionnent un peu comme le mien, sauf qu'au lieu d'une table d'empreintes digitales, ils ont essentiellement une table de hachage qu'ils utilisent.
J Atkin
Existe-t-il un nom plus général pour ce type de problème en informatique?
Je n'en ai aucune idée;)
J Atkin

Réponses:

4

Pyth, 33 30 octets

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

Voici l'idée: une fois que nous avons transposé l'entrée et divisé en chiffres, nous pouvons trier les chaînes de chiffres individuelles et les affecter à leurs valeurs.

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.

Essayez-le ici .

lirtosiast
la source
Cool, ressemble à mon approche mais beaucoup plus court!
Lynn
@Lynn Désolé à ce sujet; il y a essentiellement un moyen le plus court de le faire en Pyth.
lirtosiast
4

Rubis, 184 octets

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

Explication

  • prend l'entrée de stdin
  • convertit les chaînes en séquences binaires, 1/0 pour activer / désactiver le segment
  • code les colonnes en nombre binaire 3 bits
  • code des séquences de nombres de 3 bits à 9 bits, utilisez les colonnes «0» comme symboles d'arrêt
  • utiliser une table de correspondance pour convertir les nombres de 9 bits en chiffres

Ceci est mon premier code-golf. Merci pour le plaisir!

bogl
la source
2
Bienvenue chez PPCG! Très beau travail sur votre premier post!
J Atkin
2

Japt, 119 octets

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 bon sang, celui-ci est vraiment long. Je ne pense pas avoir fini de jouer au golf.

Explication

Préparation

Nous prenons l'entrée et convertissons tout |_en 1. Ensuite, nous transposons, supprimons les espaces de fin et divisons le long de doubles retours à la ligne.

Traduction

Nous mappons sur le tableau résultant et trouvons l'index où le formulaire apparaît dans un tableau de référence. Voici un diagramme pour vous aider:

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

Après cela, nous joignons le tableau de nombres et sortons!

REMARQUE : vous vous demandez peut-être pourquoi nous devons changer chaque personnage artistique en une série de 1. C'est parce qu'il semble y avoir un bug (ou quelque chose comme ça) qui ne me permet pas de stocker les personnages tels quels |_.

Mama Fun Roll
la source
J'ai remarqué le _bug, mais je ne sais pas ce qui l'a provoqué.
ETHproductions
OK, "\n\n"peut être remplacé par , et "\\||_"par "%||_". Je pense que vous pouvez aussi sauver quelques octets par codant pour la longue chaîne dans la base 4 (changer chacune des 4 caractères disinctive à 0, 1, 2ou 3, rembourrage à une longueur d'un multiple de 4, puis en cours d' exécution r"...."_n4 d}au - dessus), mais pour une raison , Je ne l'ai pas encore fait fonctionner.
ETHproductions
2

Python2, 299 261 244 octets

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

J'ai vraiment aimé ce défi, bon travail!

Explication

La fonction sprend les trois lignes en entrée, elle essaie de trouver une séparation des chiffres (tous les caractères sont des espaces). Lorsqu'une telle séparation est trouvée, elle appelle savec le reste des trois lignes et ajoute la valeur renvoyée par l'appel aux trois lignes qui composent le chiffre. S'il n'y a pas de séparation, cela signifie qu'il n'y a qu'un seul chiffre.

La fonction pest le point d'entrée et prend donc une chaîne qui représente les chiffres. Les chiffres sont stockés comme un "hachage" calculé avec sum(ord(c)**i for i,c in enumerate("".join(n)))%108pour économiser de l'espace (grâce à d'autres réponses!).

Exemple

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

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

Autres versions

261 octets (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 octets, celui-ci transpose les lignes (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
la source
2

JavaScript (ES6), 169 octets

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

Commence par se diviser en trois lignes, remapper chaque colonne en une valeur, puis créer une identité unique pour chaque colonne à partir de ces valeurs. Il se divise ensuite par0 (l'identité de l'espace entre les colonnes), et mappe finalement chaque identité à ses valeurs numériques, qu'il concatène et génère.

Mwr247
la source
Très agréable! Je souhaite que python ait une fonction de partage de liste ...
J Atkin
@JAtkin J'ai joinédité une chaîne afin de pouvoir la diviser. Je pense que vous pourriez aussi le faire en Python?
Mwr247
0

Python 3, 281 254 octets

modifier

J'ai juste regardé le code de l'autre réponse python et j'ai remarqué qu'une grande partie du code est similaire. Cela a été conclu indépendamment.

(ajout de nouvelles lignes pour "lisibilité")

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

Non golfé:

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

Comment ça marche

(Remarque: j'explique le programme non golfé ici car il est plus lisible et il a exactement le même code, à l'exception que la digitfonction est intégrée dans un lambda)

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

La fonction principale est parse. Il divise d'abord l'entrée en lignes et crée le numberstableau.

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

C'est ma partie préférée (car il a fallu si longtemps pour comprendre). Ici, nous avons ziples lignes afin que nous puissions essentiellement traverser verticalement l'entrée. Lorsque la ligne contient des caractères, nous l'ajoutons au dernier numéro du numberstableau. S'il ne contient aucun caractère, nous ajoutons un nouveau numéro au tableau.

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

Vraiment simple, numbersest mappé avec la digitfonction et est converti en chaîne.

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

C'est (assez) simple. fingerprintest la représentation sous forme de chaîne des chiffres créés ci-dessus moins les 2 premiers caractères (c'était la plus petite empreinte digitale que j'ai pu trouver). Nous retournons l'index de la première correspondance.

J Atkin
la source
0

Haskell, 270 207 octets

Ne soyez pas trop dur, c'est mon tout premier programme haskell;) Je suis presque certain que cela peut être approfondi, mais je ne sais pas comment étant donné ma connaissance limitée de la langue.

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

Non golfé:

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

Un grand merci à @nimi pour les conseils!

J Atkin
la source
mauvaises nouvelles d'abord: je crains que vous ne deviez inclure le import Data.Listdans votre nombre d'octets. Bonne nouvelle: a) si vous l'avez Data.Listsinstallé, vous pouvez l'importer à la place et le remplacer apar splitOn: ...map c$splitOn[" "]$transpose...et ...f<-splitOn",""|_.... b) intercalate "" nest concat nou id=<<n. c) remplacer respar un nom à une seule lettre. d) profil d'emploi garde au lieu de let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
nimi
Hehehe, Oups! L'import a été perdu dans le copier / coller;) Merci pour tous les conseils!
J Atkin
@nimi Désolé de vous déranger, mais ça vous dérange d'expliquer ce que =<<ça fait? Ni les documents hoogle ni la signature de type ne me sont très utiles.
J Atkin
=<<dans le contexte de la liste concatMap, c'est-à-dire qu'il mappe la fonction donnée sur la liste et combine les résultats en une seule liste. >>=fait de même mais avec les arguments retournés. id =<< n(ou n >>= id) mappe la fonction d'identité sur la liste (des listes), c'est-à-dire ne fait rien avec les sous-listes et les concatène. C'est donc la même chose que concat.
nimi