ASCII कला संख्या को पहचानें


15

चुनौती

ASCII कला नंबरों को पहचानें। चीजों को दिलचस्प बनाने के लिए, छवि के तीन यादृच्छिक बिंदु फ़्लिप किए जा सकते हैं। उदाहरण के लिए:

 ***** 
 *  ** 
    ** 

   **  
  **   
 **    

इनपुट

पायथन लिपि द्वारा उत्पन्न 7x7 ASCII कला संख्या।

उत्पादन

एक अंक।

परीक्षण स्क्रिप्ट

परीक्षण मामलों को उत्पन्न करने के लिए यहां एक पायथन स्क्रिप्ट (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))

क्या आप सुनिश्चित हैं कि प्रत्येक दो अंकों के बीच हैमिंग की दूरी 6 से अधिक है?
जॉन ड्वोरक

@JDDvorak: मैंने फ़ॉन्ट को ट्विक किया ताकि यह समस्या न हो। क्या आप एक को देखते हैं?
ब्लेंडर

जवाबों:


9

एपीएल ( 87 85)

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

स्पष्टीकरण:

प्रत्येक संभव ASCII संख्या 48 बिट्स में एन्कोडेड है। (49 वां बिट हमेशा वैसे भी शून्य होता है)। स्ट्रिंग 嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢में ASCII नंबर प्रति तीन वर्ण हैं, जिनमें से प्रत्येक में 16 बिट्स एन्कोड हैं।

  • ↓10 3⍴: डेटा स्ट्रिंग को 10 3-चार समूहों में विभाजित करें, जिनमें से प्रत्येक एक संख्या को एन्कोड करता है।
  • {... : प्रत्येक समूह के लिए:
    • (16/2)⊤⎕UCS⍵: प्रत्येक तीन अक्षरों के पहले 16 बिट्स प्राप्त करें
    • ,: एक सरणी में बिट सरणियों को संक्षिप्त करें
    • 49↑: पहले 49 तत्वों को लें। केवल 48 हैं, इसलिए यह 0अंत में जोड़ने के बराबर है ।
  • ,↑{7↑'*'=⍞}¨⍳7: कीबोर्ड से 7 वर्णों की 7 पंक्तियों को पढ़ें, प्रत्येक पंक्ति के लिए थोड़ा सा सरणी बनाएं जहां 1इसका मतलब है कि चरित्र एक था *, और उन्हें एक साथ मिलाएं।
  • (+.=)¨: प्रत्येक संभावित अंक के लिए, गणना करें कि अंक के साथ इनपुट में कितने बिट्स थे।
  • : उस सूची के नीचे की ओर के लिए सूचकांक प्राप्त करें, ताकि परिणाम में पहला आइटम पिछली सूची में सबसे बड़ी संख्या का सूचकांक हो।
  • : पहला आइटम लें, जो अंक का सूचकांक है
  • 1-⍨: एक को घटाएं, क्योंकि एपीएल सूचकांक 1-आधारित हैं।

3
वाह 87? अब तक का सबसे लंबा एपीएल कार्यक्रम होना चाहिए।
इजाबेरा

4
मैंने हमेशा सोचा था कि एपीएल हमेशा ग्रीक जैसा दिखता है। अब चीनी भी?
डिजिटल ट्रामा


5

अजगर

मुझे यकीन है कि ओसीआर समाधान होंगे, लेकिन मेरा सटीक होने की संभावना बहुत अधिक है।

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

एक समय में पाठ की एक पंक्ति इनपुट करें।

चरित्र की गिनती में वृद्धि के बिना तारांकन से निपटने के लिए एक बेहतर तरीका सुनिश्चित नहीं है।


4

जावास्क्रिप्ट (ईएस 6), 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))

उपयोग:

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

अन-गोल्फ संस्करण:

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
क्या यह काम करता है अगर इनपुट अंक में से एक के बराबर नहीं है? प्रश्न के अनुसार, तीन पिक्सेल फ़्लिप हो सकते हैं और यह अभी भी काम करना चाहिए।
मारिनस

3

बैश + इमेजमैजिक + टेसरैक्ट, 316 चार्ट

यहाँ एक OCR समाधान पर एक छुरा है। यह बहुत सटीक नहीं है, हालांकि, यह बताते हुए भी कि हमारे पास सिर्फ एक चार्ट है और यह एक अंक है। मामूली रूप से गोल्फ, लेकिन अभी भी कुछ हद तक पठनीय:

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

स्क्रिप्ट स्टड से इनपुट लेती है, इसलिए हम टेस्ट स्क्रिप्ट से पाइप कर सकते हैं।

नोट मैंने tee >( cat 1>&2 )अभी पाइपलाइन में डाला है ताकि हम देख सकें कि वास्तव में परीक्षण स्क्रिप्ट क्या उत्पन्न हुई थी।

उदाहरण आउटपुट (यह 6 में से केवल 1 गलत चार के साथ एक बहुत अच्छा रन था):

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
  ***  
 ** ** 
* **
 ** * 
  **** 
    ***
 ****  
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
9

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
   *   
 *** *
   *   
   *   
   *   
   *   
 ***** 
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
1

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
  ***  
 ** ** 
** **
** **
** **
  * ** 
  ***  
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
0

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
 ***** 
 **    
 ****  
     * 
     * 
 ** * 
  ***  
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
5

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
  **** 
 **    
 ***** 
 * * 
*** ***
 ** **
  **** 
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
5

$ python ./asciitest.py | टी> (बिल्ली 1> और 2) | ./scanascii.sh
  ***  
 * ** 
     * 
    ** 
   *** 
  **   
 ******
लेप्टिका के साथ टेसरैक्ट ओपन सोर्स OCR इंजन v3.02
2

$ 

1

LÖVE2D, 560 बाइट्स

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)

सबसे पहले, इनपुट पाठ का एक अवरुद्ध प्रतिनिधित्व करता है, फिर, प्रत्येक संख्या 0 - 9 के लिए, एक संख्या को ओवरले करता है, यह जांचता है कि कितने समान पिक्सेल हैं, और उस संख्या को प्रिंट करता है जिसे निकटतम मिला। बहुत बुनियादी ओसीआर। यह सभी टेस्ट मामलों से मेल खाता है, और म्यूटेशन के साथ यथोचित प्रदर्शन करता है।

के साथ बुलाना:

love.exe "" "INPUT"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.