김창준씨의 코드를 보고 느끼는 점이 많아 흉내를 내 보았습니다.
재밌는 시간이었구요.
~cpp #!python
# -*- coding: euc-kr -*-
'''
* slurpy (slimp and slump)
* slump - (D or E) and F+ and (slump or G)
* slimp - A and (H or ((B and slimp and C) or (slump and C))
** find slurpy!
[example]
Slumps : DFG, EFG, DFFFFFG, DFDFDFDFG, DFEFFFFFG
Not Slumps: DFEFF, EFAHG, DEFG, DG, EFFFFDG
Slimps: AH, ABAHC, ABABAHCC, ADFGC, ADFFFFGC, ABAEFGCC, ADFDFGC
Not Slimps: ABC, ABAH, DFGC, ABABAHC, SLIMP, ADGC
Slurpys: AHDFG, ADFGCDFFFFFG, ABAEFGCCDFEFFFFFG
Not Slurpys: AHDFGA, DFGAH, ABABCC
'''
import unittest
class UnitPattern:
def __init__(self, *args):
self.args = args
self._remain = ''
def match(self, target):
raise NotImplementedError
def remain(self):
return self._remain
class Word(UnitPattern):
def match(self, target):
if not target: return False
self._remain = target[1:]
return self.args[0][0] == target[0]
class And(UnitPattern):
def match(self, target):
for arg in self.args:
if not arg.match(target):
return False
target = arg.remain()
self._remain = target
return True
class Or(UnitPattern):
def match(self, target):
for arg in self.args:
if arg.match(target):
self._remain = arg.remain()
return True
return False
class More(UnitPattern):
def match(self, target):
if not target: return False
moreword = self.args[0][0]
for count, t in enumerate(target):
if t != moreword:
if count == 0 : return False
break
self._remain = target[count:]
return True
class MultiPattern:
def match(self, target):
return self.pat.match(target)
def remain(self):
return self.pat.remain()
class Slump(MultiPattern):
''' slump - (D or E) and F+ and (slump or G) '''
def __init__(self):
self.pat = And(
Or(Word('D'), Word('E')),
More('F'),
Or(self, Word('G'))
)
class Slimp(MultiPattern):
''' slimp - A and (H or ((B and slimp and C) or (slump and C)) '''
def __init__(self):
self.pat = And(
Word('A'),
Or(
Word('H'),
Or(
And(Word('B'), self, Word('C')),
And(Slump(), Word('C'))
)
)
)
def isSlurpy(target):
''' slurpy (slimp and slump) '''
pat = And(Slimp(), Slump())
result = pat.match(target)
if pat.remain(): return False
return result
### test code ##########################################################
class SlurpyTest(unittest.TestCase):
def testWord(self):
word = Word('D')
self.assertEquals(True, word.match('DEF'))
self.assertEquals('EF', word.remain())
def testAnd(self):
D = Word('D')
E = Word('E')
andDE = And(D,E)
self.assertEquals(True, andDE.match('DE'))
def testMore(self):
self.assertEquals(True, More('F').match('FFFF'))
self.assertEquals(True, And(Word('D'), More('F')).match('DFFF'))
more = More('F')
more.match('FGHG')
self.assertEquals('GHG', more.remain())
def testOr(self):
self.assertEquals(True, Or(Word('F'), Word('E')).match('F'))
self.assertEquals(True, Or(Word('F'), Word('E')).match('E'))
self.assertEquals(True,
And(More('K'), Or(Word('F'), Word('E'))).match('KKKKE'))
def testSlump(self):
#Slumps : DFG, EFG, DFFFFFG, DFDFDFDFG, DFEFFFFFG
self.assertEquals(True, Slump().match('DFG'))
self.assertEquals(True, Slump().match('EFG'))
self.assertEquals(True, Slump().match('DFFFFFG'))
self.assertEquals(True, Slump().match('DFDFDFDFG'))
self.assertEquals(True, Slump().match('DFEFFFFFG'))
#Not Slumps : DFEFF, EFAHG, DEFG, DG, EFFFFDG
self.assertEquals(False, Slump().match('DFEFF'))
self.assertEquals(False, Slump().match('EFAHG'))
self.assertEquals(False, Slump().match('DEFG'))
self.assertEquals(False, Slump().match('DG'))
self.assertEquals(False, Slump().match('EFFFFDG'))
def testSlimp(self):
#Slimps: AH, ABAHC, ABABAHCC, ADFGC, ADFFFFGC, ABAEFGCC, ADFDFGC
self.assertEquals(True, Slimp().match('AH'))
self.assertEquals(True, Slimp().match('ABAHC'))
self.assertEquals(True, Slimp().match('ABABAHCC'))
self.assertEquals(True, Slimp().match('ADFGC'))
self.assertEquals(True, Slimp().match('ADFFFFGC'))
self.assertEquals(True, Slimp().match('ABAEFGCC'))
self.assertEquals(True, Slimp().match('ADFDFGC'))
#Not Slimps: ABC, ABAH, DFGC, ABABAHC, SLIMP, ADGC
self.assertEquals(False, Slimp().match('ABC'))
self.assertEquals(False, Slimp().match('ABAH'))
self.assertEquals(False, Slimp().match('DFGC'))
self.assertEquals(False, Slimp().match('ABABAHC'))
self.assertEquals(False, Slimp().match('SLIMP'))
self.assertEquals(False, Slimp().match('ADGC'))
def testSlurpy(self):
#Slurpys: AHDFG, ADFGCDFFFFFG, ABAEFGCCDFEFFFFFG
self.assertEquals(True, isSlurpy('AHDFG'))
self.assertEquals(True, isSlurpy('ADFGCDFFFFFG'))
self.assertEquals(True, isSlurpy('ABAEFGCCDFEFFFFFG'))
#Not Slurpys: AHDFGA, DFGAH, ABABCC
self.assertEquals(False, isSlurpy('AHDFGA'))
self.assertEquals(False, isSlurpy('DFGAH'))
self.assertEquals(False, isSlurpy('ABABCC'))
if __name__ == '__main__':
unittest.main(argv=('', '-v'))