Брайлевская графика

46

Вырезать булеву матрицу в 4х2 блоков и сделать их как символы Брайля 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 с 0-s, если размеры не кратны 4 и 2.

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

⠮⠄

Применяются обычные правила игры в гольф, гибкий формат ввода. Вывод должен иметь структуру матрицы или выглядеть как матрица, например, список строк; одна строка с символами новой строки.

Подсказка: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)это точечный шаблон

b0 b3
b1 b4
b2 b5
b6 b7

Большой тест:

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

⣰⠟⠻⣦⠀⠠⠾⡇⢠⡞⢛⡆
⣿⢠⣬⣥⠄⣀⠀⡇⢈⣻⣈⡀
⣿⠘⢹⡇⡞⠙⡇⣧⡉⢹⡏⠀
⠘⠷⠟⠁⠳⠾⠃⠘⠇⠾⠧⠀
СПП
источник
Поздравляю со вторым испытанием.
17
5
Лучшее описание: у вас есть двумерный массив булевых значений, строки которого представляют горизонтальные растровые линии черно-белого (1 бит на пиксель) буфера кадра или графического холста. Закодируйте все прямоугольные блоки 4x2 этого холста в символы Брайля Юникода. Чтобы обработать дробные блоки по краям, добавьте ширину холста, кратную 2, и высоту, кратную четырем, с нулями (или иным образом обеспечьте эквивалентный вывод, обрабатывая данные, как если бы они были так дополнены).
Kaz
3
@ Kaz Я не знаю, я лично очень ценю, насколько лаконичен этот пост. ИМО, не так много ясности можно было бы добавить, написав больше (помимо нескольких небольших уточнений, таких как отметка, что высота должна быть кратна 4, а ширина 2); Ваше предложение для меня сложнее, чем текущий пост.
Quelklef

Ответы:

10

Желе ,  31  30 байт

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

Попробуйте онлайн!

Как?

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
Джонатан Аллан
источник
Поддерживает ли «цифры» больше 1? Вместо добавления 10240 (0x2800 - два байта) к результату, вы можете добавить 40 (0x28 - один байт) к вектору двоичных цифр. Я не знаю много о Желе, поэтому я не уверен, что это действительно сработает.
ngn
будет действительно преобразовывать начальную цифру 40, как вы предлагаете, но нам нужно было бы добавить ее к каждому такому списку (на глубине 2), который, я думаю, потребовал бы больше байтов кода ( ;@€€40Ḅ).
Джонатан Аллан
6

JavaScript ES7 210 207 201 200 198 194 185 183 байта

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 байта сохранены благодаря ngn

3 байта спасены благодаря Люку

Как это устроено

Я собираюсь разбить код на части и поговорить о них отдельно:

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

Здесь каждая переменная объявляется. xи y- позиция «курсора» (левый верхний край текущего символа Брайля). Координата x увеличивается на 2 на каждой итерации и останавливается, когда нет строки с индексом y(a [x] возвращает, undefinedесли он не существует, который преобразуется в false).

Есть несколько трюков во втором ряду. (a[y] || [])[x]гарантирует, что поиск значения в (x, y)позиции не приведет к ошибке. Это &&обычный оператор и оператор, и он проверяет только правую часть выражения, если слева было значение true. Это можно перевести на

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

Следующая часть:

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.fromCharCodeпросто преобразует переданное число в символ Unicode с тем же кодом символа. Выражение в скобках вычисляет индекс символа Брайля:

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

Проходит позицию в

1 4
2 5
3 6

order, умножает значения в этих позициях на 2 i , где i - индекс, и складывает их вместе.

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

part объявляет вызванную лямбда-функцию g, которая с учетом координаты xand yвозвращает либо значение в (x, y)позиции, либо 0, если позиция находится за пределами массива.

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

Эта часть суммирует последние две позиции с правильными весами, используя функцию, определенную чуть ранее.

Не в последнюю очередь,

a=>eval('...')

часть имеет 2 функции. Он определяет анонимную лямбду и гарантирует, что цикл for не вызывает никаких проблем (такая лямбда-строка, как эта, не может содержать только один цикл for, оценка обходит это).

Балинт
источник
несколько простых предложений: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(замена +-s на |-s)
ngn
Почему бы не представить версию ES7 в качестве основного решения?
Лохматый
@Shaggy Не все могут запустить ES7, так что это резервная копия
Bálint
Это не имеет отношения к этим частям;) Пока существует один-единственный интерпретатор (браузер), который может правильно выполнять ваш код, он считается действительным здесь.
Лохматый
@ngn Спасибо за первые два, но сдвиг битов имеет меньший приоритет, чем в принципе, так что это не сработает
Bálint
6

Mathematica, 126 110 97 90

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

Это решение использует преимущество, заключающееся в том, ListCorrelateчтобы сворачивать (обращенное) ядро ​​над матрицей , которая по сути является умножением скользящей матрицы (или точечным произведением). Смотрите визуальное объяснение здесь . Заполнение выполняется с помощью 0четвертого аргумента. В следующем примере мы ожидаем, что результат будет соответствовать подсказке выше:

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

Обратите внимание, что ListConvolveэто не короче, так как третий аргумент будет -1.

Так как это применяет ядро ​​в каждой позиции матрицы, нам просто нужно извлечь элементы в каждой четвертой строке и втором столбце. Мы используем Shorthands для Spanи Part: [[;;;;4,;;;;2]].

Полезно, FromCharacterCodeможет взять матрицу кодов символов и вернуть список строк.


Это решение возвращает список строк, который является одним из разрешенных форматов вывода. Просто Column@подготовьте вывод, чтобы «выглядеть как матрица».


Вы можете поиграть с этим в бесплатной онлайн тетради Mathematica. Перейдите сюда , нажмите «Создать новую записную книжку», подождите, вставьте этот код и нажмите 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}

Тогда вы должны увидеть это:

hftf
источник
5

Dyalog APL, 133 122 114 112 101 100 98 95 94 93 90 88 86 байтов

Предполагает ⎕IO←0

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

- 8 9 12 байт благодаря @ Adám в чате

-2 байта благодаря @ngn

Попробуйте онлайн!

Как (вход есть )?

  • A←4 2сохранить вектор 4 2в переменнойA
  • (⍴⍵)÷Размеры делятся наA
  • потолок
  • C←, Хранится в C
  • , умножается на A
  • ⍵↑⍨подходит к этим размерам
  • S←, Хранится в S
  • ⍳⍴, индексы S
  • {0 0≡A|⍵}¨, 1Где верхняя левая из клетки, и 0везде
  • (,b)/,⍳⍴b←правдивые показатели
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, превратить каждый элемент в шрифт Брайля
  • C⍴изменить размеры в C
Zachary
источник
рассмотреть +/(2*0 3 1,A,4+⍳3)×something2⊥something[⍎¨⍕76524130]
нгн
Это все еще работает, теперь, когда я изменил это ⎕IO←0?
Захари
На самом деле, это будет работать только в ⎕IO←0:)
ngn
Я пробовал это, я делаю что-то не так? tio.run/…
Zacharý
Извините, я забыл об этой глупости ( ⎕IO) в APL. Для ⎕IO←1, конечно , вы должны были бы добавить 1 к каждой цифре 76524130.
СПП
4

JavaScript, 136 байт

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

Благодаря ngn использование сдвигов битов экономит 4 байта.

ТТГ
источник
Вы можете использовать битовые сдвиги, такие как i/4|0->i>>2
ngn
c*2**немного сдвиг тоже :)
нгн
4

Python 2 + drawille , 141 125 120 116 байт

Сохранено 16 байтов благодаря ngn и L3viathan

Сохранено 5 байт благодаря L3viathan

Сохранено 4 байта благодаря 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()

Попробуйте онлайн!

на tio не установлен drawille, поэтому он не работает

Noskcaj
источник
Питон и его батареи! :) Не перестает удивлять меня. Вы можете уменьшить это до 120 байтов, если вы используете enumerate()и понимание списка.
нгн
Сохраните пару байтов, сделав функцию однострочной: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
вам не нужен and cтрюк - понимание может быть самостоятельным утверждением, за которым следует;print c.frame()
ngn
3

APL (Dyalog) , 57 54 байта *

-3 благодаря ОП. Подсказки для булевой матрицы. Печатает матрицу символов.

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

Попробуйте онлайн!

⎕,0 добавить ноль справа (игнорируется, если четное количество столбцов)

 дать это (отделить 3и )

⍪∘0⍣3 добавьте нули в нижнюю часть трижды (потому что пропускает частичные окна)

0⍪⍣3 складывать нули сверху трижды (потому что начинается в верхнем левом углу)

 выход , что (отделяет скобку и тому 0)

{… В }⌺(2 2⍴4 2) каждом 4-рядном 2-колоночном окне с 4-рядным вертикальным и 2-рядным горизонтальным шагом:

⊢⌿⍵ последний ряд (горит вертикальное правое сокращение); [b6,b7]

(), Prepend:

  3↑ взять три ряда; [[b0,b3],[b1,b4],[b2,b5]]

   транспонировать; [[b0,b1,b2],[b3,b4,b5]]

  , распутать; [b0,b1,b2,b3,b4,b5]

 теперь у нас есть [b0,b1,b2,b3,b4,b5,b6,b7]

 задний ход; [b7,b6,b5,b4,b3,b2,b1,b0]

40, 40 перед именем (для 40 × 2 9 = 10240);[40,b7,b6,b5,b4,b3,b2,b1,b0]

2⊥ оценивать как базу-2 (двоичная)

⎕UCS преобразовать в персонажа

1↓ отбросить первый ряд (все ноль из-за отступов)


* В Классике, считая как ⎕U233A.

Адам
источник
Есть простой способ сэкономить несколько байтов, см. Мой комментарий под решением Jelly.
нгн
Должна быть ошибка - ссылка TIO не соответствует коду, который вы разместили здесь.
СПП
это код заполнения нулями в конце: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn
@ngn Fixed, но у меня есть ощущение , что ⍪∘0⍣3и ,0только необходимы , из - за ошибки в , и первый один не требуется для тестов.
Адам
Мои тестовые примеры не являются исчерпывающими - решение, конечно, должно работать для любого корректного ввода. Вы можете сократить 0⍪⍣3⍪∘0⍣3⊢⍵,0до 0(⊖⍪)⍣6⊢⍵,0.
СПП
2

Python 3 , 168 165 161 байт

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)

Попробуйте онлайн!

TFeld
источник
Красиво в гольф! Вы можете сохранить три байта с помощью [*zip(*m[:4])]вместо вызова list.
Линн
1

Python 3 , 169 байт

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

Попробуйте онлайн!

Линн
источник
Вы можете переписать if y%4<1:a+=-~len(l)//2*[10240],как a+=(y%4<1)*[-~len(l)//2*[10240]]и поместиться x=0;y+=1на одной строке. Я думаю, что это сохраняет байт.
нгн
@ngn сэкономил еще несколько байтов, спасибо!
Линн
1

Perl 5 , 164 байта

163 байта кода + 1 флаг -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}$\.=$/}

Попробуйте онлайн!

Берет каждую строку через запятую, разделенную на одну строку.

Xcali
источник