Graphiques en braille

46

Couper une matrice booléenne dans les blocs et les 4x2 rendre en caractères 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 avec 0-s si les dimensions ne sont pas des multiples de 4 et 2.

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

⠮⠄

Les règles de golf habituelles s'appliquent, flexibles sur le format d'entrée. La sortie doit avoir la structure d’une matrice ou ressembler à une matrice, par exemple une liste de chaînes; chaîne unique avec des nouvelles lignes.

Indice: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)est le motif de points

b0 b3
b1 b4
b2 b5
b6 b7

Plus grand test:

[[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
la source
Félicitations pour le deuxième défi.
Adám
5
Meilleure description: vous avez un tableau 2D de valeurs booléennes dont les lignes représentent les lignes de trame horizontales d’un tampon d’image ou de zone graphique noir et blanc (1 bit par pixel). Encodez tous les blocs rectangulaires 4x2 de cette toile en caractères Braille Unicode. Pour manipuler des blocs fractionnaires sur les bords, réglez la largeur de la toile sur un multiple de 2 et la hauteur sur un multiple de quatre, avec des zéros (ou, au contraire, assurez une sortie équivalente en traitant les données comme si elles avaient été ainsi remplies).
Kaz
3
@Kaz Je ne sais pas, personnellement, j'apprécie vraiment la concision de cet article. OMI, on n’ajouterait pas beaucoup de clarté en écrivant plus (à part quelques petites précisions comme celle de noter que la hauteur doit être un multiple de 4 et la largeur de 2); votre suggestion est plus difficile à lire pour moi que le post actuel.
Quelklef

Réponses:

10

Gelée ,  31 à  30 octets

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

Essayez-le en ligne!

Comment?

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
la source
Est -ce soutien « chiffres » supérieur à 1? Au lieu d’ajouter 10240 (0x2800 - deux octets) au résultat, vous pouvez ajouter 40 (0x28 - un octet) au vecteur de chiffres binaires. Je ne connais pas grand chose à propos de Jelly, alors je ne suis pas sûr que cela fonctionnerait vraiment.
NDGN
convertirait effectivement un chiffre de gauche de 40 comme vous le suggérez, mais nous aurions besoin de l'ajouter à chaque liste (à une profondeur de 2), ce qui, je pense, nécessiterait davantage d'octets de code ( ;@€€40Ḅ).
Jonathan Allan
6

JavaScript ES7 210 207 201 200 200 198 194 185 185 183 octets

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 octets sauvegardés grâce à ngn

3 octets sauvés grâce à Luke

Comment ça fonctionne

Je vais scinder le code en plusieurs parties et en parler séparément:

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

C'est là que chaque variable est déclarée. xet yest la position du "curseur" (le bord supérieur gauche du caractère braille actuel). La coordonnée x augmente de 2 à chaque itération et s'arrête lorsqu'il n'y a pas de ligne avec l'index y(un [x] renvoie undefineds'il n'existe pas et est converti en false).

Il y a plusieurs astuces dans la deuxième rangée. (a[y] || [])[x]garantit que la recherche de la valeur à la (x, y)position ne génère pas d'erreur. Le &&est l'habituel et l'opérateur, et il vérifie seulement le côté droit de l'expression, si le gauche était vrai. Cela peut être traduit en

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

La partie suivante:

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.fromCharCodeconvertit simplement le nombre passé en un caractère Unicode avec le même code de caractère. L'expression entre parenthèses calcule l'indice du caractère Braille:

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

Passe par la position dans le

1 4
2 5
3 6

order, multiplie les valeurs à ces positions avec 2 i , où i est l’indice et les additionne. le

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

partie déclare une fonction lambda appelée g, laquelle, étant donnée une coordonnée xet yrenvoie la valeur à la (x, y)position ou 0 si la position se situe en dehors des limites du tableau.

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

Cette partie additionne les deux dernières positions avec les poids corrects en utilisant la fonction définie un peu plus tôt.

Dernier point mais non le moindre, le

a=>eval('...')

la partie a 2 fonctions. Il définit un lambda anonyme et garantit que la boucle for ne pose aucun problème (une seule lambda comme celle-ci ne peut pas contenir une seule boucle for, une évaluation contourne cela).

Bálint
la source
quelques suggestions simples: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(en remplaçant +-s par |-s)
ngn
Pourquoi ne pas soumettre la version ES7 en tant que solution principale?
Shaggy
@Shaggy Tout le monde ne peut pas encore utiliser ES7, c'est donc une sauvegarde
Bálint
C'est sans importance 'autour de ces parties;) tant qu'il existe un seul interpréteur (navigateur) capable d'exécuter correctement votre code, il est considéré comme valide ici.
Shaggy
@ngn Merci pour les deux premiers, mais un décalage de bits a une priorité inférieure à pratiquement tout, de sorte que ne fonctionnera pas
Bálint
6

Mathematica, 126 110 97 90

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

Cette solution met à profit ListCorrelatepour convoluer un (inversé) sur une matrice noyau , qui est essentiellement une multiplication de matrice de glissement (ou produit scalaire). Voir une explication visuelle ici . Le rembourrage se fait en utilisant 0comme quatrième argument. Dans l'exemple suivant, nous nous attendons à ce que le résultat corresponde à l'indice ci-dessus:

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

Notez que ce ListConvolven’est pas plus court, puisque le troisième argument le serait -1.

Comme cela applique le noyau à chaque position de la matrice, il suffit d'extraire les éléments de chaque quatrième ligne et deuxième colonne. Nous utilisons pour sténographies Spanet Part: [[;;;;4,;;;;2]].

Utilement, FromCharacterCodepeut prendre une matrice de codes de caractères et renvoyer une liste de chaînes.


Cette solution renvoie une liste de chaînes, qui est l'un des formats de sortie autorisés. Il suffit de préfixer Column@la sortie pour qu'elle «ressemble à une matrice».


Vous pouvez jouer avec cela dans un cahier Mathematica en ligne gratuit. Allez ici , cliquez sur Créer un nouveau carnet, attendez un instant, collez-le dans ce code, puis appuyez sur 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}

Alors vous devriez voir ceci:

hftf
la source
5

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

Suppose ⎕IO←0

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

- 8 9 12 octets grâce à @ Adám dans le chat

-2 octets grâce à @ngn

Essayez-le en ligne!

Comment (l'entrée est )?

  • A←4 2, stocke le vecteur 4 2dans la variableA
  • (⍴⍵)÷, les dimensions de divisé parA
  • plafond
  • C←, stocké dans C
  • , multiplié par A
  • ⍵↑⍨, ajustement à ces dimensions
  • S←, stocké dans S
  • ⍳⍴, index de S
  • {0 0≡A|⍵}¨, 1où le haut gauche d'une cellule est, 0partout ailleurs
  • (,b)/,⍳⍴b←, index de vérité
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, tournez chaque élément en braille
  • C⍴, remodeler les dimensions pour C
Zacharý
la source
Considérez +/(2*0 3 1,A,4+⍳3)×something2⊥something[⍎¨⍕76524130]
ngn
Tu veux toujours que ça marche maintenant que je l'ai changé ⎕IO←0?
Zacharý
En fait, cela ne fonctionnerait que dans ⎕IO←0:)
ngn
J'ai essayé ça, est-ce que je fais quelque chose de mal? tio.run/…
Zacharý
Désolé, j'ai oublié cette chose stupide ( ⎕IO) dans APL. Pour ⎕IO←1, bien sûr, vous devrez ajouter 1 à chaque chiffre de 76524130.
ngn
4

JavaScript, 136 octets

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

Grâce à ngn , l’utilisation des bits de décalage permet d’économiser 4 octets.

tsh
la source
vous pouvez utiliser des décalages de bits comme i/4|0->i>>2
ngn
c*2**est un peu de décalage, aussi :)
ngn
4

Python 2 + drawille , 141 125 120 116 octets

16 octets sauvés grâce à ngn et L3viathan

5 octets sauvés grâce à L3viathan

4 octets sauvegardés grâce à 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()

Essayez-le en ligne!

tio n’a pas drawille installé donc ça ne marche pas

Noskcaj
la source
Python et ses batteries! :) Ne manque pas de me surprendre. Vous pouvez réduire cette taille à moins de 120 octets si vous utilisez enumerate()une liste de compréhension.
ngn
Économisez quelques octets en transformant la fonction en une seule ligne: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
Je l'ai
vous n'avez pas besoin de cette and castuce - la compréhension pourrait être une déclaration en elle-même suivie de;print c.frame()
ngn
3

APL (Dyalog) , 57 54 octets *

-3 grâce à OP. Invites pour la matrice booléenne. Imprime la matrice de caractères.

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

Essayez-le en ligne!

⎕,0 ajouter un zéro à droite (ignoré si nombre pair de colonnes)

 donner que (séparer 3et )

⍪∘0⍣3 ajoute des zéros en bas trois fois (parce que les fenêtres partielles sont lâchées)

0⍪⍣3 empile les zéros en haut trois fois (car commence dans le coin en haut à gauche)

 donne que (sépare la parenthèse et le 0)

{}⌺(2 2⍴4 2) Sur chaque fenêtre à 2 colonnes de 4 rangées, avec gradins verticaux de 4 rangées et horizontales de 2 rangées:

⊢⌿⍵ dernière rangée (réduction verticale droite); [b6,b7]

(), Ajouter:

  3↑ prenez trois rangées; [[b0,b3],[b1,b4],[b2,b5]]

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

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

 maintenant nous avons [b0,b1,b2,b3,b4,b5,b6,b7]

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

40, prépend 40 (pour 40 × 2 9 = 10240);[40,b7,b6,b5,b4,b3,b2,b1,b0]

2⊥ évaluer en base 2 (binaire)

⎕UCS convertir en personnage

1↓ déposer la première ligne (tout à zéro à cause du remplissage de)


* En classique, compter comme ⎕U233A.

Adam
la source
Il existe un moyen facile de sauvegarder quelques octets, voir mon commentaire sous la solution Jelly.
ngn
Il doit y avoir une erreur - le lien TIO ne correspond pas au code que vous avez posté ici.
ngn
c'est le code de remplissage zéro vers la fin: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn
@ngn fixe, mais j'ai un sentiment ⍪∘0⍣3et ,0ne sont nécessaires en raison d'un bogue dans , et le premier n'est pas nécessaire pour vos cas de test.
Adám
Mes cas de test ne sont pas exhaustifs - la solution devrait, bien sûr, fonctionner pour toute entrée valide. Vous pouvez raccourcir 0⍪⍣3⍪∘0⍣3⊢⍵,0à 0(⊖⍪)⍣6⊢⍵,0.
ngn
2

Python 3 , 168 165 161 octets

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)

Essayez-le en ligne!

TFeld
la source
Joliment joué au golf! Vous pouvez enregistrer trois octets avec [*zip(*m[:4])]au lieu d'appeler list.
Lynn
2

Haskell , 145 octets

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

Essayez-le en ligne!

Angs
la source
1

Python 3 , 169 octets

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

Essayez-le en ligne!

Lynn
la source
Vous pouvez réécrire au if y%4<1:a+=-~len(l)//2*[10240],fur a+=(y%4<1)*[-~len(l)//2*[10240]]et à mesure et vous adapter x=0;y+=1à la même ligne. Je pense que cela sauve un octet.
ngn
@ ngn a enregistré quelques octets supplémentaires à partir de là, merci!
Lynn
1

Perl 5 , 164 octets

163 octets de code + 1 drapeau -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}$\.=$/}

Essayez-le en ligne!

Prend chaque ligne séparée par une virgule sur une ligne.

Xcali
la source
1

APL (Dyalog) , 53 octets

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

Essayez-le en ligne!

ngn
la source