Retro ekran oku


22

Çalınan Sanat Rakam nedir?


7 segmentli rakamlar ASCII'de _|karakterler kullanılarak gösterilebilir . İşte rakamlar 0-9:

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

İşiniz, sanatın normal sayılara ayrıştırılmasıdır.

Rakamlarla ilgili notlar

  • Her hane farklı bir genişliğe sahiptir.
    • 1 genişliğine sahiptir 1
    • 3ve 7vardır 2geniş
    • 245689ve 0hepsi 3geniş

Ayrıca her hane arasında bir dolgu maddesi bulunur. İşte tam char seti:

 // <- bir boşluk olmalı, fakat SE formatı karışık
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

Giriş

Giriş, konsoldan veya bir işleve dize argümanı olabilir.

Çıktı

Çıkışı konsola koyar veya işlevden döndürülür.

Örnekler:

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

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

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

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

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

Bu kod golf çok kısa bayt sayısı kazanır!



Bu tür bir sorunu çözmek için en iyi algoritmaları öğrenmekle ilgileniyorum ve buradaki yanıtları öğrenmekte zorluk çekiyorum (bunlar iyi, çok özlü). Tercihen resimlerle daha uzun açıklamalar görmek için beni önerebileceğiniz bir yer var mı?

Benimki çalışma şekli oldukça basittir. Bu transposes listesi ve üzerinde döngüler. Daha sonra boş satırlara bölünür. Her numara, her numara için bir parmak izi tablosuna göre kontrol edilir. Diğerleri biraz benimki gibi çalışıyor, parmak izi tablosu yerine, temelde kullandıkları bir karma tablo var.
J Atkin

Bilgisayar biliminde bu tür bir problem için daha genel bir isim var mı?

Hiç bir fikrim yok;)
J Atkin

Yanıtlar:


4

Pyth, 33 , 30 bayt

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

İşte fikir: Girdiyi dönüştürdüğümüzde ve rakamlara böldüğümüzde, tek tek rakam dizelerini elde edip değerlerine atayabiliriz.

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.

Burada dene .


Harika, temelde benim yaklaşımım gibi görünüyor ama çok daha kısa!
Lynn

@Lynn Bunun için üzgünüm; Bunu Pyth'ta yapmanın en kısa bir yolu var.
lirtosiast

4

Ruby, 184 bayt

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

açıklama

  • girdiyi stdin'den alıyor
  • dizeleri ikili sıralara dönüştürür, bölüm açık / kapalı için 1/0
  • sütunları 3bit ikili sayıya kodlar
  • 3 bitlik sayıları 9 bitlik sayıları kodlar, durma sembolleri olarak '0' sütunu kullanın
  • 9 bitlik sayıları sayılara çevirmek için arama tablosu kullanın.

Bu benim ilk kod-golf'üm. Eğlence için teşekkürler!


2
PPCG'ye Hoşgeldiniz! İlk gönderinizde çok iyi iş çıkardınız!
J Atkin


2

Japt, 119 bayt

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!

Tanrım, bu çok uzun. Golf oynamayı bitirdiğimi sanmıyorum.

açıklama

Hazırlık

Biz girdi almak ve herhangi dönüştürmek |_için1 . Sonra transpoze ediyoruz, bitiş boşluklarını çıkarıyoruz ve çift yeni satırlara bölün.

Çeviri

Elde edilen dizinin üzerinde eşlenir ve formun bir referans dizisinde göründüğü dizini buluruz. İşte size yardımcı olacak bir şema:

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

Ondan sonra sayı ve çıktı dizisine katılıyoruz!

NOT : Her bir sanat karakterini neden bir dizi karaktere dönüştürmek zorunda olduğumuzu merak ediyor olabilirsiniz. Bunun nedeni, karakterleri olduğu gibi saklamama izin vermeyen bir böcek (veya bunun gibi bir şey) gibi gözüküyor |_.


Böceği fark ettim _ama neye neden olduğunu bilmiyorum.
ETHProductions

Tamam, ve ile "\n\n"değiştirilebilir . Ben de olabilir tabana 4 (4 disinctive karakterlerin her değişmesinde uzun dize kodlayan bazı bayt tasarruf düşünüyorum , , , veya , 4 kişilik bir çoklu bir uzunluğa dolgu, daha sonra çalışan üzerine), ama nedense , Bunu henüz işe almadım. "\\||_""%||_"0123r"...."_n4 d}
ETHProductions

2

Python2, 299 261 244 bayt

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

Bu meydan okumayı gerçekten sevdim, iyi iş!

açıklama

İşlev s, üç satırı giriş olarak alır, bir rakam ayrımı bulmaya çalışır (tüm karakterler boşluktur). Böyle bir ayırım bulunduğunda çağırırs , üç satırın kalanıyla çağırır ve çağrının döndürdüğü değeri, basamağı oluşturan üç satıra ekler. Ayırma yoksa, sadece bir rakam olduğu anlamına gelir.

İşlev pgiriş noktasıdır, bu nedenle rakamları temsil eden bir dize alır. Rakamlar yer sum(ord(c)**i for i,c in enumerate("".join(n)))%108kazanmak için hesaplanan bir "karma" olarak depolanır (diğer cevaplar sayesinde!).

exemple

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

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

Diğer sürümleri

261 bayt (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 bayt, bu satırları dönüştürür (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 bayt

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

Üç satıra bölünerek başlar, her sütunu bir değere yeniden ekler ve sonra bu değerlerden her sütun için benzersiz bir kimlik oluşturur. Sonra bölüştürür 0(sütunlar arasındaki boşluğun kimliği) ve sonunda her bir kimliği birleştirip çıktıladığı sayı değerleriyle eşleştirir.


Çok hoş! Python'un bir list split fonksiyonu olsaydı ...
J Atkin

@ Jakin joinBir dizgeye girdim, böylelikle bölebilecektim. Bunu Python'da da yapabileceğinizi düşünüyorum.
Mwr247

0

Python 3, 281 254 bayt

Düzenle

Sadece diğer python cevap koduna baktım ve kodun çoğunun benzer olduğunu fark ettim. Bu bağımsız olarak geldi.

("okunabilirlik" için yeni satırlar eklendi)

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

Testler:

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

Nasıl çalışır

(Not: daha okunabilir ve bu istisna ile, tam aynı kodu vardır çünkü burada ungolfed programı anlatıyorum digitfonksiyonu içinde çizgili bir lambda içine)

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

Ana işlevi parse. Önce girişi satırlara böler ve numbersdiziyi oluşturur .

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

Bu benim favori bölümüm (çözmem çok uzun sürdüğü için). Burada biz zipsatırlarız, böylece girdiyi dikey olarak geçebiliriz. Satırda karakter varsa, numbersdizideki son sayıya ekleriz . Üzerinde herhangi bir karakter yoksa, diziye yeni bir sayı ekleriz.

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

Gerçekten basit, fonksiyonla numberseşleştirilir digitve bir dizgeye dönüştürülür.

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

Bu (oldukça) basittir. fingerprintYukarıda oluşturulan rakamların eksi ilk 2 karakterden oluşan dize temsilidir (bu bulabildiğim en küçük parmak izi idi). İlk karşılaşmanın endeksini döndürdük.


0

Haskell, 270 207 bayt

Çok zor olmayın, bu benim ilk haskell programım;) Neredeyse bunun daha fazla golf oynayabileceğinden eminim, ancak dil konusundaki sınırlı bilgimi nasıl verdiğimi bilmiyorum.

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

İpuçları için @ nimi'ye teşekkürler!


ilk önce kötü haber: Korkarım ki import Data.Listbayt sayıma dahil etmelisin. İyi haber: a) varsa Data.Listsyüklü yerine içe ve yerini alabilir aile splitOn: ...map c$splitOn[" "]$transpose...ve ...f<-splitOn",""|_.... b) intercalate "" nbir concat nya da id=<<n. c) restek harfli bir harf ile değiştirin . d) kullanım modeli yerine korur let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
nimi

Hehehe, Whoops! İçe aktarma kopyala / yapıştır içinde kayboldu;) Tüm ipuçları için teşekkürler!
J Atkin,

@nimi Sizi rahatsız ettiğim için üzgünüm, peki ne yaptığını açıklıyor =<<musunuz? Ne hoogle dokümanlar ne de tür imzası bana çok yardımcı olmaz.
J Atkin

=<<liste bağlamında concatMapverilen işlevi listenin üzerinde eşleştirir ve sonuçları tek bir listede birleştirir. >>=aynısını yapar, ancak argümanları ters çevirir. id =<< n(veya n >>= id) kimlik işlevini listenin (listelerin) üzerinden eşler, yani alt listelerle ve birleştirerek hiçbir şey yapmaz. Yani aynı concat.
nimi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.