Grafica Braille


46

Tagliare una matrice booleana in 4x2 blocchi e renderli come caratteri 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]]

⣎⣀⠅

Riempi con 0-s se le dimensioni non sono multiple di 4 e 2.

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

⠮⠄

Si applicano le normali regole del golf, flessibili sul formato di input. L'output dovrebbe avere la struttura di una matrice o apparire come una matrice, ad esempio un elenco di stringhe; stringa singola con newline.

Suggerimento: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)è il motivo a punti

b0 b3
b1 b4
b2 b5
b6 b7

Test più grande:

[[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]]

⣰⠟⠻⣦⠀⠠⠾⡇⢠⡞⢛⡆
⣿⢠⣬⣥⠄⣀⠀⡇⢈⣻⣈⡀
⣿⠘⢹⡇⡞⠙⡇⣧⡉⢹⡏⠀
⠘⠷⠟⠁⠳⠾⠃⠘⠇⠾⠧⠀

Complimenti per la seconda sfida.
Adám,

5
Migliore descrizione: hai un array 2D di valori booleani le cui righe rappresentano le linee raster orizzontali di un buffer di frame o canvas grafico in bianco e nero (1 bit per pixel). Codifica tutti i blocchi rettangolari 4x2 di questa tela in caratteri Unicode Braille. Per gestire i blocchi frazionari ai bordi, riempire la larghezza della tela con un multiplo di 2 e l'altezza con un multiplo di quattro, con zeri (o altrimenti garantire l'output equivalente, trattando i dati come se fossero così imbottiti).
Kaz,

3
@Kaz Non lo so, personalmente apprezzo davvero quanto sia conciso questo post. IMO, non si aggiungerebbe molta chiarezza scrivendo più (oltre ad alcuni piccoli chiarimenti come notare che l'altezza dovrebbe essere un mult di 4 e la larghezza di 2); il tuo suggerimento per me è più difficile da leggere rispetto al post corrente.
Quelklef,

Risposte:


10

Gelatina ,  31  30 byte

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

Provalo online!

Come?

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

Fa supporto "cifre" maggiore di 1? Invece di aggiungere 10240 (0x2800 - due byte) al risultato, è possibile anteporre 40 (0x28 - un byte) al vettore di cifre binarie. Non so molto di Jelly, quindi non sono sicuro che funzionerebbe davvero.
ngn,

convertiresti davvero una cifra iniziale di 40 come suggerisci, ma avremmo bisogno di anteporla a ciascuna di queste liste (a una profondità di 2) che, credo, richiederebbe più byte di codice ( ;@€€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 salvati grazie a ngn

3 byte salvati grazie a Luke

Come funziona

Ho intenzione di dividere il codice in parti e parlarne separatamente:

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

È qui che viene dichiarata ogni variabile. xed yè la posizione del "cursore" (il bordo superiore sinistro dell'attuale carattere braille). La coordinata x aumenta di 2 ogni iterazione e si interrompe quando non vi è alcuna riga con l'indice y(una [x] restituisce undefinedse non esiste, che viene convertita in falso).

Ci sono più prese nella seconda fila. (a[y] || [])[x]assicura che la ricerca del valore nella (x, y)posizione non generi un errore. Il &&solito è operatore e controlla solo il lato destro dell'espressione, se la sinistra era vera. Questo può essere tradotto in

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

La prossima parte:

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.fromCharCodeconverte semplicemente il numero passato in un carattere unicode con lo stesso codice carattere. L'espressione tra parentesi calcola l'indice del carattere Braille:

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

Passa attraverso la posizione in

1 4
2 5
3 6

ordine, moltiplica i valori in quelle posizioni con 2 i , dove i è l'indice e li somma insieme. Il

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

la parte dichiara una funzione lambda chiamata g, che dato una xe ycoordinata restituisce il valore nella (x, y)posizione o 0 se la posizione si trova al di fuori dei limiti dell'array.

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

Questa parte aggiunge le ultime due posizioni con i pesi corretti utilizzando la funzione definita un po 'prima.

Ultimo ma non meno importante, il

a=>eval('...')

la parte ha 2 funzioni. Definisce un lambda anonimo e garantisce che il ciclo for non causi alcun problema (una singola riga lambda come questa non può contenere un solo ciclo for, una valutazione lo aggira).


alcuni semplici suggerimenti: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(sostituendo +-s con |-s)
ngn

Perché non inviare la versione ES7 come soluzione principale?
Shaggy,

@Shaggy Non tutti possono ancora eseguire ES7, quindi è un backup
Bálint,

È irrilevante 'attorno a queste parti;) Fintanto che esiste un solo interprete (browser) che può eseguire correttamente il codice, qui è considerato valido.
Shaggy,

@ngn Grazie per i primi due, ma lo spostamento dei bit ha una precedenza inferiore rispetto a qualsiasi altra cosa, quindi non funzionerà
Bálint

6

Mathematica, 126 110 97 90

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

Questa soluzione sfrutta ListCorrelatea convolvere un (invertita) kernel su una matrice , che è essenzialmente una moltiplicazione di matrici di scorrimento (o prodotto scalare). Vedi una spiegazione visiva qui . Il riempimento viene eseguito utilizzando 0come quarto argomento. Nel seguente esempio, prevediamo che il risultato corrisponda al suggerimento sopra riportato:

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

Nota che ListConvolvenon è più breve, poiché il terzo argomento sarebbe -1.

Poiché questo applica il kernel in ogni posizione della matrice, dobbiamo solo estrarre gli elementi in ogni quarta riga e seconda colonna. Usiamo abbreviazioni per Spane Part: [[;;;;4,;;;;2]].

Utilmente, FromCharacterCodepuò prendere una matrice di codici carattere e restituire un elenco di stringhe.


Questa soluzione restituisce un elenco di stringhe, che è uno dei formati di output consentiti. Basta anteporre Column@che l'output "assomigli ad una matrice".


Puoi giocare con questo in un taccuino Mathematica online gratuito. Vai qui , fai clic su Crea un nuovo blocco note, attendi un momento, incolla questo codice, quindi premi 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}

Quindi dovresti vedere questo:


5

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

assume ⎕IO←0

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

- 8 9 12 byte grazie a @ Adám in chat

-2 byte grazie a @ngn

Provalo online!

Come (input è )?

  • A←4 2, memorizza il vettore 4 2in variabileA
  • (⍴⍵)÷, le dimensioni di diviso perA
  • , soffitto
  • C←, immagazzinato C
  • , moltiplicato per A
  • ⍵↑⍨, adatto a quelle dimensioni
  • S←, immagazzinato S
  • ⍳⍴, indici di S
  • {0 0≡A|⍵}¨, 1dove si trova la parte superiore sinistra di una cella, 0ovunque
  • (,b)/,⍳⍴b←, indici veritieri
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, trasforma ogni elemento in braille
  • C⍴, rimodella le dimensioni in C

considera +/(2*0 3 1,A,4+⍳3)×something2⊥something[⍎¨⍕76524130]
ngn il

Potrebbe funzionare ancora adesso che l'ho cambiato ⎕IO←0?
Zacharý,

In realtà, funzionerebbe solo in ⎕IO←0:)
ngn

Ci ho provato, sto facendo qualcosa di sbagliato? tio.run/…
Zacharý

Scusa, ho dimenticato questa cosa stupida ( ⎕IO) in APL. Perché ⎕IO←1, ovviamente, dovresti aggiungere 1 a ogni cifra di 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))))

Grazie a ngn , usando i bit shift si risparmiano 4 byte.


puoi usare i bit shift come i/4|0->i>>2
ngn il

c*2**è anche un po '
mutevole

4

Python 2 + drawille , 141 125 120 116 byte

Risparmiato 16 byte grazie a ngn e L3viathan

5 byte salvati grazie a L3viathan

Salvato 4 byte grazie a 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()

Provalo online!

tio non ha Drawille installato quindi non funziona


Python e le sue batterie! :) Non manca di sorprendermi. È possibile ridurlo a meno di 120 byte se si utilizza enumerate()e una comprensione dell'elenco.
ngn,

Salvare un paio di byte trasformando la funzione in una 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()
riga


non hai bisogno del and ctrucco - la comprensione potrebbe essere una dichiarazione a sé stante seguita da;print c.frame()
ngn

3

APL (Dyalog) , 57 54 byte *

-3 grazie all'OP. Richiede la matrice booleana. Stampa la matrice dei caratteri.

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

Provalo online!

⎕,0 aggiungi uno zero a destra (ignorato se il numero pari di colonne)

 cedere che (separare 3e )

⍪∘0⍣3 aggiungi zeri in basso tre volte (perché rilascia finestre parziali)

0⍪⍣3 impila zeri in alto tre volte (perché inizia nell'angolo in alto a sinistra)

 cedere che (separa la parentesi e il 0)

{}⌺(2 2⍴4 2) Su ogni finestra a 2 colonne a 4 file, con gradino verticale a 4 file e orizzontale a 2 file:

⊢⌿⍵ ultima fila (lett. riduzione verticale a destra); [b6,b7]

(... ), anteporre:

  3↑ prendere tre file; [[b0,b3],[b1,b4],[b2,b5]]

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

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

 ora abbiamo [b0,b1,b2,b3,b4,b5,b6,b7]

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

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

2⊥ valuta come base-2 (binario)

⎕UCS convertire in personaggio

1↓ rilascia la prima riga (tutto zero a causa del riempimento)


* In classico, contando come ⎕U233A.


C'è un modo semplice per salvare qualche byte, vedi il mio commento sotto la soluzione Jelly.
ngn,

Deve esserci un errore: il link TIO non corrisponde al codice che hai pubblicato qui.
ngn,

è il codice zero-padding verso la fine: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn

@ngn Risolto, ma ho la sensazione che ⍪∘0⍣3e ,0sono necessari solo a causa di un bug in , e il primo non è necessario per i tuoi casi di test.
Adám,

I miei casi di test non sono esaustivi: la soluzione dovrebbe ovviamente funzionare per qualsiasi input valido. È possibile ridurre 0⍪⍣3⍪∘0⍣3⊢⍵,0a 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)

Provalo online!


Ben giocato a golf! È possibile salvare tre byte con [*zip(*m[:4])]anziché chiamare 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)

Provalo online!


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

Provalo online!


È possibile riscrivere if y%4<1:a+=-~len(l)//2*[10240],come a+=(y%4<1)*[-~len(l)//2*[10240]]e montare x=0;y+=1sulla stessa linea. Penso che salvi un byte.
ngn,

@ngn ha salvato qualche altro byte da lì in poi, grazie!
Lynn,

1

Perl 5 , 164 byte

163 byte di codice + 1 flag -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}$\.=$/}

Provalo online!

Prende ciascuna riga una virgola separata su una riga.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.