「Arrow」の編集履歴(バックアップ)一覧に戻る
Arrow - (2007/07/25 (水) 05:40:53) のソース
#comment_num2 def raw_nat( dna ): r = 0 for c in dna[::-1]: if c == 'C': r*=2; r+=1 else: r*=2 return r def raw_consts( dna ): i = 0 l = len(dna) res = '' while i<l: c = dna[i] if c == 'C': res+= 'I'; i+=1 elif c == 'F': res+= 'C'; i+=1 elif c == 'P': res+= 'F'; i+=1 elif c == 'I': res += 'P'; i+=2 return res def quote( dna ): res = '' for c in dna: if c == 'I': res += 'C' elif c == 'C': res += 'F' elif c == 'F': res += 'P' else: res += 'IC' return res def asnat( n ): if n == 0: return 'P' elif n%2 == 0: return 'I' + asnat(n/2) else: return 'C' + asnat(n/2) class DNA(object): def __init__( _, dna ): _.rna = [] _.dna = dna _.c = 0 _.i = 0 def execute( _ ): while 1: print 'iteration '+str(_.c) print 'dna =',_.dna[_.i:_.i+10]+'...','('+str(len(_.dna)), 'bases)' pattern = _.pattern() print 'patern =', ''.join(pattern) template = _.template() print 'template =', ''.join(template) _.matchreplace(pattern,template) print 'len(rna) =', len(_.rna) print _.c += 1 def pattern( _ ): pattern = [] level = 0 while 1: dna = _.dna[_.i:_.i+3] if dna.startswith('C'): _.i+=1; pattern.append('I') elif dna.startswith('F'): _.i+=1; pattern.append('C') elif dna.startswith('P'): _.i+=1; pattern.append('F') elif dna.startswith('IC'): _.i+=2; pattern.append('P') elif dna.startswith('IP'): _.i+=2; pattern.append('!'+_.nat()) elif dna.startswith('IF'): _.i+=3; pattern.append('?'+_.consts()) elif dna.startswith('IIP'): _.i+=3; pattern.append('('); level += 1 elif dna.startswith('IIC') or dna.startswith('IIF'): _.i+=3 if level == 0: return pattern else: pattern.append(')') level -= 1 elif dna.startswith('III'): _.rna.append(_.dna[_.i+3:_.i+10]); _.i+=10 else: _.finish() def template( _ ): template = [] while 1: dna = _.dna[_.i:_.i+3] if dna.startswith('C'): _.i+=1; template.append('I') elif dna.startswith('F'): _.i+=1; template.append('C') elif dna.startswith('P'): _.i+=1; template.append('F') elif dna.startswith('IC'): _.i+=2; template.append('P') elif dna.startswith('IF') or dna.startswith('IP'): _.i+=2; template.append('/'+_.nat()+'_'+_.nat()) elif dna.startswith('IIC') or dna.startswith('IIF'): _.i+=3; return template elif dna.startswith('IIP'): _.i+=3; template.append('A'+_.nat()) elif dna.startswith('III'): _.rna.append(_.dna[_.i+3:_.i+10]); _.i+=10 else: _.finish() def finish( _ ): open('endo.rna','w').write('\n'.join(_.rna)) raise Exception('execution complete, ' + str(len(_.rna)) + ' rna commands') def matchreplace( _, pattern, template ): e = [] j = 0 c = [] for p in pattern: if p in 'ICFP': if _.dna[_.i+j] == p: j+=1 else: _.dna = _.dna[_.i:]; print 'match failed at pattern', p; _.i=0; return elif p.startswith('!'): j += int(p[1:]) if _.i + j >= len(_.dna): _.dna = _.dna[_.i:]; _.i=0; print 'match failed at pattern', p; return elif p.startswith('?'): try: find = _.dna[_.i+j:].index(p[1:]) print p,'found at',find j += find + len(p) -1 except: _.dna = _.dna[_.i:]; _.i=0; print 'match failed at pattern', p; return elif p == '(': c.append(j) elif p == ')': e.append(_.dna[_.i+c.pop():_.i+j]) else: print 'successful match of length', sum(map(len,e)) #for i,d in enumerate(e): print 'e['+str(i)+'] = ' + d[:10] + '... (' + str(len(d)) + ' bases)' _.dna = _.replace(template, e) + _.dna[_.i+j:] _.i = 0 def replace( _, template, e ): r = '' for t in template: if t in 'ICFP': r += t elif t.startswith('/'): level, n = map(int,t[1:].split('_')) if n < len(e): r += _.protect(level, e[n]) elif t.startswith('A'): n = int(t[1:]) if n < len(e): r += asnat(len(e[n])) else: r += asnat(0) return r def nat( _ ): try: p = _.dna[_.i:].find('P') except: _.finish() dna = _.dna[_.i:_.i+p] _.i+=p+1 return str(raw_nat(dna)) def consts( _ ): f = _.dna[_.i:].index try: p = min([f('IF'),f('IP'),f('II')]) except: _.finish() dna = _.dna[_.i:_.i+p] _.i+=p return raw_consts(dna) def protect( _, level, d ): if level == 0: return d else: return _.protect(level-1,quote(d)) if __name__ == '__main__': import sys print sys.argv[1] try: prefix = open(sys.argv[1]).read() except IOError: prefix = '' endo = open('endo.dna').read() DNA(prefix+endo).execute()