Đồ họa chữ nổi


46

Cắt một ma trận boolean trong 4x2 khối và khiến chúng như ký tự 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 với 0-s nếu kích thước không phải là bội số của 4 và 2.

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

⠮⠄

Quy tắc chơi golf thông thường được áp dụng, linh hoạt về định dạng đầu vào. Đầu ra phải có cấu trúc của ma trận hoặc trông giống như ma trận, ví dụ như danh sách các chuỗi; chuỗi đơn với dòng mới.

Gợi ý: chr(0x2800 + 128*b7 + 64*b6 + 32*b5 + 16*b4 + 8*b3 + 4*b2 + 2*b1 + b0)là mẫu chấm

b0 b3
b1 b4
b2 b5
b6 b7

Bài kiểm tra lớn hơn:

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

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

Chúc mừng thử thách thứ hai.
Adám

5
Mô tả tốt hơn: bạn có một mảng 2D các giá trị Boolean có các hàng biểu thị các đường raster ngang của bộ đệm khung hình đen trắng (1 bit trên mỗi pixel) hoặc khung vẽ đồ họa. Mã hóa tất cả các khối hình chữ nhật 4x2 của khung vẽ này thành các ký tự chữ nổi Unicode. Để xử lý các khối phân đoạn ở các cạnh, hãy ghép chiều rộng của khung hình thành bội số của 2 và chiều cao thành bội số của bốn, với các số không (hoặc nếu không, đảm bảo đầu ra tương đương, xử lý dữ liệu như thể được đệm).
Kaz

3
@Kaz Tôi không biết, cá nhân tôi thực sự đánh giá cao bài viết này súc tích như thế nào. IMO, không có nhiều sự rõ ràng sẽ được thêm vào bằng cách viết thêm (bên cạnh một vài làm rõ nhỏ như lưu ý rằng chiều cao nên là bội số của 4 và chiều rộng là 2); đề nghị của bạn khó đọc hơn bài viết hiện tại.
Quelklef

Câu trả lời:


10

Thạch ,  31  30 byte

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

Hãy thử trực tuyến!

Làm sao?

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

hỗ trợ "chữ số" lớn hơn 1 không? Thay vì thêm 10240 (0x2800 - hai byte) vào kết quả, bạn có thể thêm 40 (0x28 - một byte) vào vectơ của các chữ số nhị phân. Tôi không biết nhiều về Jelly, vì vậy tôi không chắc điều này có thực sự hiệu quả không.
ngn

thực sự sẽ chuyển đổi một chữ số hàng đầu là 40 như bạn đề xuất, nhưng chúng tôi cần phải thêm nó vào từng danh sách như vậy (ở độ sâu 2), theo tôi, sẽ cần nhiều byte mã hơn ( ;@€€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 được lưu nhờ ngn

3 byte được lưu nhờ Luke

Làm thế nào nó hoạt động

Tôi sẽ chia mã thành nhiều phần và nói riêng về chúng:

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

Đây là nơi mà mọi biến được khai báo. xylà vị trí của "con trỏ" (cạnh trên bên trái của ký tự chữ nổi hiện tại). Tọa độ x tăng thêm 2 mỗi lần lặp và nó dừng lại, khi không có hàng nào có chỉ mục y(một [x] trả về undefinednếu nó không tồn tại, được chuyển thành false).

Có nhiều thủ thuật trong hàng thứ hai. (a[y] || [])[x]đảm bảo rằng việc tìm kiếm giá trị tại (x, y)vị trí không gây ra lỗi. Đây &&là thông thường và toán tử, và nó chỉ kiểm tra bên phải của biểu thức, nếu bên trái là đúng. Điều này có thể được dịch sang

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

Phần tiếp theo:

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.fromCharCodechỉ cần chuyển đổi số đã truyền thành một ký tự unicode có cùng mã ký tự. Biểu thức trong ngoặc đơn tính toán chỉ số của ký tự chữ nổi:

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

Đi qua vị trí trong

1 4
2 5
3 6

thứ tự, nhân các giá trị tại các vị trí đó với 2 i , trong đó i là chỉ mục và cộng chúng lại với nhau. Các

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

một phần khai báo hàm lambda được gọi g, hàm đã cho xytọa độ trả về giá trị tại (x, y)vị trí hoặc 0 nếu vị trí nằm ngoài giới hạn của mảng.

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

Phần này cộng hai vị trí cuối cùng với các trọng số chính xác bằng cách sử dụng hàm được xác định trước đó một chút.

Cuối cùng nhưng không kém phần quan trọng,

a=>eval('...')

phần có 2 chức năng. Nó định nghĩa một lambda ẩn danh và đảm bảo rằng vòng lặp for không gây ra bất kỳ vấn đề nào (một dòng lambda duy nhất như thế này không thể chỉ chứa một vòng lặp duy nhất, một vòng đánh giá sẽ phá vỡ điều này).


một vài gợi ý đơn giản: ||0-> |0; ~~(k/3)-> (k>2); *128-> <<7(thay thế +-s bằng |-s)
ngn

Tại sao không gửi phiên bản ES7 làm giải pháp chính của bạn?
Xù xì

@Shaggy Không phải ai cũng có thể chạy ES7, vì vậy đó là bản sao lưu
Bálint

Điều đó không liên quan 'làm tròn các phần này;) Miễn là có một, trình thông dịch duy nhất (trình duyệt) có thể chạy mã của bạn đúng cách, nó được coi là hợp lệ ở đây.
Xù xì

@ngn Cảm ơn hai người đầu tiên, nhưng dịch chuyển bit có độ ưu tiên thấp hơn cơ bản mọi thứ, vì vậy sẽ không hoạt động
Bálint

6

Toán học, 126 110 97 90

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

Giải pháp này lợi dụng ListCorrelateđể kết hợp một hạt nhân (đảo ngược) trên một ma trận , về cơ bản là một phép nhân ma trận trượt (hoặc sản phẩm chấm). Xem một lời giải thích trực quan ở đây . Việc đệm được thực hiện bằng cách sử dụng 0làm đối số thứ tư. Trong ví dụ sau, chúng tôi hy vọng kết quả khớp với gợi ý ở trên:

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

Lưu ý rằng ListConvolvekhông ngắn hơn, vì đối số thứ ba sẽ là -1.

Vì điều này áp dụng kernel ở mọi vị trí của ma trận, chúng ta chỉ cần trích xuất các phần tử ở mỗi hàng thứ tư và cột thứ hai. Chúng tôi sử dụng tốc ký cho SpanPart: [[;;;;4,;;;;2]].

Thật hữu ích, FromCharacterCodecó thể lấy một ma trận mã ký tự và trả về một danh sách các chuỗi.


Giải pháp này trả về một danh sách các chuỗi, là một trong những định dạng đầu ra được phép. Đơn giản chỉ cần Column@chuẩn bị cho đầu ra để trông giống như một ma trận.


Bạn có thể chơi xung quanh với điều này trong một máy tính xách tay Mathicala trực tuyến miễn phí. Tới đây , nhấp vào Tạo sổ ghi chép mới, đợi một lát, dán mã này, sau đó nhấn 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}

Sau đó, bạn sẽ thấy điều này:


5

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

Giả định ⎕IO←0

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

- 8 9 12 byte nhờ @ Adám trong trò chuyện

-2 byte nhờ @ngn

Hãy thử trực tuyến!

Làm thế nào (đầu vào là )?

  • A←4 2, lưu trữ vector 4 2trong biếnA
  • (⍴⍵)÷, kích thước chia choA
  • , Trần nhà
  • C←, được lưu trữ trong C
  • , nhân với A
  • ⍵↑⍨, phù hợp với những kích thước đó
  • S←, được lưu trữ trong S
  • ⍳⍴, chỉ số của S
  • {0 0≡A|⍵}¨, 1nơi trên cùng bên trái của một tế bào, 0ở mọi nơi khác
  • (,b)/,⍳⍴b←, chỉ số trung thực
  • {⎕UCS 10240+2⊥(∊S⌷⍨⍵+⍳¨A)[⍎¨⍕76531420]}¨, biến từng yếu tố thành chữ nổi
  • C⍴, định hình lại kích thước để C

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

WOuld vẫn còn hoạt động mà tôi đã thay đổi nó thành ⎕IO←0?
Zacharý

Trên thực tế, nó sẽ chỉ hoạt động trong ⎕IO←0:)
ngn

Tôi đã thử điều đó, tôi đang làm gì đó sai? tio.run/ từ
Zacharý

Xin lỗi, tôi đã quên điều ngu ngốc này ( ⎕IO) trong APL. Đối với ⎕IO←1, tất nhiên, bạn phải thêm 1 cho mỗi chữ số 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))))

Nhờ ngn , sử dụng dịch chuyển bit tiết kiệm 4 byte.


bạn có thể sử dụng dịch chuyển bit như i/4|0->i>>2
ngn

c*2**cũng là một chút thay đổi :)
ngn

4

Python 2 + drawille , 141 125 120 116 byte

Đã lưu 16 byte nhờ ngn và L3viathan

Đã lưu 5 byte nhờ L3viathan

Đã lưu 4 byte nhờ 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()

Hãy thử trực tuyến!

tio không cài đặt drawille nên nó không hoạt động


Python và pin của nó! :) Không làm tôi ngạc nhiên. Bạn có thể thu nhỏ này xuống dưới 120 byte nếu bạn sử dụng enumerate()và hiểu danh sách.
ngn

Lưu một vài byte bằng cách làm cho hàm thành một lớp lót: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


bạn không cần and cmánh khóe - sự hiểu biết có thể là một tuyên bố theo sau bởi chính nó;print c.frame()
ngn

3

APL (Dyalog) , 57 54 byte *

-3 cảm ơn OP. Nhắc nhở cho ma trận Boolean. In ma trận ký tự.

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

Hãy thử trực tuyến!

⎕,0 nối số 0 ở bên phải (bỏ qua nếu số cột chẵn)

 mang lại rằng (để tách 3)

⍪∘0⍣3 nối các số không vào ba lần dưới cùng (vì giảm một phần cửa sổ)

0⍪⍣3 xếp các số 0 trên ba lần trên cùng (vì bắt đầu ở góc trên cùng bên trái)

 mang lại rằng (tách dấu ngoặc đơn và 0)

{... }⌺(2 2⍴4 2) trên mỗi 4 hàng cửa sổ 2 cột, với 4 hàng dọc và 2 liên tiếp bước ngang:

⊢⌿⍵ hàng cuối cùng (giảm dọc phải); [b6,b7]

(... ), thêm vào trước:

  3↑ lấy ba hàng; [[b0,b3],[b1,b4],[b2,b5]]

   chuyển vị; [[b0,b1,b2],[b3,b4,b5]]

  , rốn; [b0,b1,b2,b3,b4,b5]

 Bây giờ chúng tôi có [b0,b1,b2,b3,b4,b5,b6,b7]

 đảo ngược; [b7,b6,b5,b4,b3,b2,b1,b0]

40, trả trước 40 (cho 40 × 2 9 = 10240);[40,b7,b6,b5,b4,b3,b2,b1,b0]

2⊥ đánh giá là cơ sở 2 (nhị phân)

⎕UCS chuyển đổi thành nhân vật

1↓ thả hàng đầu tiên (tất cả bằng không vì phần đệm)


* Trong cổ điển, tính như ⎕U233A.


Có một cách dễ dàng để lưu một vài byte, xem nhận xét của tôi trong giải pháp Jelly.
ngn

Phải có một lỗi - liên kết TIO không khớp với mã bạn đã đăng ở đây.
ngn

đó là mã không đệm gần cuối: 0⍪⍣3⍪∘0⍣3⊢⎕,0vs0⍪∘0⍣3⊢⎕,0
ngn

@ngn Đã sửa, nhưng tôi có cảm giác rằng ⍪∘0⍣3,0chỉ cần do lỗi trong và lỗi đầu tiên là không cần thiết cho các trường hợp thử nghiệm của bạn.
Adám

Các trường hợp thử nghiệm của tôi không toàn diện - tất nhiên, giải pháp nên hoạt động cho mọi đầu vào hợp lệ. Bạn có thể rút ngắn 0⍪⍣3⍪∘0⍣3⊢⍵,0để 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)

Hãy thử trực tuyến!


Chơi golf độc đáo! Bạn có thể lưu ba byte [*zip(*m[:4])]thay vì gọi list.
Lynn


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

Hãy thử trực tuyến!


Bạn có thể viết lại if y%4<1:a+=-~len(l)//2*[10240],như a+=(y%4<1)*[-~len(l)//2*[10240]]và phù hợp x=0;y+=1trên cùng một dòng. Tôi nghĩ rằng nó tiết kiệm một byte.
ngn

@ngn đã lưu thêm một vài byte từ đó trở đi, cảm ơn bạn!
Lynn

1

Perl 5 , 164 byte

163 byte mã + 1 cờ -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}$\.=$/}

Hãy thử trực tuyến!

Mất mỗi dấu phẩy được phân tách trên một dòng.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.