김창준씨의 코드를 보고 느끼는 점이 많아 흉내를 내 보았습니다. 재밌는 시간이었구요. ^^ {{{~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')) }}}