রি 2 ডি ক্লাস, পাইথন 2
আপডেট: যুক্ত হয়েছে "9. প্রান্তিককরণ" সমস্যা।
আমার পদ্ধতিটি পাইথন রি মডিউলটি অনুসন্ধান এবং মিল করতে করতে ব্যবহার করা। রি 2 ডি ক্লাস প্রক্রিয়াকরণের জন্য পাঠ্য প্রস্তুত করে, পুনরায় ফাংশনগুলি সম্পাদন করে এবং ফলাফলকে আউটপুট হিসাবে বিন্যাস করে।
মনে রাখবেন যে এটি সম্পূর্ণ নতুন ভাষা নয় - এটি অতিরিক্ত 2 ডি মোডের জন্য যুক্ত পতাকাগুলির সাথে 2 টি মাত্রায় প্রমিত মানের নিয়মিত প্রকাশের ভাষা।
শ্রেণীর নিম্নলিখিত ব্যবহার রয়েছে:
re2dobject = Re2d(<horizontal pattern>, [<vertical pattern>], [<flags>])
উভয় নিদর্শন স্ট্যান্ডার্ড লিনিয়ার পাঠ্য আরই নিদর্শন। যদি একটি উল্লম্ব প্যাটার্ন সরবরাহ না করা হয় তবে শ্রেণিটি উল্লম্বভাবে মিলে যাওয়ার জন্য অনুভূমিক প্যাটার্নটি ব্যবহার করবে। পতাকাগুলি 2 ডি এক্সটেনশান সহ স্ট্যান্ডার্ড আর আর পতাকা।
পরীক্ষামূলক
1. Finding chessboards
Chessboard pattern at (2, 1, 4, 3)
print '\n1. Finding chessboards'
reob1 = Re2d('#(_#)+_?|_(#_)+#?')
found = reob1.search('~______~\n~##_#_#~\n~#_#_##~\n~##_#_#~\n~______~')
print 'Chessboard pattern at', found
assert not reob1.search('#_##\n_#_#\n__#_\n#_#_\n#_#_')
অনুসন্ধান পদ্ধতিটি দাবাবোর্ডের ধরণ খুঁজে পেয়েছে এবং একটি 4-টিউপল পজিশন দেয়। টিপলের x,y
ম্যাচের প্রথম চরিত্রের অবস্থান এবং
অঞ্চলটির width, height
মিল রয়েছে। শুধুমাত্র একটি প্যাটার্ন দেওয়া হয়েছে সুতরাং এটি অনুভূমিক এবং উল্লম্ব মিলের জন্য ব্যবহৃত হবে ।
2. Verifying chessboards
Is chess? True
print '\n2. Verifying chessboards'
reob2 = Re2d('^#(_#)*_?|_(#_)*#?$')
print 'Is chess?', reob2.match('_#_#_#_#\n#_#_#_#_\n_#_#_#_#')
assert not reob2.match('_#_#_#__\n__#_#_#_\n_#_#_#__')
দাবাবোর্ডটি ম্যাচ পদ্ধতিতে যাচাই করা হয়েছিল যা একটি বুলিয়ান দেয়। মনে রাখবেন যে, ^
এবং $
শুরু করা এবং শেষ অক্ষর মেলে প্রয়োজন হয় পুরো
পাঠ্য।
3. Rectangle of digits
Found: [(0, 1, 5, 3), (1, 1, 4, 3), (2, 1, 3, 3), (3, 1, 2, 3), (0, 2, 5, 2), (1, 2, 4, 2), (2, 2, 3, 2), (3, 2, 2, 2), (6, 3, 2, 2)]
Not found: None
print '\n3. Rectangle of digits'
reob3 = Re2d(r'\d\d+', flags=MULTIFIND)
print 'Found:', reob3.search('hbrewvgr\n18774gwe\n84502vgv\n19844f22\ncrfegc77')
print 'Not found:', reob3.search('uv88wn000\nvgr88vg0w\nv888wrvg7\nvvg88wv77')
আমরা এখন MULTIFIND
2+ অঙ্কের ব্লকের সম্ভাব্য সমস্ত ম্যাচ ফিরিয়ে দিতে পতাকা ব্যবহার করি । পদ্ধতিটি 9 টি সম্ভাব্য ম্যাচ সন্ধান করে। মনে রাখবেন যে তারা ওভারল্যাপিং করতে পারে।
4. Word search (orthogonal only)
Words: [(0, 0, 4, 1), (0, 3, 4, 1), (3, 3, -4, -1), (3, 2, -4, -1), (3, 0, -4, -1)] [(0, 0, 1, 4), (3, 0, 1, 4), (3, 3, -1, -4), (0, 3, -1, -4)]
Words: ['SNUG', 'WOLF', 'FLOW', 'LORE', 'GUNS'] ['S\nT\nE\nW', 'G\nO\nL\nF', 'F\nL\nO\nG', 'W\nE\nT\nS']
No words: [] []
print '\n4. Word search (orthogonal only)'
words = 'GOLF|GUNS|WOLF|FLOW|LORE|WETS|STEW|FLOG|SNUG'
flags = HORFLIP | VERFLIP | MULTIFIND
reob4a, reob4b = Re2d(words, '.', flags), Re2d('.', words, flags)
matching = 'SNUG\nTEQO\nEROL\nWOLF'
nomatch = 'ABCD\nEFGH\nIJKL\nMNOP'
print 'Words:', reob4a.search(matching), reob4b.search(matching)
print 'Words:', reob4a.findall(matching), reob4b.findall(matching)
print 'No words:', reob4a.findall(nomatch), reob4b.findall(nomatch)
এই পরীক্ষাটি উল্লম্ব এবং অনুভূমিক উল্টানো ব্যবহার দেখায়। এটি বিপরীত শব্দগুলির সাথে মিলে যায়। তির্যক শব্দগুলি সমর্থন করে না।
MULTIFIND
পতাকা সব 4 নির্দেশাবলী মধ্যে একাধিক ওভারল্যাপিং ম্যাচ পারেন। অনুসন্ধানের পদ্ধতিটি মেলানো বাক্সগুলি অনুসন্ধানের জন্য অনুসন্ধানের পরে টেক্সটের মেলানো ব্লকগুলি বের করে racts বিপরীত দিকের ম্যাচগুলির জন্য অনুসন্ধান কীভাবে নেতিবাচক প্রস্থ এবং / অথবা উচ্চতা ব্যবহার করে তা নোট করুন। উল্লম্ব দিকের শব্দগুলির মধ্যে নতুন রেখার অক্ষর রয়েছে - এটি 2D অক্ষর ব্লকের ধারণার সাথে সামঞ্জস্যপূর্ণ।
7. Calvins portals
Portals found: [(3, 1, 5, 6)]
Portal not found None
print '\n7. Calvins portals'
reob7 = Re2d(r'X\.{2,22}X|.X{2,22}.', r'X\.{3,22}X|.X{3,22}.', MULTIFIND)
yes = '....X......\n.XXXXXX.XX.\n...X...X...\n.X.X...XXX.\n...X...X.X.\n.XXX...X.X.\nX..XXXXX.X.'
no = 'XX..XXXX\nXX..X..X\nXX..X..X\n..X.X..X\n.X..X.XX'
print 'Portals found:', reob7.search(yes)
print 'Portal not found', reob7.search(no)
এই সন্ধানটির প্রতিটি মাত্রার জন্য পৃথক নিদর্শনগুলির প্রয়োজন কারণ প্রত্যেকের জন্য ন্যূনতম আকার পৃথক।
9. Alignment
Found: ['#.,##', '##'] ['#\n.\n,\n.\n#', '#\n,\n.\n#']
Found: [(3, 4, 5, 1), (6, 4, 2, 1)] [(7, 0, 1, 5), (3, 1, 1, 4)]
Not found: None None
print '\n9. Alignment'
reob9a = Re2d(r'#.*#', r'.', MULTIFIND)
reob9b = Re2d(r'.', r'#.*#', MULTIFIND)
matching = '.,.,.,.#.,\n,.,#,.,.,.\n.,.,.,.,.,\n,.,.,.,.,.\n.,.#.,##.,\n,.,.,.,.,.'
nomatch = '.,.#.,.,\n,.,.,.#.\n.,#,.,.,\n,.,.,.,#\n.#.,.,.,\n,.,.#.,.\n#,.,.,.,\n,.,.,#,.'
print 'Found:', reob9a.findall(matching), reob9b.findall(matching)
print 'Found:', reob9a.search(matching), reob9b.search(matching)
print 'Not found:', reob9a.search(nomatch), reob9b.search(nomatch)
2 টি অনুসন্ধানের এই সেটটি 2 টি উল্লম্ব এবং 2 টি অনুভূমিক মিল খুঁজে পেয়েছে তবে এমবেডড #.,#
স্ট্রিংটি খুঁজে পাচ্ছে না ।
10. Collinear Points (orthogonal only)
Found: [(0, 1, 7, 1)] [(3, 1, 1, 4)]
Not found: None None
print '\n10. Collinear Points (orthogonal only)'
matching = '........\n#..#..#.\n...#....\n#.......\n...#....'
nomatch = '.#..#\n#..#.\n#....\n..#.#'
reob10h = Re2d(r'#.*#.*#', '.')
reob10v = Re2d('.', r'#.*#.*#')
flags = MULTIFIND
print 'Found:', reob10h.search(matching, flags), reob10v.search(matching, flags)
print 'Not found:', reob10h.search(nomatch, flags), reob10v.search(nomatch, flags)
উভয় দিকে মিল খুঁজে পেতে আমরা এখানে দুটি অনুসন্ধান ব্যবহার করি। এটি একাধিক অরথোগোনাল ম্যাচগুলি সন্ধান করতে সক্ষম তবে এই পদ্ধতিটি তির্যক ম্যাচগুলিকে সমর্থন করে না।
12. Avoid qQ
Found: (2, 2, 4, 4)
Not found: None
print '\n12. Avoid qQ'
reob12 = Re2d('[^qQ]{4,4}')
print 'Found:', reob12.search('bhtklkwt\nqlwQklqw\nvtvlwktv\nkQtwkvkl\nvtwlkvQk\nvnvevwvx')
print 'Not found:', reob12.search('zxvcmn\nxcvncn\nmnQxcv\nxcvmnx\nazvmne')
এই অনুসন্ধানটি প্রথম মিল খুঁজে পেয়েছে।
13. Diamond Mining
.X.
X.X
.X.
.X.
X.X
.X.
..X..
./.\.
X...X
.\./.
\.X..
..X..
./.\.
X...X
.\./.
..X..
.XX.\
//.\.
X...X
.\./.
..X..
...X...
../.\..
./.X.\.
X.X.X.X
.\.X.//
..\./X.
.X.X..\
Diamonds: [(2, 2, 3, 3), (0, 6, 3, 3)] [(8, 0, 5, 5), (10, 2, 5, 5), (5, 3, 5, 5)] [(0, 0, 7, 7)]
Not found: None None None
print '\n13. Diamond Mining'
reob13a = Re2d(r'.X.|X.X', flags=MULTIFIND)
reob13b = Re2d(r'..X..|./.\\.|X...X|.\\./.', flags=MULTIFIND)
reob13c = Re2d(r'...X...|../.\\..|./...\\.|X.....X|.\\.../.|..\\./..', flags=MULTIFIND)
match = '''
...X......X....
../.\..../.\...
./.X.\..X...X..
X.X.X.XX.\./.\.
.\.X.//.\.X...X
..\./X...X.\./.
.X.X..\./...X..
X.X....X.......
.X.............
'''.strip().replace(' ', '')
nomatch = '''
.X......./....
.\....X.......
...X.\.\...X..
..X.\...\.X.\.
...X.X...X.\.X
../X\...\...X.
.X...\.\..X...
..\./.X....X..
...X..../.....
'''.strip().replace(' ', '')
for diamond in reob13a.findall(match)+reob13b.findall(match)+reob13c.findall(match):
print diamond+'\n'
print 'Diamonds:', reob13a.search(match), reob13b.search(match), reob13c.search(match)
print 'Not found:', reob13a.search(nomatch), reob13b.search(nomatch), reob13c.search(nomatch)
হীরা সমস্যা আরও কঠিন। তিনটি আকারের জন্য তিনটি অনুসন্ধানের সামগ্রীর প্রয়োজন। এটি পরীক্ষার সেটটিতে ছয়টি হীরা খুঁজে পেতে পারে তবে এটি পরিবর্তনশীল আকারের হীরাতে স্কেল করে না। এটি হীরা সমস্যার আংশিক সমাধান।
পাইথন 2 কোড
import sys
import re
DEBUG = re.DEBUG
IGNORECASE = re.IGNORECASE
LOCALE = re.LOCALE
UNICODE = re.UNICODE
VERBOSE = re.VERBOSE
MULTIFIND = 1<<11
ROTATED = 1<<12 # not implemented
HORFLIP = 1<<13
VERFLIP = 1<<14
WRAPAROUND = 1<<15 # not implemented
class Re2d(object):
def __init__(self, horpattern, verpattern=None, flags=0):
self.horpattern = horpattern
self.verpattern = verpattern if verpattern != None else horpattern
self.flags = flags
def checkblock(self, block, flags):
'Return a position if block matches H and V patterns'
length = []
for y in range(len(block)):
match = re.match(self.horpattern, block[y], flags)
if match:
length.append(len(match.group(0)))
else:
break
if not length:
return None
width = min(length)
height = len(length)
length = []
for x in range(width):
column = ''.join(row[x] for row in block[:height])
match = re.match(self.verpattern, column, flags)
if match:
matchlen = len(match.group(0))
length.append(matchlen)
else:
break
if not length:
return None
height = min(length)
width = len(length)
# if smaller, verify with RECURSIVE checkblock call:
if height != len(block) or width != len(block[0]):
newblock = [row[:width] for row in block[:height]]
newsize = self.checkblock(newblock, flags)
return newsize
return width, height
def mkviews(self, text, flags):
'Return views of text block from flip/rotate flags, inc inverse f()'
# TODO add ROTATED to generate more views
width = len(text[0])
height = len(text)
views = [(text, lambda x,y,w,h: (x,y,w,h))]
if flags & HORFLIP and flags & VERFLIP:
flip2text = [row[::-1] for row in text[::-1]]
flip2func = lambda x,y,w,h: (width-1-x, height-1-y, -w, -h)
views.append( (flip2text, flip2func) )
elif flags & HORFLIP:
hortext = [row[::-1] for row in text]
horfunc = lambda x,y,w,h: (width-1-x, y, -w, h)
views.append( (hortext, horfunc) )
elif flags & VERFLIP:
vertext = text[::-1]
verfunc = lambda x,y,w,h: (x, height-1-y, w, -h)
views.append( (vertext, verfunc) )
return views
def searchview(self, textview, flags=0):
'Return matching textview positions or None'
result = []
for y in range(len(textview)):
testtext = textview[y:]
for x in range(len(testtext[0])):
size = self.checkblock([row[x:] for row in testtext], flags)
if size:
found = (x, y, size[0], size[1])
if flags & MULTIFIND:
result.append(found)
else:
return found
return result if result else None
def search(self, text, flags=0):
'Return matching text positions or None'
flags = self.flags | flags
text = text.split('\n') if type(text) == str else text
result = []
for textview, invview in self.mkviews(text, flags):
found = self.searchview(textview, flags)
if found:
if flags & MULTIFIND:
result.extend(invview(*f) for f in found)
else:
return invview(*found)
return result if result else None
def findall(self, text, flags=0):
'Return matching text blocks or None'
flags = self.flags | flags
strmode = (type(text) == str)
text = text.split('\n') if type(text) == str else text
result = []
positions = self.search(text, flags)
if not positions:
return [] if flags & MULTIFIND else None
if not flags & MULTIFIND:
positions = [positions]
for x0,y0,w,h in positions:
if y0+h >= 0:
lines = text[y0 : y0+h : cmp(h,0)]
else:
lines = text[y0 : : cmp(h,0)]
if x0+w >= 0:
block = [row[x0 : x0+w : cmp(w,0)] for row in lines]
else:
block = [row[x0 : : cmp(w,0)] for row in lines]
result.append(block)
if strmode:
result = ['\n'.join(rows) for rows in result]
if flags & MULTIFIND:
return result
else:
return result[0]
def match(self, text, flags=0):
'Return True if whole text matches the patterns'
flags = self.flags | flags
text = text.split('\n') if type(text) == str else text
for textview, invview in self.mkviews(text, flags):
size = self.checkblock(textview, flags)
if size:
return True
return False