Gráficos em braille

46

Corte uma matriz de boolean em 4x2 blocos e torná-los como caracteres 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]]

⣎⣀⠅

Almofada com 0-s se as dimensões não forem múltiplos de 4 e 2.

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

⠮⠄

Aplicam-se regras usuais de golfe, flexíveis no formato de entrada. A saída deve ter a estrutura de uma matriz ou parecer com uma matriz, por exemplo, lista de strings; cadeia única com novas linhas.

Dica: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)é o padrão de pontos

b0 b3
b1 b4
b2 b5
b6 b7

Teste maior:

[[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
fonte
Parabéns pelo segundo desafio.
Adám 27/08/17
5
Melhor descrição: você tem uma matriz 2D de valores booleanos cujas linhas representam as linhas de varredura horizontais de um buffer de quadro em preto-e-branco (1 bit por pixel) ou tela gráfica. Codifique todos os blocos retangulares 4x2 dessa tela em caracteres Unicode Braille. Para manipular blocos fracionários nas bordas, preencha a largura da tela com um múltiplo de 2 e a altura com um múltiplo de quatro, com zeros (ou garanta a saída equivalente, tratando os dados como se fossem preenchidos).
Kaz
3
@ Kaz Eu não sei, eu pessoalmente aprecio o quão conciso este post é. Na IMO, não se acrescentaria muita clareza escrevendo mais (além de alguns pequenos esclarecimentos, como observar que a altura deve ser um número múltiplo de 4 e a largura de 2); sua sugestão é mais difícil de ler do que a postagem atual.
Quelklef

Respostas:

10

Geléia ,  31  30 bytes

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

Experimente online!

Quão?

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
fonte
Será apoio "dígitos" superior a 1? Em vez de adicionar 10240 (0x2800 - dois bytes) ao resultado, você pode acrescentar 40 (0x28 - um byte) ao vetor de dígitos binários. Eu não sei muito sobre Jelly, então não tenho certeza se isso realmente funcionaria.
ngn 27/08/17
de fato, converteria um dígito inicial de 40, como você sugere, mas precisaríamos anexá-lo a cada lista (a uma profundidade de 2) que, acredito, exigiria mais bytes de código ( ;@€€40Ḅ).
Jonathan Allan
6

JavaScript ES7 210 207 201 200 198 194 185 183 bytes

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 bytes salvos graças a ngn

3 bytes salvos graças a Luke

Como funciona

Vou dividir o código em partes e falar sobre eles separadamente:

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

É aqui que todas as variáveis ​​são declaradas. xe yé a posição do "cursor" (a borda superior esquerda do caractere atual em braille). A coordenada x aumenta em 2 a cada iteração e para, quando não há linha com o índice y(a [x] retorna undefinedse não existir, o que é convertido em falso).

Existem vários truques na segunda linha. (a[y] || [])[x]garante que procurar o valor na (x, y)posição não gere um erro. O &&é o habitual e o operador, e apenas verifica o lado direito da expressão, se a esquerda for verdadeira. Isso pode ser traduzido para

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

A próxima 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.fromCharCodesimplesmente converte o número passado em um caractere unicode com o mesmo código de caractere. A expressão entre parênteses calcula o índice do caractere Braille:

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

Atravessa a posição no

1 4
2 5
3 6

ordem, multiplica os valores nessas posições com 2 i , onde i é o índice e os soma. o

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

parte declara uma função lambda chamada g, que, dada uma xe ycoordenada, retorna o valor na (x, y)posição ou 0 se a posição estiver fora dos limites da matriz.

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

Esta parte soma as duas últimas posições com os pesos corretos, usando a função definida um pouco antes.

Por último, mas não menos importante, o

a=>eval('...')

parte tem 2 funções. Ele define um lambda anônimo e garante que o loop for não cause problemas (uma única linha lambda como essa não pode conter apenas um loop for, uma avaliação contorna isso).

Bálint
fonte
algumas sugestões simples: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(substituindo +-s por |-s)
ngn
Por que não enviar a versão ES7 como sua solução principal?
Shaggy
@Shaggy Nem todos podem executar ES7 ainda, por isso é um backup
Bálint
Isso é irrelevante nessas partes;) Desde que haja um único intérprete (navegador) que possa executar seu código corretamente, é considerado válido aqui.
Shaggy
Graças @ngn para os dois primeiros, mas pouco deslocamento tem uma precedência mais baixa do que basicamente qualquer coisa, de modo que não vai funcionar
Bálint
6

Mathematica, 126 110 97 90

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

Essa solução aproveita ListCorrelatepara envolver um núcleo (invertido) sobre uma matriz , que é essencialmente uma multiplicação de matriz deslizante (ou produto de ponto). Veja uma explicação visual aqui . O preenchimento é feito usando 0o quarto argumento. No exemplo a seguir, esperamos que o resultado corresponda à dica acima:

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

Observe que ListConvolvenão é mais curto, pois o terceiro argumento seria -1.

Como isso aplica o kernel em todas as posições da matriz, só precisamos extrair os elementos em cada quarta linha e segunda coluna. Usamos atalhos para Spane Part: [[;;;;4,;;;;2]].

Ajuda, FromCharacterCodepode pegar uma matriz de códigos de caracteres e retornar uma lista de strings.


Esta solução retorna uma lista de cadeias, que é um dos formatos de saída permitidos. Simplesmente anteceda Column@a saída para "parecer uma matriz".


Você pode brincar com isso em um notebook Mathematica online gratuito. Vá aqui , clique em Criar um novo caderno, aguarde um momento, cole neste código e pressione 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}

Então você deve ver isso:

hftf
fonte
5

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

Assume ⎕IO←0

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

- 8 9 12 bytes graças a @ Adám no chat

-2 bytes graças a @ngn

Experimente online!

Como (entrada é )?

  • A←4 2, armazene o vetor 4 2na variávelA
  • (⍴⍵)÷, as dimensões de dividido porA
  • teto
  • C←, armazenado em C
  • , multiplicado por A
  • ⍵↑⍨, ajuste a essas dimensões
  • S←, armazenado em S
  • ⍳⍴, índices de S
  • {0 0≡A|⍵}¨, 1onde fica a 0parte superior esquerda de uma célula, em qualquer outro lugar
  • (,b)/,⍳⍴b←índices de verdade
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, transforme cada elemento em braille
  • C⍴, remodelar as dimensões para C
Zacharý
fonte
considere +/(2*0 3 1,A,4+⍳3)×something2⊥something[⍎¨⍕76524130]
ngn
Isso ainda funcionaria agora que eu mudei para ⎕IO←0?
Zachary
Na verdade, seria única obra em ⎕IO←0:)
NGN
Eu tentei isso, estou fazendo algo errado? tio.run/…
Zacharý
Desculpe, esqueci essa coisa estúpida ( ⎕IO) no APL. Para ⎕IO←1, é claro que você tem que adicionar 1 a cada dígito 76524130.
NGN
4

JavaScript, 136 bytes

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

Graças ao ngn , o uso de deslocamento de bits economiza 4 bytes.

tsh
fonte
você pode usar turnos de bits como i/4|0->i>>2
ngn 28/08/17
c*2**é uma mudança pouco, também :)
NGN
4

Python 2 + drawille , 141 125 120 116 bytes

Economizou 16 bytes graças ao ngn e L3viathan

Guardado 5 bytes graças a L3viathan

Guardado 4 bytes graças 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()

Experimente online!

O tio não possui drawille instalado, portanto não funciona

Noskcaj
fonte
Python e suas baterias! :) Não deixa de me surpreender. Você pode reduzir para menos de 120 bytes se você usar enumerate()e uma compreensão da lista.
NGN
Salvar um par de bytes, fazendo a função de uma frase: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
você não precisa do and ctruque - a compreensão pode ser uma declaração por si só, seguida por;print c.frame()
ngn 28/08/19
3

APL (Dyalog) , 57 54 bytes *

-3 graças a OP. Solicita matriz booleana. Imprime a matriz de caracteres.

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

Experimente online!

⎕,0 acrescentar um zero à direita (ignorado se o número par de colunas)

 produzir que (separar 3e )

⍪∘0⍣3 acrescentar zeros na parte inferior três vezes (porque cai janelas parciais)

0⍪⍣3 empilhe zeros na parte superior três vezes (porque começa no canto superior esquerdo)

 rendimento que (separa parênteses e 0)

{}⌺(2 2⍴4 2) Em cada janela de 4 linhas e 2 colunas, com degraus na vertical e 4 linhas na horizontal:

⊢⌿⍵ última linha (lit. redução vertical à direita); [b6,b7]

(), Prepend:

  3↑ pegue três linhas; [[b0,b3],[b1,b4],[b2,b5]]

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

  , confusão; [b0,b1,b2,b3,b4,b5]

 agora temos [b0,b1,b2,b3,b4,b5,b6,b7]

 marcha ré; [b7,b6,b5,b4,b3,b2,b1,b0]

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

2⊥ avaliar como base-2 (binário)

⎕UCS converter em personagem

1↓ solte a primeira linha (tudo zero por causa do preenchimento)


* No clássico, contando como ⎕U233A.

Adão
fonte
Existe uma maneira fácil de economizar alguns bytes; veja meu comentário na solução Jelly.
ngn 10/09/17
Deve haver um erro - o link do TIO não corresponde ao código que você postou aqui.
ngn 10/09/17
é o código de preenchimento zero perto do final: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn 10/09
@ngn fixo, mas eu tenho um sentimento que ⍪∘0⍣3e ,0só são necessários devido a um bug no , e o primeiro não é necessário para seus casos de teste.
Adám 10/09/17
Meus casos de teste não são exaustivos - a solução deve, é claro, funcionar para qualquer entrada válida. Você pode reduzir 0⍪⍣3⍪∘0⍣3⊢⍵,0para 0(⊖⍪)⍣6⊢⍵,0.
ngn 10/09/17
2

Python 3 , 168 165 161 bytes

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)

Experimente online!

TFeld
fonte
Bem jogado! Você pode salvar três bytes em [*zip(*m[:4])]vez de chamar list.
Lynn
2

Haskell , 145 bytes

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

Experimente online!

Angs
fonte
1

Python 3 , 169 bytes

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

Experimente online!

Lynn
fonte
Você pode reescrever if y%4<1:a+=-~len(l)//2*[10240],como a+=(y%4<1)*[-~len(l)//2*[10240]]e caber x=0;y+=1na mesma linha. Eu acho que economiza um byte.
NGN
@ngn salvou mais alguns bytes dali em diante, obrigado!
Lynn
1

Perl 5 , 164 bytes

163 bytes de código + 1 sinalizador -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}$\.=$/}

Experimente online!

Leva cada vírgula de linha separada em uma linha.

Xcali
fonte
1

APL (Dyalog) , 53 bytes

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

Experimente online!

ngn
fonte