From f3e1c473173020d25f56f0319ba5637473547416 Mon Sep 17 00:00:00 2001 From: trollhase Date: Thu, 3 Oct 2013 05:36:40 +0200 Subject: [PATCH] colortest, deriver --- colortest.py | 244 ++++++++++++++++++++++++++++++ deriver.py | 342 ++++++++++++++++++++++++++++++++++++++++++ fizzbuzz-oneline.py | 2 +- pso.py | 7 +- sorting_algorithms.py | 32 +++- 5 files changed, 615 insertions(+), 12 deletions(-) create mode 100644 colortest.py create mode 100644 deriver.py diff --git a/colortest.py b/colortest.py new file mode 100644 index 0000000..b5a177a --- /dev/null +++ b/colortest.py @@ -0,0 +1,244 @@ +import pygame +from pygame.locals import * +from random import random,randint +from math import sqrt + +screen = None +color = (128,128,128) +color_vel = (0,0,0) +running = True + +class Vector(tuple): + def __add__(self,other): + if len(self) != len(other): + raise Exception("Can't add vectors of different size: %d %d" % (len(self), len(other))) + return Vector([ self[i]+other[i] for i in range(len(self)) ]) + + def __sub__(self,other): + if len(self) != len(other): + raise Exception("Can't subtract vectors of different size") + return Vector([ self[i]-other[i] for i in range(len(self)) ]) + + def __mul__(self,factor): + return Vector([ self[i]*factor for i in range(len(self)) ]) + + def __div__(self,factor): + return self.__mul__(1.0/factor) + + def __rmul__(self,factor): + return self.__mul__(factor) + + def __rdiv__(self,factor): + raise NotImplemented + + def __iadd__(self,other): + return self.__add__(other) + + def __isub__(self,other): + return self.__sub__(other) + + def __neg__(self): + return self.__mul__(-1.0) + + def __setitem__(self,k,v): + raise Exception("Not available") # immutable + + def distance(self, other): + if len(self) != len(other): + raise Exception("Can't calculate distance between vectors of different size") + return sqrt(sum([ (self[i]-other[i])**2 for i in range(len(self)) ])) + + def length(self): + return self.distance( Vector( (0,0) ) ) + + +class Tick(object): + def __init__(self, tickrange): + self.tickrange = tickrange + self.m_tick = 0 + + def tick(self): + self.m_tick = (self.m_tick+1)%self.tickrange + return self.m_tick == 0 + +class Mode(object): + def __init__(self, screensize): + self.screensize = screensize + + def update(self): + pass + + def draw(self,screen): + pass + +def minmax(vmin,vmax): + return lambda v: min(vmax,max(vmin,v)) + +class TransitionMode(Mode): + t = 0.3 + a = 30 + def __init__(self, screensize): + Mode.__init__(self,screensize) + self.color = Vector( (127,127,127) ) + self.color_vel = Vector( 2*self.a*random()+self.a for i in range(3) ) + self.utick = Tick(10) + + def update(self): + if self.utick.tick(): + randvec = Vector( (2*self.a*random()-self.a) for i in range(3) ) + self.color_vel = (1-self.t)*self.color_vel+self.t*randvec + self.color = Vector( map(minmax(0,255), self.color+self.color_vel) ) + + def draw(self,screen): + screen.fill( self.color ) + +class LelMode(Mode): + color = [(255,0,0),(0,255,0)] + size = 10 + def __init__(self,screensize): + Mode.__init__(self,screensize) + self.offset = 0 + self.tick = 0 + + def update(self): + self.offset = (self.offset+1)%2 + + def draw(self,screen): + w,h = screen.get_size() + for x in range(w): + color = self.color[ (x//self.size + self.offset)%2] + pygame.draw.line(screen, color, (x,0), (x,h) ) + +class BallMode(Mode): + def __init__(self,screensize): + Mode.__init__(self,screensize) + self.ball = [200,200] + self.radius = 70 + self.velocity = [10,10] + + def update(self): + w, h = self.screensize + if self.ball[0] + self.radius >= w: + self.velocity[0] = -abs(self.velocity[0]) + elif self.ball[0] - self.radius < 0: + self.velocity[0] = abs(self.velocity[0]) + elif self.ball[1] + self.radius >= h: + self.velocity[1] = -abs(self.velocity[1]) + elif self.ball[1] - self.radius < 0: + self.velocity[1] = abs(self.velocity[1]) + + for i in range(2): + self.ball[i] += self.velocity[i] + + def draw(self,screen): + screen.fill( (0,0,0) ) + pygame.draw.circle(screen, (255,0,0), tuple(self.ball), self.radius) + + +class Particle: + def __init__(self,color, pos, vel): + self.color = color + self.pos = Vector(pos) + self.vel = Vector(vel) + + def updateVel(self,gravity,max_v=20): + gravity = Vector(gravity) + + #Update velocity + self.vel = 0.95*self.vel+0.01*random()*(gravity-self.pos)+0.1*random()*Vector( randint(-70,70) for i in range(2) ) + + #Limit speed + l = self.vel.length() + self.vel *= max_v/l + + def updatePos(self): + self.pos = self.pos + self.vel + + def draw(self,screen): + w,h = 1280,800 + if self.pos[0] > 0 and self.pos[0] < w and self.pos[1] > 0 and self.pos[1] < h: + pos = tuple(map(int,self.pos)) + velpos = tuple(map(int,self.pos+self.vel)) + pygame.draw.circle(screen, self.color, pos, 5) + pygame.draw.line(screen, (255,255,255), pos, velpos, 1 ) + + @staticmethod + def generate(xmax,ymax): + return Particle( tuple( randint(100,255) for i in range(3) ), ( randint(0,xmax), randint(0,ymax) ), tuple( randint(-50,50) for i in range(2) ) ) + +class SwarmMode(Mode): + swarmsize = 60 + def __init__(self,screensize): + Mode.__init__(self,screensize) + self.particles = list( Particle.generate(1280,800) for i in range(self.swarmsize) ) + self.generateGravity() + self.gtick = Tick(150) + self.utick = Tick(2) + + def generateGravity(self): + #self.gravity = tuple( randint(0,m) for m in [1280,800] ) + self.gravity = Vector( (1280,800) )/2 + + def update(self): + if self.gtick.tick(): + self.generateGravity() + + v = self.utick.tick() + + #king = self.particles[0] + #if v: king.updateVel(self.gravity, max_v=3) + #king.updatePos() + + for p in self.particles: + if v: p.updateVel(self.gravity) + p.updatePos() + + def draw(self,screen): + screen.fill( (0,0,0) ) + for p in self.particles: + p.draw(screen) + +class Game(object): + def __init__(self, modes=[SwarmMode,TransitionMode,LelMode,BallMode]): + self.modes = modes + pygame.init() + self.screen = pygame.display.set_mode( (1280,800), pygame.FULLSCREEN ) + pygame.mouse.set_visible(False) + self.setmode(0) + self.running = True + + def update(self): + self.mode.update() + + def setmode(self,i): + self.modeindex = i + self.mode = self.modes[i%len(self.modes)](self.screen.get_size()) + + def nextmode(self): + self.setmode( self.modeindex+1 ) + + def draw(self): + self.mode.draw(self.screen) + pygame.display.flip() + + def getevents(self): + for event in pygame.event.get(): + if event.type == QUIT: + self.running = False + elif event.type == KEYDOWN: + if event.key == K_ESCAPE: + pygame.event.post(pygame.event.Event(QUIT)) + elif event.key == K_SPACE: + self.nextmode() + + def run(self): + clock = pygame.time.Clock() + while self.running: + clock.tick(30) + self.getevents() + self.update() + self.draw() + + +if __name__ == '__main__': + Game().run() \ No newline at end of file diff --git a/deriver.py b/deriver.py new file mode 100644 index 0000000..125a0ab --- /dev/null +++ b/deriver.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python + +#DeriverTest + +import re + +LEFT = 1 +RIGHT = 2 + +def is_between(v,mi,ma): + mi = ord(mi) + ma = ord(ma) + v = ord(v) + return mi <= v and ma >= v + +def is_alpha(v): + return is_between(v,'a','z') + +def is_numeric(v): + return is_between(v,'0','9') + +class Operator2(object): + priority = 0 + symbol = None + priority_side = LEFT + def __init__(self,left,right): + self.left = left + self.right = right + + def __repr__(self): + return "(" + repr(self.left) + ") "+self.symbol+" (" + repr(self.right) + ")" + + def insert(self,id_dict,idv=None): + return self.__class__(self.left.insert(id_dict,idv),self.right.insert(id_dict,idv)) + + def __eq__(self,other): + return self.__class__ == other.__class__ and self.left == other.left and self.right == other.right + + def is_constant(self,idv=None): + return self.left.is_constant(idv) and self.right.is_constant(idv) + + def calc(self): + a = self.left.calc().value + b = self.right.calc().value + + return Numeric(self._calc(a,b)) + + def _calc(self): + raise "Error symbol %s not implemented" % self.symbol + +class Addition(Operator2): + priority = 3 + symbol = "+" + + def _calc(self,a,b): + return a + b + +class Subtraction(Operator2): + priority = 3 + symbol = "-" + + def _calc(self,a,b): + return a - b + +class Multiplication(Operator2): + priority = 2 + symbol = "*" + + def _calc(self,a,b): + return a * b + +class Division(Operator2): + priority = 2 + symbol = "/" + + def _calc(self,a,b): + return a/b + +class Power(Operator2): + priority = 1 + symbol = "^" + + def _calc(self,a,b): + return a**b + +class Numeric(object): + def __init__(self,value): + self.value = value + + def __repr__(self): + return str(self.value) + + def __eq__(self,other): + return self.__class__ == other.__class__ and self.value == other.value + + def insert(self,id_dict,idv=None): + return self.__class__(self.value) + + def is_constant(self,idv=None): + return True + + def calc(self): + return self + +class Var(object): + def __init__(self,idv): + self.idv = idv + + def insert(self,id_dict,idv=None): + raise Exception("That shits not real") + + def is_constant(self,idv=None): + if idv is None: + return False + return idv != self.idv + + def __repr__(self): + return self.idv + + def calc(self): + raise "Can't calculate a variable" + +class Parser: + operators2 = dict( (cls.symbol,cls) for cls in Operator2.__subclasses__() ) + @classmethod + def parse(cls, term): + if len(term) == 0: + raise Exception("shit's empty") + + if len(term) == 1 and is_alpha(term): + return Var(term) + + try: + numeric_value = float(term) + return Numeric(numeric_value) #return Numeric if term is numeric + except ValueError: + pass + + brackets_counter = 0 + operator_match = (-1,None) + + for index,char in enumerate(term): + if char == "(": + brackets_counter+=1 + elif char == ")": + brackets_counter-=1 + if brackets_counter < 0: + raise Exception("Bracket error") + elif char in cls.operators2 and brackets_counter == 0: + operator_found = cls.operators2[char] + if operator_match[0] < 0 or operator_found.priority > operator_match[1].priority: + operator_match = (index,operator_found) + + if operator_match[0] >= 0: + return operator_match[1]( Parser.parse( term[:operator_match[0]] ), Parser.parse( term[operator_match[0]+1:] ) ) + + if term[0] == "(" and term[-1] == ")": + return Parser.parse(term[1:-1]) + + raise Exception("WTF is this shit %s" % term) + +class IdMark: + def __init__(self,idv,constant=False): + self.idv = idv + self.constant = constant + + def insert(self,id_dict,idv): + return id_dict[self.idv] + + def __repr__(self): + if self.constant: + return "IDC[%s]" % self.idv + else: + return "ID[%s]" % self.idv + +class DeriveVarIdMark: + def insert(self,id_dict,idv): + return Var(idv) + + def __repr__(self): + return "X[]" + +class DerivationMark: + def __init__(self,content): + self.content = content + + def insert(self,id_dict,idv): + return Deriver.derive(self.content.insert(id_dict,idv),idv) + +class DRule: + def __init__(self,pattern,skeleton): + self.pattern = pattern + self.skeleton = skeleton + + def test(self,term,idv): + queue = [(self.pattern,term)] + id_dict = {} + while len(queue) != 0: + vpattern,vterm = queue[0] + queue = queue[1:] + + if vpattern.__class__ == IdMark: + if vpattern.constant and not vterm.is_constant(idv): + return None + elif vpattern.idv in id_dict: + if id_dict[vpattern.idv] != vterm: + return None + else: + id_dict[vpattern.idv] = vterm + elif vpattern.__class__ == DeriveVarIdMark: + if not (vterm.__class__ == Var and vterm.idv == idv): + return None + elif vpattern.__class__ == vterm.__class__: + queue.append( (vpattern.left,vterm.left) ) + queue.append( (vpattern.right,vterm.right) ) + else: + return None + + return id_dict + +class Deriver: + rules = [ + DRule( #dc/dx = 0 / c const + IdMark("c",constant=True), + Numeric(0) + ), + DRule( #d/dx (a+b) = da/dx + db/dx + Addition(IdMark("x"),IdMark("y")), + Addition(DerivationMark(IdMark("x")),DerivationMark(IdMark("y"))) + ), + DRule( #d/dx (a-b) = da/dx - db/dx + Subtraction(IdMark("a"),IdMark("b")), + Subtraction(DerivationMark(IdMark("a")),DerivationMark(IdMark("b"))) + ), + DRule( #d/dx (c*a) = c * da/dx + Multiplication(IdMark("c",constant=True),IdMark("x")), + Multiplication(IdMark("c"), DerivationMark(IdMark("x")) ) + ), + DRule( #dx/dx = 1 + DeriveVarIdMark(), + Numeric(1) + ), + DRule( #d/dx (x^c) = c * x ^ (c-1) + Power( DeriveVarIdMark(), IdMark("c") ), + Multiplication( + IdMark("c"), + Power( + DeriveVarIdMark(), + Subtraction( + IdMark("c"), + Numeric(1) + ) + ) + ) + ), + DRule( #d/dx (a*b) = a * db/dx + b * da/dx + Multiplication( IdMark("a"), IdMark("b") ), + Addition( + Multiplication( + IdMark("a"), + DerivationMark( IdMark("b") ) + ), + Multiplication( + IdMark("b"), + DerivationMark( IdMark("a") ) + ) + ) + ), + DRule( #d/dx (a/b) = (da/dx * b - a * db/dx)/b^2 + Division( + IdMark("a"), + IdMark("b") + ), + Division( + Subtraction( + Multiplication( + DerivationMark( IdMark("a") ), + IdMark("b") + ), + Multiplication( + IdMark("a"), + DerivationMark( IdMark("b") ) + ) + ), + Power( + IdMark("b"), + Numeric(2) + ) + ) + ) + ] + + @classmethod + def derive(cls,term,idv): + for rule in cls.rules: + id_dict = rule.test(term,idv) + if id_dict is not None: + return rule.skeleton.insert(id_dict,idv) + + raise Exception("Couldn't derive %s" % term) + +class SRule: + def __init__(self,pattern,applier): + self.pattern = pattern + self.applier = applier + +class Simplifier: + @staticmethod + def simplify(term): + if term.is_constant(): + return term.calc() + elif isinstance(term,Operator2): + print term.__class__.__name__ + + sleft = Simplifier.simplify(term.left) + sright = Simplifier.simplify(term.right) + term = term.__class__(sleft,sright) + + if term.left.is_constant(): + tleft = term.left.calc() + else: + tleft = term.left + + if term.right.is_constant(): + tright = Simplifier.simplify(term.right.calc()) + else: + tright = term.right + + return term.__class__(tleft,tright) + else: + return term + +sterm = raw_input("Input term (deriving by x): ") + +term = Parser.parse(sterm) +print "Deriving %s" % term +dterm = Deriver.derive(term,"x") +print "DTerm: %s" % dterm +sterm = Simplifier.simplify(dterm) +print "Result: %s" % sterm + + diff --git a/fizzbuzz-oneline.py b/fizzbuzz-oneline.py index 3059f11..3e077d9 100644 --- a/fizzbuzz-oneline.py +++ b/fizzbuzz-oneline.py @@ -1 +1 @@ -print reduce(lambda x,y:x+"\n"+y, [ (((str(i),"Fizz")[i%3==0],"Buzz")[i%5==0],"FizzBuzz")[i%15==0] for i in range(1,101) ], "")[1:] \ No newline at end of file +print reduce(lambda x,y:x+"\n"+y, map(lambda i: (((str(i),"Fizz")[i%3==0],"Buzz")[i%5==0],"FizzBuzz")[i%15==0], range(1,101) ), "")[1:] \ No newline at end of file diff --git a/pso.py b/pso.py index 5da195e..6d989c2 100644 --- a/pso.py +++ b/pso.py @@ -119,16 +119,17 @@ class Swarm: def __centerOfSwarm(self): - return reduce(lambda a,b: a+b, [ p.position for p in self.particles ], Vector([0,0]) )/len(self.particles) + return reduce(lambda a,b: a+b, [ p.bestposition for p in self.particles ], Vector([0,0]) )/len(self.particles) def __swarmSize(self): center = self.__centerOfSwarm() - return max([ p.position.distance(center) for p in self.particles ]) + return max([ p.bestposition.distance(center) for p in self.particles ]) if __name__ == '__main__': swarm = Swarm( 20, ParticleCreator([(-2000.0,2000.0),(-2000.0,2000.0)]), Fitness(), 1, 0.4, 0.2 ) - iterations = swarm.runUntilSwarmSize(1) + iterations = 10000 + swarm.stepN(iterations) print "%d iterations" % iterations diff --git a/sorting_algorithms.py b/sorting_algorithms.py index 92d218f..6e558b0 100644 --- a/sorting_algorithms.py +++ b/sorting_algorithms.py @@ -1,8 +1,9 @@ from random import randint from time import clock +from sys import argv -class SortAlgorithm: +class SortAlgorithm(object): def __init__(self): self.swaps = 0 self.vgls = 0 @@ -40,7 +41,7 @@ class InsertSort(SortAlgorithm): for i in range(1,len(a)): t = a[i] j = i-1 - while j >= 0 and self.vgl(a[i] > t): + while j >= 0 and self.vgl(a[j] > t): self.set(a,j,a[j+1]) j-=1 #a[j+1] = t @@ -65,7 +66,7 @@ class QuickSort(SortAlgorithm): while i < j: while self.vgl(a[i] <= pivot) and i < right: i+=1 - while self.vgl(a[i] >= pivot) and j > left: j-=1 + while self.vgl(a[j] >= pivot) and j > left: j-=1 if i < j: self.swap(a,i,j) @@ -78,7 +79,7 @@ class QuickSort(SortAlgorithm): class HeapSort(SortAlgorithm): def sort(self,a): self.heapsort(a) - return a + return list(reversed(a)) def heapify(self, data, i, w): #indexes = filter(lambda v: v < w, [i,2*(i+1)-1,2*(i+1)]) @@ -182,18 +183,33 @@ class SortTester: print "Testing %s..." % algorithm.__name__ inst = algorithm() c = data[:] - inst.sort(c) + s = inst.sort(c) + if not SortedTest().test(s): + raise Exception(algorithm.__name__+" failed to sort") results[algorithm] = (inst.vgls,inst.swaps) return results +class SortedTest: + def test(self, a): + v = a[0] + for n in a[1:]: + if v > n: + return False + v = n + return True + def main(): - result = SortTester([BubbleSort,InsertSort,QuickSort,HeapSort,MergeSort,ShellSort,SelectSort]).test(size=1000) + try: + size = int( argv[1]) + except Exception: + size= 1000 + result = SortTester(list( SortAlgorithm.__subclasses__() )).test(size=size) for cls, r in result.items(): - print "%-12s: %d compares, %d swaps" % (cls.__name__, r[0],r[1]) + print "%-12s: %10d, %d compares, %d swaps" % (cls.__name__, r[0]+r[1], r[0],r[1]) def test(): - print ShellSort().sort([randint(0,500) for i in range(0,100)]) + print HeapSort().sort([randint(0,500) for i in range(0,100)]) if __name__ == '__main__': main()