ASCII sanat numaralarını tanıma


15

Meydan okuma

ASCII sanat sayılarını tanır. İşleri ilginç hale getirmek için görüntüdeki üç rastgele nokta ters çevrilebilir. Örneğin:

 ***** 
 *  ** 
    ** 

   **  
  **   
 **    

Giriş

Aşağıdaki Python betiği tarafından oluşturulan 7x7 ASCII sanat numarası.

Çıktı

Bir rakam.

Test komut dosyası

İşte test senaryolarını oluşturmak için bir Python betiği (2.6+):

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

Her iki basamak arasındaki Hamming mesafesinin 6'dan fazla olduğundan emin misiniz?
John Dvorak

@ JanDvorak: Bunun bir sorun olmayacak şekilde yazı tipini değiştirdim. Bir tane görüyor musun?
Blender

Yanıtlar:


9

APL ( 87 85)

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

Açıklama:

Her olası ASCII numarası 48 bit olarak kodlanır. (49'uncu bit her zaman sıfırdır). Dize 嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢, her biri 16 bit kodlayan her ASCII numarası için üç karakter içerir.

  • ↓10 3⍴: veri dizesini, her biri bir sayı kodlayan 10 3 karakterlik gruba ayırın.
  • {... : grupların her biri için:
    • (16/2)⊤⎕UCS⍵: üç karakterin her birinin ilk 16 bitini edinin
    • ,: bit dizilerini bir diziye birleştirir
    • 49↑: ilk 49 unsuru ele alalım. Sadece 48 tane var, bu yüzden 0sonunda a eklemekle eşdeğer .
  • ,↑{7↑'*'=⍞}¨⍳7: klavyeden 7 karakterden oluşan 7 satırı okuyun, her satır 1için karakterin a olduğu anlamına gelen bir bit dizisi oluşturun *ve bunları birleştirin.
  • (+.=)¨: olası her basamak için, girdinin basamakla ne kadar ortak biti olduğunu hesaplayın.
  • : sonuçtaki ilk öğenin önceki listedeki en büyük sayının dizini olması için bu listenin aşağı doğru türüne ilişkin dizinleri alın.
  • : basamağın dizini olan ilk öğeyi al
  • 1-⍨: APL indeksleri 1 tabanlı olduğu için birini çıkartın.

3
vay 87? şimdiye kadarki en uzun APL programı olmalı.
izabera

4
APL'nin her zaman Yunancasına benzediğini düşünürdüm. Şimdi de Çinli mi?!?
Dijital Travma


5

piton

Eminim OCR çözümleri olacak, ancak benimkinin doğru olma olasılığı çok daha yüksek.

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

Her seferinde bir metin satırı girin.

Karakter sayısını artırmadan yıldızlarla baş etmenin daha iyi bir yolundan emin değilim.


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

Kullanımı:

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

Golfsiz sürüm:

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
Giriş, rakamlardan birine tam olarak eşit değilse bu işe yarar mı? Soruya göre, üç piksel çevrilebilir ve yine de çalışması gerekir.
marinus

3

Bash + ImageMagick + tesseract, 316 karakter

İşte OCR çözümünde bir bıçak. Bu çok doğru değil, hatta tesseract'a sadece bir karakterimiz olduğunu ve bir rakam olduğunu söylerken bile. Orta derecede golfçü ama yine de biraz okunabilir:

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

Betik stdin'den girdi alır, böylece test betiğinden bağlantı kurabiliriz.

Not Ben tee >( cat 1>&2 )sadece test senaryosunun aslında ne ürettiğini görebilmemiz için boru hattına koydum .

Örnek çıktı (Bu, 6 üzerinden sadece 1 yanlış karakter ile oldukça iyi bir çalışma idi):

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
* **
 ** * 
  **** 
    ***
 ****  
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
9

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
   *   
 *** *
   *   
   *   
   *   
   *   
 ***** 
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
1

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
** **
** **
** **
  * ** 
  ***  
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
0

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
 ***** 
 **    
 ****  
     * 
     * 
 ** * 
  ***  
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
5

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
  **** 
 **    
 ***** 
 * * 
*** ***
 ** **
  **** 
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
5

$ python ./asciitest.py | tee> (kedi 1> & 2) | ./scanascii.sh
  ***  
 * ** 
     * 
    ** 
   *** 
  **   
 ******
Leptonica ile Tesseract Açık Kaynak OCR Motoru v3.02
2

$ 

1

LÖVE2D, 560 Bayt

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)

İlk olarak, giriş metninin bloklu bir temsilini çizer, daha sonra her 0 - 9 sayısı için bir sayıyı kaplar, kaç tane benzer piksel olduğunu kontrol eder ve en yakın olan sayıyı yazdırır. Çok temel OCR. Tüm Test Durumlarıyla eşleşir ve mutasyonlarla oldukça iyi performans gösterir.

İle ara:

love.exe "" "INPUT"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.