Nhận biết số nghệ thuật ASCII


15

Thử thách

Nhận biết số nghệ thuật ASCII. Để làm cho mọi thứ thú vị, ba điểm ngẫu nhiên trong hình ảnh có thể được lật. Ví dụ:

 ***** 
 *  ** 
    ** 

   **  
  **   
 **    

Đầu vào

Số nghệ thuật 7x7 ASCII được tạo bởi tập lệnh Python bên dưới.

Đầu ra

Một chữ số.

Kiểm tra tập lệnh

Đây là tập lệnh Python (2.6+) để tạo các trường hợp thử nghiệm:

import random

digits = '''\
  ***  
 ** ** 
**   **
**   **
**   **
 ** ** 
  ***  

   *   
 ***   
   *   
   *   
   *   
   *   
 ***** 

  ***  
 *  ** 
     * 
    ** 
   **  
  **   
 ******

  ***  
 *  ** 
     * 
  ***  
     * 
 *  ** 
  ***  

   **  
  ***  
 * **  
*  **  
****** 
   **  
   **  

 ***** 
 **    
 ****  
     * 
     * 
 *   * 
  ***  

  **** 
 **    
 ***** 
 *   * 
 **  **
 **  * 
  **** 

 ***** 
    ** 
    ** 
   **  
   **  
  **   
 **    

  **** 
 **  **
 **  **
  **** 
 **  **
 **  **
  **** 

  ***  
 ** ** 
**   **
 **  * 
  **** 
    ** 
 ****  '''.split('\n\n')

def speckle(image, num_speckles):
    grid = [list(row) for row in image.split('\n')]

    for i in range(num_speckles):
        row = random.choice(grid)
        row[random.randint(0, 6)] = random.choice([' ', '*'])

    return '\n'.join([''.join(row) for row in grid])

digit = random.choice(digits)

print(speckle(digit, 3))

Bạn có chắc khoảng cách Hamming giữa mỗi hai chữ số là hơn 6 không?
John Dvorak

@JanDvorak: Tôi đã điều chỉnh phông chữ để điều này không thành vấn đề. Bạn có thấy một cái không?
Máy xay sinh tố

Câu trả lời:


9

APL ( 87 85)

1-⍨⊃⍒(,↑{7↑'*'=⍞}¨⍳7)∘(+.=)¨{49↑,(16/2)⊤⎕UCS⍵}¨↓10 3⍴'嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢'

Giải trình:

Mỗi số ASCII có thể được mã hóa thành 48 bit. (Bit thứ 49 luôn luôn bằng không). Chuỗi 嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢có ba ký tự cho mỗi số ASCII, mỗi ký tự mã hóa 16 bit.

  • ↓10 3⍴: chia chuỗi dữ liệu thành 10 nhóm 3 char, mỗi nhóm mã hóa một số.
  • {... : cho mỗi nhóm:
    • (16/2)⊤⎕UCS⍵: nhận 16 bit đầu tiên của mỗi trong ba ký tự
    • ,: nối các mảng bit thành một mảng
    • 49↑: lấy 49 phần tử đầu tiên. Chỉ có 48, vì vậy điều này tương đương với việc thêm một 0ở cuối.
  • ,↑{7↑'*'=⍞}¨⍳7: đọc 7 dòng 7 ký tự từ bàn phím, tạo một mảng bit cho mỗi dòng 1có nghĩa là ký tự là a *và nối chúng lại với nhau.
  • (+.=)¨: cho mỗi chữ số có thể, tính toán số lượng bit đầu vào có chung với chữ số.
  • : lấy các chỉ số cho một loại xuống của danh sách đó, sao cho mục đầu tiên trong kết quả là chỉ số của số lớn nhất trong danh sách trước.
  • : lấy mục đầu tiên, là chỉ số của chữ số
  • 1-⍨: trừ đi một, vì các chỉ số APL dựa trên 1.

3
wow 87? phải là chương trình APL dài nhất từ ​​trước đến nay.
izabera

4
Tôi luôn nghĩ APL luôn trông giống Hy Lạp. Bây giờ Trung Quốc cũng vậy?!?
Chấn thương kỹ thuật số


5

Con trăn

Tôi chắc chắn sẽ có giải pháp OCR, nhưng xác suất của tôi là chính xác cao hơn nhiều.

import difflib as x;r=range;s='2***3**1**1**3****3****3**1**1**3***23*4***6*6*6*6*4*****12***3*2**6*5**4**4**4******2***3*2**6*3***7*2*2**3***23**4***3*1**2*2**2******4**5**21*****2**5****7*6*2*3*3***22****2**5*****2*3*2**2**1**2*3****11*****5**5**4**5**4**4**42****2**2**1**2**2****2**2**1**2**2****12***3**1**1**3**1**2*3****5**2****2'
for c in r(8):s=s.replace(str(c),' '*c)
s=map(''.join,zip(*[iter(s)]*7));a=[raw_input("") for i in r(7)];l=[[x.SequenceMatcher('','|'.join(a),'|'.join(s[i*7:(i+1)*7])).ratio()] for i in r(10)];print l.index(max(l))

Nhập một dòng văn bản tại một thời điểm.

Không chắc chắn về cách tốt hơn để đối phó với các dấu sao mà không làm tăng số lượng nhân vật.


4

JavaScript (ES6), 89

f=n=>(a=1,[a=(a+a^c.charCodeAt())%35 for(c of n)],[4,25,5,16,0,11,32,13,10,1].indexOf(a))

Sử dụng:

> f("  ***  \n *  ** \n     * \n    ** \n   **  \n  **   \n ******")
2

Phiên bản không chơi gôn:

f = (n) => (
  // Initialize the digit's hash.
  a=1,
  // Hash the digit.
  // 35 is used because the resulting hash is unique for the first ten digits.
  // Moreover, it generates 4 1-digit hashes.
  [a = (a + a ^ c.charCodeAt()) % 35 for(c of n)],
  // Compare the hash to pre-computed digit hash.
  // The matching hash index is the digit.
  [4,25,5,16,0,11,32,13,10,1].indexOf(a)
)

3
Điều này có hoạt động không nếu đầu vào không chính xác bằng một trong các chữ số? Theo câu hỏi, ba pixel có thể được lật và nó vẫn hoạt động.
bến

3

Bash + ImageMagick + tesseract, ký tự 316

Đây là một cú đâm vào một giải pháp OCR. Mặc dù nó không chính xác lắm, ngay cả khi nói với tesseract rằng chúng ta chỉ có một char và nó là một chữ số. Chơi golf vừa phải, nhưng vẫn có thể đọc được phần nào:

w=0
c()((w=${#2}>w?${#2}:w))
mapfile -c1 -Cc -t l
h=${#l[@]}
{
echo "# ImageMagick pixel enumeration: $w,$h,1,gray"
for y in ${!l[@]};{
for((x=0;x<w;x++));{
[ "${l[$y]:$x:1}" != " " ]
echo "$x,$y: ($?,$?,$?)"
}
}
}|convert txt:- i.png
tesseract i.png o -psm 10 <(echo "tessedit_char_whitelist 0123456789")
cat o.txt

Kịch bản lấy đầu vào từ stdin, vì vậy chúng ta có thể chuyển từ kịch bản kiểm tra.

Lưu ý tôi đã đưa tee >( cat 1>&2 )vào đường ống chỉ để chúng ta có thể thấy tập lệnh thử nghiệm thực sự được tạo ra.

Ví dụ đầu ra (Đây là một hoạt động khá tốt với chỉ 1 char không chính xác trong số 6):

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
* **
 ** * 
  **** 
    ***
 ****  
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
9

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
   *   
 *** *
   *   
   *   
   *   
   *   
 ***** 
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
1

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
** **
** **
** **
  * ** 
  ***  
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
0

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
 ***** 
 **    
 ****  
     * 
     * 
 ** * 
  ***  
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
5

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
  **** 
 **    
 ***** 
 * * 
*** ***
 ** **
  **** 
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
5

$ python ./asciitest.py | tee> (mèo 1> & 2) | ./scanascii.sh
  ***  
 * ** 
     * 
    ** 
   *** 
  **   
 ******
Tesseract Mã nguồn mở OCR Engine v3.02 với Leptonica
2

$ 

1

LÖVE2D, 560 byte

t=...;g=love.graphics g.setNewFont(124)g.setBackgroundColor(255,255,255)A=g.newCanvas()B=g.newCanvas()x=1 y=1 g.setColor(255,255,255)g.setCanvas(B)g.clear(0,0,0)for i=1,#t do x=x+1 if t:sub(i,i)=="\n"then x=1 y=y+1 end if t:sub(i,i)=="*"then g.rectangle("fill",x*16,y*16,16,16)end end u=B:newImageData()g.setCanvas(A)S={}for i=0,9 do g.clear(0,0,0,0)g.print(i,48,0)r=A:newImageData()s={i=i,s=0}for x=0,16*8 do for y=0,16*8 do a=u:getPixel(x,y)b=r:getPixel(x,y)s.s=s.s+math.abs(a-b)end end S[i+1]=s end table.sort(S,function(a,b)return a.s<b.s end)print(S[1].i)

Đầu tiên, vẽ một biểu diễn khối của văn bản đầu vào, sau đó, với mỗi số 0 - 9, chồng lên một số, kiểm tra xem có bao nhiêu pixel tương tự và in số gần nhất. OCR rất cơ bản. Nó phù hợp với tất cả các Test Case và hoạt động tốt với các đột biến.

Gọi với:

love.exe "" "INPUT"
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.