from collections import namedtuple
from functools import partial
from itertools import starmap
import operator
class Vector:
def _lift_un(self, op):
"""apply unary operator"""
return map(op, self)
def _lift_bi(self, op, v):
"""apply binary operator"""
return starmap(op, zip(self, v))
def __mul__(self, s):
return type(self)(*self._lift_un(partial(operator.mul, s)))
__rmul__ = __mul__
def __neg__(self):
return type(self)(*self._lift_un(operator.neg))
def __pos__(self):
return type(self)(*self._lift_un(operator.pos))
def __abs__(self):
return sum(self._lift_un(lambda x: x**2))**.5
def __add__(self, v):
return type(self)(*self._lift_bi(operator.add, v))
__radd__ = __add__
def __sub__(self, v):
return type(self)(*self._lift_bi(operator.sub, v))
def __eq__(self, v):
return all(self._lift_bi(operator.eq, v))
def __ne__(self, v):
return any(self._lift_bi(operator.ne, v))
def __repr__(self):
return '%s(%s)' % (type(self).__name__,
', '.join(self._lift_un(repr)))
class Vector3(Vector, namedtuple('_Vector3', 'x y z')):
pass
vector = Vector3(0, 0, 0)
print vector
print vector + Vector3(1,1,1)
print vector * 5
print abs(vector)
print (vector - Vector3(1,2,3)) * 2 == Vector3(-2,-4,-6)
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgbmFtZWR0dXBsZQpmcm9tIGZ1bmN0b29scyBpbXBvcnQgcGFydGlhbApmcm9tIGl0ZXJ0b29scyBpbXBvcnQgc3Rhcm1hcAppbXBvcnQgb3BlcmF0b3IKCmNsYXNzIFZlY3RvcjoKCWRlZiBfbGlmdF91bihzZWxmLCBvcCk6CgkJIiIiYXBwbHkgdW5hcnkgb3BlcmF0b3IiIiIKCQlyZXR1cm4gbWFwKG9wLCBzZWxmKQoJCglkZWYgX2xpZnRfYmkoc2VsZiwgb3AsIHYpOgoJCSIiImFwcGx5IGJpbmFyeSBvcGVyYXRvciIiIgoJCXJldHVybiBzdGFybWFwKG9wLCB6aXAoc2VsZiwgdikpCgkKCWRlZiBfX211bF9fKHNlbGYsIHMpOgoJCXJldHVybiB0eXBlKHNlbGYpKCpzZWxmLl9saWZ0X3VuKHBhcnRpYWwob3BlcmF0b3IubXVsLCBzKSkpCgkKCV9fcm11bF9fID0gX19tdWxfXwoJCglkZWYgX19uZWdfXyhzZWxmKToKCQlyZXR1cm4gdHlwZShzZWxmKSgqc2VsZi5fbGlmdF91bihvcGVyYXRvci5uZWcpKQoJCglkZWYgX19wb3NfXyhzZWxmKToKCQlyZXR1cm4gdHlwZShzZWxmKSgqc2VsZi5fbGlmdF91bihvcGVyYXRvci5wb3MpKQoJCglkZWYgX19hYnNfXyhzZWxmKToKCQlyZXR1cm4gc3VtKHNlbGYuX2xpZnRfdW4obGFtYmRhIHg6IHgqKjIpKSoqLjUKCQoJZGVmIF9fYWRkX18oc2VsZiwgdik6CgkJcmV0dXJuIHR5cGUoc2VsZikoKnNlbGYuX2xpZnRfYmkob3BlcmF0b3IuYWRkLCB2KSkKCQoJX19yYWRkX18gPSBfX2FkZF9fCgkKCWRlZiBfX3N1Yl9fKHNlbGYsIHYpOgoJCXJldHVybiB0eXBlKHNlbGYpKCpzZWxmLl9saWZ0X2JpKG9wZXJhdG9yLnN1YiwgdikpCgkKCWRlZiBfX2VxX18oc2VsZiwgdik6CgkJcmV0dXJuIGFsbChzZWxmLl9saWZ0X2JpKG9wZXJhdG9yLmVxLCB2KSkKCQoJZGVmIF9fbmVfXyhzZWxmLCB2KToKCQlyZXR1cm4gYW55KHNlbGYuX2xpZnRfYmkob3BlcmF0b3IubmUsIHYpKQoJCglkZWYgX19yZXByX18oc2VsZik6CgkJcmV0dXJuICclcyglcyknICUgKHR5cGUoc2VsZikuX19uYW1lX18sCgkJCQkJCSAgICcsICcuam9pbihzZWxmLl9saWZ0X3VuKHJlcHIpKSkKCmNsYXNzIFZlY3RvcjMoVmVjdG9yLCBuYW1lZHR1cGxlKCdfVmVjdG9yMycsICd4IHkgeicpKToKCXBhc3MKCQp2ZWN0b3IgPSBWZWN0b3IzKDAsIDAsIDApCgpwcmludCB2ZWN0b3IKcHJpbnQgdmVjdG9yICsgVmVjdG9yMygxLDEsMSkKcHJpbnQgdmVjdG9yICogNQpwcmludCBhYnModmVjdG9yKQpwcmludCAodmVjdG9yIC0gVmVjdG9yMygxLDIsMykpICogMiA9PSBWZWN0b3IzKC0yLC00LC02KQ==