Baca tampilan retro

22

Seni dicuri dari Berapa ukuran digit?


Digit 7-segmen dapat direpresentasikan dalam ASCII menggunakan _|karakter. Berikut ini digit-digitnya 0-9:

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

Tugas Anda adalah mengurai gambar menjadi angka normal.

Catatan tentang angka

  • Setiap digit memiliki lebar yang berbeda.
    • 1 memiliki lebar 1
    • 3dan 7yang 2lebar
    • 245689dan 0semuanya 3lebar

Juga antara setiap digit adalah satu karakter padding. Ini adalah set karakter lengkap:

 // <- seharusnya satu spasi, tapi format SE mengacaukannya
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

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

Memasukkan

Input dapat berupa konsol atau sebagai string arg ke suatu fungsi.

Keluaran

Output dimasukkan ke konsol atau dikembalikan dari fungsi.

Contoh:

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

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

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

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

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

Ini adalah kode-golf sehingga jumlah byte terpendek menang!

J Atkin
sumber
Terkait
J Atkin
Saya tertarik mempelajari tentang algoritma terbaik untuk menyelesaikan masalah seperti ini, dan saya mengalami kesulitan belajar dari jawaban di sini (mereka bagus, sangat ringkas). Apakah ada tempat Anda bisa merujuk saya untuk melihat penjelasan yang lebih panjang, lebih disukai dengan gambar?
Nah, cara kerja saya cukup sederhana. Ini mentranspos daftar dan loop di atasnya. Kemudian terbagi pada baris kosong. Setiap nomor diperiksa terhadap tabel sidik jari untuk setiap nomor. Yang lain bekerja sedikit seperti milik saya, kecuali bukannya tabel sidik jari mereka pada dasarnya memiliki tabel hash yang mereka gunakan.
J Atkin
Apakah ada nama yang lebih umum untuk jenis masalah ini dalam ilmu komputer?
Saya tidak tahu;)
J Atkin

Jawaban:

4

Pyth, 33 30 byte

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

Inilah idenya: Setelah kami mengubah input, dan membaginya menjadi digit, kami dapat mengurutkan hash string digit individu dan menetapkannya ke nilai-nilai mereka.

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.

Coba di sini .

lirtosiast
sumber
Keren, pada dasarnya terlihat seperti pendekatan saya tetapi jauh lebih pendek!
Lynn
@ Lynn Maaf tentang itu; pada dasarnya ada satu cara terpendek untuk melakukan ini di Pyth.
lirtosiast
4

Ruby, 184 byte

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

Penjelasan

  • mengambil input dari stdin
  • mengkonversi string ke urutan biner, 1/0 untuk segmen on / off
  • mengkodekan kolom ke nomor biner 3bit
  • mengkodekan urutan 3 angka bit menjadi 9 angka bit, gunakan kolom '0' sebagai simbol berhenti
  • gunakan tabel pencarian untuk mengonversi angka 9 bit menjadi angka

Ini adalah golf kode pertama saya. Terima kasih untuk kesenangannya!

Bog
sumber
2
Selamat datang di PPCG! Pekerjaan yang sangat bagus pada posting pertama Anda!
J Atkin
2

Pyth, 39 byte

sm@"413-928-506--7"%%Crd6C\524cjbC.z*3d

Ini sepertinya berhasil? Cobalah online .

Lynn
sumber
2

Japt, 119 byte

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!

Ya ampun, ini sangat panjang. Saya pikir saya belum selesai bermain golf.

Penjelasan

Persiapan

Kami mengambil input dan mengubahnya |_menjadi 1. Lalu kami memindahkan, menghapus ruang akhir, dan membagi dua baris baru.

Terjemahan

Kami memetakan di atas array yang dihasilkan dan menemukan indeks tempat formulir muncul dalam array referensi. Berikut diagram untuk membantu:

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

Setelah itu, kita bergabung dengan array angka dan hasil!

CATATAN : Anda mungkin bertanya-tanya mengapa kami harus mengubah setiap karakter seni ke seri 1. Ini karena sepertinya ada bug (atau sesuatu seperti itu) yang tidak membiarkan saya menyimpan karakter apa adanya |_.

Mama Fun Roll
sumber
Saya perhatikan _bug itu, tapi saya tidak tahu apa penyebabnya.
ETHproduk
OKE, "\n\n"bisa diganti dengan , dan "\\||_"dengan "%||_". Saya pikir Anda juga bisa menyimpan beberapa byte dengan pengkodean string panjang di dasar 4 (mengubah masing-masing dari 4 karakter disinctive untuk 0, 1, 2, atau 3, padding dengan panjang kelipatan dari 4, kemudian berlari r"...."_n4 d}di atasnya), tapi untuk beberapa alasan , Saya belum mendapatkan ini berfungsi.
ETHproduksi
2

Python2, 299 261 244 byte

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

Saya sangat menyukai tantangan ini, kerja bagus!

Penjelasan

Fungsi smengambil tiga baris sebagai input, ia mencoba untuk menemukan pemisahan digit (semua karakter adalah spasi). Ketika pemisahan seperti itu ditemukan itu memanggil sdengan sisa dari tiga baris dan menambahkan nilai yang dikembalikan oleh panggilan ke tiga baris yang menyusun angka. Jika tidak ada pemisahan itu berarti hanya ada satu digit.

Fungsi padalah titik masuk sehingga dibutuhkan string yang mewakili digit. Digit disimpan sebagai "hash" yang dihitung sum(ord(c)**i for i,c in enumerate("".join(n)))%108untuk menghemat ruang (terima kasih atas jawaban lain!).

Contoh

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

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

Versi lain

261 byte (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 byte, yang ini transpos baris (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
sumber
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``

Mulai dengan memecah menjadi tiga baris, memetakan kembali setiap kolom menjadi sebuah nilai, dan kemudian membangun identitas unik untuk setiap kolom dari nilai-nilai itu. Itu kemudian dibagi dengan 0(identitas untuk ruang antara kolom), dan akhirnya memetakan setiap identitas ke nilai-nilai bilangannya, yang digabungkan dan dihasilkan.

Mwr247
sumber
Sangat bagus! Saya berharap python memiliki fungsi daftar split ...
J Atkin
@JAtkin saya joined ke string sehingga saya bisa membaginya. Saya percaya Anda bisa melakukannya dengan Python juga?
Mwr247
0

Python 3, 281 254 byte

Edit

Saya hanya melihat kode untuk jawaban python lainnya dan memperhatikan bahwa banyak dari kode tersebut mirip. Ini tiba di mandiri.

(baris baru ditambahkan untuk "keterbacaan")

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

Tidak Disatukan:

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

Tes:

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

Bagaimana itu bekerja

(Catatan: Saya menjelaskan program yang tidak dikenali di sini karena lebih mudah dibaca dan memiliki kode yang sama persis, dengan pengecualian bahwa digitfungsi tersebut dimasukkan ke dalam lambda)

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

Fungsi utamanya adalah parse. Pertama membagi input menjadi beberapa baris dan menciptakan numbersarray.

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

Ini adalah bagian favorit saya (karena butuh waktu lama untuk mencari tahu). Di sini kita zipgaris sehingga kita pada dasarnya dapat melintasi input secara vertikal. Ketika baris memiliki karakter di atasnya, kita menambahkannya ke nomor terakhir dalam numbersarray. Jika tidak ada karakter di dalamnya, kami menambahkan nomor baru ke array.

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

Sangat sederhana, numbersdipetakan dengan digitfungsi dan dikonversi menjadi string.

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

Ini (cukup) sederhana. fingerprintadalah representasi string dari angka yang dibuat di atas minus 2 karakter pertama (ini adalah sidik jari terkecil yang bisa saya temukan). Kami mengembalikan indeks pertandingan pertama.

J Atkin
sumber
0

Haskell, 270 207 byte

Jangan terlalu keras, ini adalah program haskell pertama saya;) Saya hampir yakin ini bisa bermain golf lebih lanjut, tapi saya tidak tahu bagaimana mengingat pengetahuan saya yang terbatas tentang bahasa tersebut.

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

Tidak Disatukan:

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

Terima kasih banyak kepada @nimi untuk tipsnya!

J Atkin
sumber
berita buruk pertama: Saya khawatir Anda harus memasukkan import Data.Listdalam hitungan byte Anda. Berita baik: a) jika Anda telah Data.Listsmenginstal, Anda dapat mengimpornya dan menggantinya adengan splitOn: ...map c$splitOn[" "]$transpose...dan ...f<-splitOn",""|_.... b) intercalate "" nadalah concat natau id=<<n. c) ganti resdengan nama satu huruf. d) penggunaan pola penjaga bukannya let ... in: c n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0.
nimi
Hehehe, Aduh! Impor hilang dalam copy / paste;) Terima kasih atas semua tipsnya!
J Atkin
@nimi Maaf mengganggu Anda tentang hal itu, tetapi apakah Anda keberatan menjelaskan apa yang =<<terjadi? Baik hoogle docs atau tipe signature sangat membantu saya.
J Atkin
=<<dalam konteks daftar adalah concatMap, yaitu memetakan fungsi yang diberikan di atas daftar dan menggabungkan hasilnya ke dalam satu daftar. >>=melakukan hal yang sama tetapi dengan argumen terbalik. id =<< n(atau n >>= id) memetakan fungsi identitas di atas daftar (daftar), yaitu tidak melakukan apa-apa dengan sublists dan menggabungkannya. Jadi sama dengan concat.
nimi