Grafis braille

46

Potong matriks boolean di 4x2 blok dan membuat mereka sebagai karakter Braille U+2800... U+28FF.

[[0,1,0,0,1,0],
 [1,0,0,0,0,0],
 [1,0,0,0,1,0],
 [1,1,1,1,0,0]]

⣎⣀⠅

Pad dengan 0-s jika dimensi bukan kelipatan 4 dan 2.

[[0,1,0],
 [1,0,0],
 [1,1,1]]

⠮⠄

Aturan golf biasa berlaku, fleksibel pada format input. Keluaran harus memiliki struktur matriks atau terlihat seperti matriks, misalnya daftar string; string tunggal dengan baris baru.

Petunjuk: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)adalah pola titik

b0 b3
b1 b4
b2 b5
b6 b7

Tes yang lebih besar:

[[0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0],
 [0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1],
 [0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,0,0,0,1],
 [1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,1],
 [1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1,0],
 [1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0],
 [1,1,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0],
 [1,1,0,1,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,1,1,1,1],
 [1,1,0,1,1,1,1,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,0],
 [1,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,0,1,1,0,0],
 [1,1,0,0,0,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,1,0,0],
 [1,1,0,0,0,1,1,0,1,0,0,0,1,0,1,1,1,0,0,1,1,0,0],
 [0,1,1,0,1,1,1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0],
 [0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,0,1,1,1,0,0],
 [0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,1,1,1,1,0]]

⣰⠟⠻⣦⠀⠠⠾⡇⢠⡞⢛⡆
⣿⢠⣬⣥⠄⣀⠀⡇⢈⣻⣈⡀
⣿⠘⢹⡇⡞⠙⡇⣧⡉⢹⡏⠀
⠘⠷⠟⠁⠳⠾⠃⠘⠇⠾⠧⠀
ngn
sumber
Selamat atas tantangan kedua.
Adám
5
Deskripsi yang lebih baik: Anda memiliki larik 2D nilai Boolean yang barisnya mewakili garis raster horizontal penyangga bingkai hitam-putih (1 bit per piksel) atau kanvas grafis. Encode semua blok persegi panjang 4x2 dari kanvas ini menjadi karakter Unicode Braille. Untuk menangani blok fraksional di tepi, pad lebar kanvas ke kelipatan 2, dan tinggi ke kelipatan empat, dengan nol (atau memastikan output setara, memperlakukan data seolah-olah itu begitu empuk).
Kaz
3
@ Ka, saya tidak tahu, saya pribadi sangat menghargai betapa ringkasnya postingan ini. IMO, tidak banyak kejelasan akan ditambahkan dengan menulis lagi (selain beberapa klarifikasi kecil seperti mencatat bahwa tingginya harus mult 4 dan lebar 2); saran Anda lebih sulit bagi saya untuk membaca daripada posting saat ini.
Quelklef

Jawaban:

10

Jelly ,  31  30 byte

sz0Z
ç€2ZF€ç€8Zœ?@€€-36Ḅ+⁽$ṁỌY

Cobalah online!

Bagaimana?

sz0Z - Link 1, split & right-pad with zeros: list, items; number, chunkSize
s    - split items into chunks of length chunkSize
 z0  - transpose with filler zero
   Z - transpose

ç€2ZF€ç€8Zœ?@€€-36Ḅ+⁽$ṁỌY - Main link: list of lists of numbers (1s & 0s), M
ç€2                       - call the last link (1) as a dyad for €ach (left=M, right=2)
                          -  ((left,right) bits read left-right then top-bottom)
   Z                      - transpose the resulting list of lists of lists
                          -  ((left, right) bits read top-bottom then left-right)
    F€                    - flatten €ach
      ç€8                 - call the last link (1) as a dyad for €ach (left=^, right=8)
         Z                - transpose the resulting list of lists of lists
                          -  ("blocks" each and all read left-right top-to bottom)
               -36        - literal -36
             €€           - for €ach (block-wise row) for €ach (block)
          œ?@             -   lexicographical permutation with reversed arguments
                          -    (get the permutation at index -36 (modular) in a list of
                          -     all permutations of the indexes sorted lexicographically.
                          -     That is the 8!-36 = 40284th - equivalently the values at
                          -     indexes [8,7,6,4,2,5,3,1])
                  Ḅ       - convert from binary list to integer (vectorises)
                    ⁽$ṁ   - base 250 literal = 10240
                   +      - add
                       Ọ  - cast to character (vectorises)
                        Y - join with newlines
                          - implicit print
Jonathan Allan
sumber
Apakah dukungan "angka" lebih besar dari 1? Alih-alih menambahkan 10240 (0x2800 - dua byte) ke hasilnya, Anda bisa menambahkan 40 (0x28 - satu byte) ke vektor digit biner. Saya tidak tahu banyak tentang Jelly, jadi saya tidak yakin apakah ini akan berhasil.
ngn
memang akan mengkonversi digit terdepan dari 40 seperti yang Anda sarankan, tetapi kita perlu menambahkannya ke setiap daftar tersebut (pada kedalaman 2) yang, saya pikir, akan membutuhkan lebih banyak byte kode ( ;@€€40Ḅ).
Jonathan Allan
6

JavaScript ES7 210 207 201 200 198 194 185 183 byte

a=>eval('for(y=0,c="";A=a[y];y+=4,c+=`\n`)for(x=0;A[x]+1;x+=2)c+=String.fromCharCode(10240+eval("for(N=k=0;k<6;k++)N+=(g=(X,Y=3)=>(a[Y+y]||0)[X+x]|0)(k>2,k%3)*2**k")|g(0)+g(1)*2<<6)')

4 byte disimpan berkat ngn

3 byte disimpan berkat Luke

Bagaimana itu bekerja

Saya akan membagi kode menjadi beberapa bagian dan membicarakannya secara terpisah:

for(y=x=0, c=""; a[y]; x+=2)
    !((a[y] || [])[x]+1) && (y+=4,x=0,c+=`\n`)

Di sinilah setiap variabel dideklarasikan. xdan yadalah posisi "cursor" (tepi kiri atas karakter braille saat ini). Koordinat x meningkat 2 setiap iterasi, dan berhenti, ketika tidak ada baris dengan indeks y(a [x] kembaliundefined jika tidak ada, yang akan dikonversi ke false).

Ada beberapa trik di baris kedua. (a[y] || [])[x]memastikan bahwa mencari nilai pada (x, y)posisi tidak menimbulkan kesalahan. Ini &&adalah yang biasa dan operator, dan hanya memeriksa sisi kanan ekspresi, jika yang kiri benar. Ini dapat diterjemahkan ke

if (!((a[y] || [])[x] + 1)) 
    y+=4,x=0,c+=`\n`

Bagian selanjutnya:

c+=String.fromCharCode(10240+eval("for(N=k=0;k<6;k++)N+=(g=(x,y)=>(a[y]||[])[x]||0)(~~(k/3)+x,k%3+y)*2**k,N")+g(x,y+3)*64+g(x+1,y+3)*128)

String.fromCharCodecukup konversi nomor yang diteruskan ke karakter unicode dengan kode karakter yang sama. Ekspresi dalam tanda kurung menghitung indeks karakter Braille:

for(N=k=0;k<6;k++)N+=(g=(x,y)=>(a[y]||[])[x]||0)(~~(k/3)+x,k%3+y)*2**k

Pergi melalui posisi di

1 4
2 5
3 6

memesan, mengalikan nilai pada posisi-posisi tersebut dengan 2 i , di mana i adalah indeks dan menambahkannya bersama-sama. Itu

g=(x,y)=>(a[y]||[])[x]||0

bagian menyatakan fungsi lambda disebut g, yang diberi xdan ymengoordinasikan mengembalikan nilai pada (x, y)posisi atau 0 jika posisi terletak di luar batas array.

+g(x,y+3)*64+g(x+1,y+3)*128

Bagian ini menambahkan dua posisi terakhir dengan bobot yang benar menggunakan fungsi yang didefinisikan sedikit lebih awal.

Terakhir,

a=>eval('...')

bagian memiliki 2 fungsi. Ini mendefinisikan lambda anonim dan memastikan, untuk loop tidak menyebabkan masalah (satu baris lambda seperti ini tidak dapat berisi satu untuk loop saja, evaluasi mengelak dari ini).

Bálint
sumber
beberapa saran sederhana: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(mengganti +-s dengan |-s)
ngn
Mengapa tidak mengirimkan versi ES7 sebagai solusi utama Anda?
Shaggy
@ Shaggy Tidak semua orang bisa menjalankan ES7, jadi ini cadangan
Bálint
Itu tidak relevan di sekitar bagian-bagian ini;) Selama ada satu, satu penerjemah (browser) yang dapat menjalankan kode Anda dengan benar, itu dianggap valid di sini.
Shaggy
@ ngn Terima kasih untuk dua yang pertama, tetapi pergeseran bit memiliki prioritas lebih rendah dari pada dasarnya, sehingga tidak akan berfungsi
Bálint
6

Mathematica, 126 110 97 90

FromCharacterCode[10240+ListCorrelate[2^{{0,3},{1,4},{2,5},{6,7}},#,1,0][[;;;;4,;;;;2]]]&

Solusi ini mengambil keuntungan dari ListCorrelateuntuk membelit sebuah (terbalik) kernel lebih matriks , yang pada dasarnya adalah perkalian matriks geser (atau dot produk). Lihat penjelasan visual di sini . Padding dilakukan dengan menggunakan 0argumen keempat. Dalam contoh berikut, kami berharap hasilnya sesuai dengan petunjuk di atas:

ListCorrelate[
  2^{{0, 3}, {1, 4}, {2, 5}, {6, 7}},
  {{b0, b3}, {b1, b4}, {b2, b5}, {b6, b7}}
]

(* returns {{b0 + 2 b1 + 4 b2 + 8 b3 + 16 b4 + 32 b5 + 64 b6 + 128 b7}} *)

Perhatikan bahwa ListConvolvetidak ada yang lebih pendek, karena argumen ketiga adalah -1.

Karena ini menerapkan kernel pada setiap posisi matriks, kita hanya perlu mengekstrak elemen di setiap baris keempat dan kolom kedua. Kami menggunakan singkatan untuk Spandan Part:[[;;;;4,;;;;2]] .

Bermanfaat, FromCharacterCodedapat mengambil matriks kode karakter dan mengembalikan daftar string.


Solusi ini mengembalikan daftar string, yang merupakan salah satu format output yang diizinkan. Cukup tambahkan Column@untuk output agar "terlihat seperti matriks."


Anda dapat bermain-main dengan ini di buku catatan Mathematica online gratis. Buka di sini , klik Buat Notebook Baru, tunggu sebentar, rekatkan kode ini, lalu tekan shift+enter.

m1={{0,1,0,0,1,0},{1,0,0,0,0,0},{1,0,0,0,1,0},{1,1,1,1,0,0}};
m2={{0,1,0},{1,0,0},{1,1,1}};
m3={{0,0,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,0},{0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1},{0,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,1,0,0,0,1},{1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,1},{1,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,0,1,0},{1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0},{1,1,0,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0},{1,1,0,1,1,1,1,1,0,0,1,1,0,0,1,0,0,1,1,1,1,1,1},{1,1,0,1,1,1,1,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,0},{1,1,0,1,0,1,1,0,1,1,0,1,1,0,1,0,0,0,0,1,1,0,0},{1,1,0,0,0,1,1,0,1,0,0,0,1,0,1,1,0,0,0,1,1,0,0},{1,1,0,0,0,1,1,0,1,0,0,0,1,0,1,1,1,0,0,1,1,0,0},{0,1,1,0,1,1,1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0},{0,1,1,1,1,1,0,0,1,1,1,1,1,0,0,1,1,0,1,1,1,0,0},{0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,1,1,1,1,0}};

MatrixToBraille := Column@
  FromCharacterCode[10240+ListCorrelate[2^{{0,3},{1,4},{2,5},{6,7}},#,1,0][[;;;;4,;;;;2]]]&

MatrixToBraille/@{m1,m2,m3}

Maka Anda harus melihat ini:

hftf
sumber
5

Dyalog APL, 133 122 114 112 101 100 98 95 94 93 90 88 86 byte

Diasumsikan ⎕IO←0

{C⍴{⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨(,b)/,⍳⍴b←{0 0≡A|⍵}¨⍳⍴S←⍵↑⍨A×C←⌈(⍴⍵)÷A←4 2}

- 8 9 12 byte berkat @ Adám dalam obrolan

-2 byte terima kasih kepada @ngn

Cobalah online!

Bagaimana (inputnya )?

  • A←4 2, simpan vektor 4 2dalam variabelA
  • (⍴⍵)÷, dimensi dibagi denganA
  • , langit-langit
  • C←, disimpan di C
  • , dikalikan dengan A
  • ⍵↑⍨, cocok dengan dimensi tersebut
  • S←, disimpan di S
  • ⍳⍴, indeks S
  • {0 0≡A|⍵}¨, di 1mana bagian kiri atas sel berada, di 0tempat lain
  • (,b)/,⍳⍴b←, indeks kebenaran
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, ubah setiap elemen menjadi braille
  • C⍴, membentuk kembali dimensi ke C
Zacharý
sumber
pertimbangkan +/(2*0 3 1,A,4+⍳3)×something2⊥something[⍎¨⍕76524130]
ngn
Akankah itu masih berfungsi sekarang sehingga saya mengubahnya ⎕IO←0?
Zacharý
Sebenarnya, itu hanya akan bekerja di ⎕IO←0:)
ngn
Saya mencobanya, apakah saya melakukan sesuatu yang salah? tio.run/...
Zacharý
Maaf, saya lupa tentang hal bodoh ini ( ⎕IO) di APL. Karena ⎕IO←1, tentu saja Anda harus menambahkan 1 untuk setiap digit 76524130.
ngn
4

JavaScript, 136 byte

a=>(b=a.map(x=>[]),a.map((l,i)=>l.map((c,j)=>b[i>>2][j>>1]|=c<<'01263457'[i%4+j*4%8])),b.map(l=>l.map(c=>String.fromCharCode(10240+c))))

Berkat ngn , menggunakan bit shift menghemat 4 byte.

tsh
sumber
Anda dapat menggunakan bit shifts seperti i/4|0->i>>2
ngn
c*2**sedikit bergeser juga :)
ngn
4

Python 2 + drawille , 141 125 120 116 byte

Disimpan 16 byte berkat ngn dan L3viathan

Disimpan 5 byte berkat L3viathan

Disimpan 4 byte berkat ngn

from drawille import*
def a(d,c=Canvas(),e=enumerate):[c.set(j,i)for i,x in e(d)for j,y in e(x)if y];print c.frame()

Cobalah online!

tio tidak memiliki drawille yang terpasang sehingga tidak berfungsi

Noskcaj
sumber
Python dan baterainya! :) Tidak gagal mengejutkan saya. Anda dapat mengecilkan ini di bawah 120 byte jika Anda menggunakan enumerate()dan pemahaman daftar.
ngn
Simpan beberapa byte dengan membuat fungsi satu-liner:def b(d,c=l.Canvas()):print([c.set(j,i)for i,x in enumerate(d)for j,y in enumerate(x)if y]and c).frame()
L3viathan
Mendapat 120 byte
L3viathan
Anda tidak perlu and ctriknya - pemahamannya bisa berupa pernyataan sendiri diikuti oleh;print c.frame()
ngn
3

APL (Dyalog) , 57 54 byte *

-3 terima kasih kepada OP. Anjuran untuk matriks Boolean. Mencetak matriks karakter.

1↓⎕UCS{240,⌽(,⍉3↑⍵),⊢⌿⍵}⌺(2 24 2)⊢0⍪⍣3⍪∘03⊢⎕,0

Cobalah online!

⎕,0 tambahkan nol di sebelah kanan (diabaikan jika jumlah kolom genap)

 hasilkan itu (untuk memisahkan 3dan )

⍪∘0⍣3 tambahkan nol di bagian bawah tiga (karena menjatuhkan sebagian windows)

0⍪⍣3 tumpukan nol di atas tiga (karena dimulai di sudut kiri atas)

 menghasilkan yang (memisahkan tanda kurung dan 0)

{... }⌺(2 2⍴4 2) pada setiap jendela 2-kolom 4-baris, dengan langkah vertikal 4-baris dan 2 baris:

⊢⌿⍵ baris terakhir (lit. pengurangan kanan vertikal); [b6,b7]

(... ), tambahkan:

  3↑ ambil tiga baris; [[b0,b3],[b1,b4],[b2,b5]]

   mengubah urutan; [[b0,b1,b2],[b3,b4,b5]]

  , berlepasan; [b0,b1,b2,b3,b4,b5]

 sekarang kita punya [b0,b1,b2,b3,b4,b5,b6,b7]

 membalikkan; [b7,b6,b5,b4,b3,b2,b1,b0]

40, prepend 40 (untuk 40 × 2 9 = 10240);[40,b7,b6,b5,b4,b3,b2,b1,b0]

2⊥ mengevaluasi sebagai basis-2 (biner)

⎕UCS konversi ke karakter

1↓ jatuhkan baris pertama (semuanya nol karena bantalan)


* Dalam Klasik, menghitung sebagai ⎕U233A.

Adm
sumber
Ada cara mudah untuk menyimpan beberapa byte, lihat komentar saya di bawah solusi Jelly.
ngn
Pasti ada kesalahan - tautan TIO tidak cocok dengan kode yang Anda posting di sini.
ngn
itu adalah kode nol-padding di dekat akhir: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn
@ ngn Tetap, tapi saya punya perasaan itu ⍪∘0⍣3dan ,0hanya diperlukan karena ada bug , dan yang pertama tidak diperlukan untuk kasus uji Anda.
Adám
Kasing uji saya tidak lengkap - solusinya harus, tentu saja, bekerja untuk input yang valid. Anda dapat mempersingkat 0⍪⍣3⍪∘0⍣3⊢⍵,0menjadi 0(⊖⍪)⍣6⊢⍵,0.
ngn
2

Python 3 , 168 165 161 byte

def f(m):
 while m:
  r,m,s=[*zip(*m)],m[4:],''
  while r:s+=chr(10240+sum(q<<int(w)for(q,w)in zip((r[0]+(0,)*3)[:4]+(r+[()])[1],'01263457')));r=r[2:]
  print(s)

Cobalah online!

TFeld
sumber
Golf yang bagus! Anda dapat menyimpan tiga byte dengan [*zip(*m[:4])]alih - alih menelepon list.
Lynn
2

Haskell , 145 byte

(a!b)c=take b$c++repeat a
r([]:_)=[]
r l=['⠀'..]!!(sum.zipWith(*)[1,8,2,16,4,32,64,128]$l>>=0!2):r(drop 2<$>l)
b[]=[]
b s=r(([]!4)s):b(drop 4s)

Cobalah online!

Angs
sumber
1

Python 3 , 169 byte

a=[]
y=0
for l in eval(input()):
 y-=1;a+=y%4//3*[-~len(l)//2*[10240]];x=0
 for v in l:a[-1][x//2]|=v<<(6429374>>y%4*6+x%2*3&7);x+=1
for l in a:print(*map(chr,l),sep='')

Cobalah online!

Lynn
sumber
Anda dapat menulis ulang if y%4<1:a+=-~len(l)//2*[10240],sebagai a+=(y%4<1)*[-~len(l)//2*[10240]]dan cocok x=0;y+=1pada baris yang sama. Saya pikir itu menghemat satu byte.
ngn
@ ngn menyimpan beberapa byte lagi dari sana, terima kasih!
Lynn
1

Perl 5 , 164 byte

163 byte kode + 1 bendera -p

@a=eval}{for(;$r<@a;$r+=4){for($c=0;$c<@{$a[0]};$c+=2){$n="0b";map$n.=0|$a[$r+3][$c+$_],1,0;for$y(1,0){map$n.=0|$a[$r+$_][$c+$y],2,1,0}$\.=chr 0x2800+oct$n}$\.=$/}

Cobalah online!

Membawa setiap baris koma dipisahkan pada satu baris.

Xcali
sumber
1

APL (Dyalog) , 53 byte

4 2∘{⎕ucs 240⍪(⍎¨⍕76531420)∘.⊃,¨⍺∘↑¨↓∘⍵¨⍺∘ר⍳⌈⍺÷⍨⍴⍵}

Cobalah online!

ngn
sumber