print('Hello from Codon 2') @tuple class Vec: a: float b: float tag: str n: ClassVar[int] = 0 d: ClassVar[int] = 0 def __new__(a: float = 0.0, b: float = 0.0): v = Vec(a, b, 'v' + str(Vec.n)) Vec.n += 1 return v def foo(self, a: float = 1.11, b: float = 2.22): return (self.a, a, b) def bar(self): return self def baz(a: float = 1.11, b: float = 2.22): return (a, b) def nop(): return 'nop' @property def c(self): return self.a + self.b def __str__(self): return f'{self.tag}: <{self.a}, {self.b}>' def __repr__(self): return f'Vec({self.a}, {self.b}, {repr(self.tag)})' def __add__(self, other: Vec): return Vec(self.a + other.a, self.b + other.b, f'({self.tag}+{other.tag})') def __iadd__(self, other: Vec): a, b = self.a, self.b a += other.a b += other.b tag = f'({self.tag}+={other.tag})' return Vec(a, b, tag) def __add__(self, x: float): return Vec(self.a + x, self.b + x, f'({self.tag}+{x})') def __iadd__(self, x: float): a, b = self.a, self.b a += x b += x tag = f'({self.tag}+={x})' return Vec(a, b, tag) def __add__(self, x: int): return Vec(self.a + x, self.b + x, f'({self.tag}++{x})') def __sub__(self, other: Vec): return Vec(self.a - other.a, self.b - other.b, f'({self.tag}-{other.tag})') def __isub__(self, other: Vec): a, b = self.a, self.b a -= other.a b -= other.b tag = f'({self.tag}-={other.tag})' return Vec(a, b, tag) def __mul__(self, x: float): return Vec(self.a * x, self.b * x, f'({self.tag}*{x})') def __imul__(self, x: float): a, b = self.a, self.b a *= x b *= x tag = f'({self.tag}*={x})' return Vec(a, b, tag) def __mod__(self, x: float): return Vec(self.a % x, self.b % x, f'({self.tag}%{x})') def __imod__(self, x: float): a, b = self.a, self.b a %= x b %= x tag = f'({self.tag}%={x})' return Vec(a, b, tag) def __divmod__(self, x: float): raise ArithmeticError('no divmod') # return self.a / x, self.a % x def __pow__(self, x: float): return Vec(self.a ** x, self.b ** x, f'({self.tag}**{x})') def __ipow__(self, x: float): a, b = self.a, self.b a **= x b **= x tag = f'({self.tag}**={x})' return Vec(a, b, tag) def __neg__(self): return Vec(-self.a, -self.b, f'(-{self.tag})') def __pos__(self): return Vec(self.a, self.b, f'(+{self.tag})') def __abs__(self): import math return math.hypot(self.a, self.b) def __bool__(self): return bool(self.a) and bool(self.b) def __invert__(self): return Vec(-self.a - 1, -self.b - 1, f'(~{self.tag})') def __lshift__(self, x: int): y = 1 << x return Vec(self.a * y, self.b * y, f'({self.tag}<<{x})') def __ilshift__(self, x: int): a, b = self.a, self.b y = 1 << x a *= y b *= y tag = f'({self.tag}<<={x})' return Vec(a, b, tag) def __rshift__(self, x: int): y = 1 << x return Vec(self.a / y, self.b / y, f'({self.tag}>>{x})') def __irshift__(self, x: int): a, b = self.a, self.b y = 1 << x a /= y b /= y tag = f'({self.tag}>>={x})' return Vec(a, b, tag) def __and__(self, x: int): return Vec(int(self.a) & x, int(self.b) & x, f'({self.tag}&{x})') def __iand__(self, x: int): a, b = self.a, self.b a = int(self.a) & x b = int(self.b) & x tag = f'({self.tag}&={x})' return Vec(a, b, tag) def __or__(self, x: int): return Vec(int(self.a) | x, int(self.b) | x, f'({self.tag}|{x})') def __ior__(self, x: int): a, b = self.a, self.b a = int(self.a) | x b = int(self.b) | x tag = f'({self.tag}|={x})' return Vec(a, b, tag) def __xor__(self, x: int): return Vec(int(self.a) ^ x, int(self.b) ^ x, f'({self.tag}^{x})') def __ixor__(self, x: int): a, b = self.a, self.b a = int(self.a) ^ x b = int(self.b) ^ x tag = f'({self.tag}^={x})' return Vec(a, b, tag) #def __int__(self): # return int(self.b) #def __float__(self): # return self.b #def __index__(self): # return int(self.a) def __floordiv__(self, x: float): return Vec(self.a // x, self.b // x, f'({self.tag}//{x})') def __ifloordiv__(self, x: float): a, b = self.a, self.b a //= x b //= x tag = f'({self.tag}//={x})' return Vec(a, b, tag) def __truediv__(self, x: float): return Vec(self.a / x, self.b / x, f'({self.tag}/{x})') def __itruediv__(self, x: float): a, b = self.a, self.b a /= x b /= x tag = f'({self.tag}/={x})' return Vec(a, b, tag) def __matmul__(self, other: Vec): return (self.a * other.a) + (self.b * other.b) def __imatmul__(self, x: float): a, b = self.a, self.b a *= x b *= x tag = f'({self.tag}@={x})' return Vec(a, b, tag) def __len__(self): return len(self.tag) def __getitem__(self, idx: int): if idx == 0: return self.a elif idx == 1: return self.b elif idx == 11: return self.a + self.b else: raise KeyError('bad vec key ' + str(idx)) def __contains__(self, val: float): return self.a == val or self.b == val def __contains__(self, val: str): return self.tag == val def __hash__(self): return int(self.a + self.b) def __call__(self, a: float = 1.11, b: float = 2.22): return self.foo(a=a, b=b) def __call__(self, x: str): return (self.a, self.b, x) def __call__(self): return Vec(self.a, self.b, f'({self.tag}())') def __iter__(self): for c in self.tag: yield c def __eq__(self, other: Vec): return self.a == other.a and self.b == other.b def __eq__(self, x: float): return self.a == x and self.b == x def __ne__(self, other: Vec): return self.a != other.a or self.b != other.b def __lt__(self, other: Vec): return abs(self) < abs(other) def __le__(self, other: Vec): return abs(self) <= abs(other) def __gt__(self, other: Vec): return abs(self) > abs(other) def __ge__(self, other: Vec): return abs(self) >= abs(other) def __del__(self): Vec.d += 1 def nd(): return Vec.d def reset(): Vec.n = 0 def par_sum(n: int): m = 0 @par(num_threads=4) for i in range(n): m += 3*i + 7 return m