cp-library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub kobejean/cp-library

:warning: cp_library/math/linalg/vec/mutvec_cls.py

Depends on

Code

import cp_library.__header__
from typing import Iterable
from cp_library.io.parsable_cls import Parsable
import cp_library.math.__header__
import cp_library.math.linalg.__header__
import cp_library.math.linalg.mat.__header__
import cp_library.math.linalg.vec.__header__
from cp_library.math.linalg.elm_wise_in_place_mixin import ElmWiseInPlaceMixin

class MutVec(list, ElmWiseInPlaceMixin, Parsable):
    def __init__(self, *args):
        super().__init__(args[0] if len(args) == 1 and isinstance(args[0], Iterable) else args)
    @classmethod
    def compile(cls, T: type = int, N = None):
        elm = Parser.compile(T)
        if N is None:
            def parse(io: IOBase): return cls(elm(io) for _ in io.wait())
        else:
            def parse(io: IOBase):  return cls(elm(io) for _ in range(N))
        return parse
from cp_library.io.io_base_cls import IOBase
from cp_library.io.parser_cls import Parser
'''
╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸
             https://kobejean.github.io/cp-library               
'''
from typing import Iterable
from types import GenericAlias


class Parsable:
    @classmethod
    def compile(cls):
        def parser(io: 'IOBase'): return cls(next(io))
        return parser
    @classmethod
    def __class_getitem__(cls, item): return GenericAlias(cls, item)




import operator
from numbers import Number
from typing import Sequence
from math import hypot

class ElmWiseMixin:
    def elm_wise(self, other, op):
        if isinstance(other, Sequence):
            return self.__class__(op(self[i], y) for i, y in enumerate(self, other))
        if isinstance(other, Number):
            return self.__class__(op(x, other) for x in self)
        raise ValueError("Operand must be a number or a tuple of the same length")

    def __add__(self, other): return self.elm_wise(other, operator.add)
    def __radd__(self, other): return self.elm_wise(other, operator.add)
    def __sub__(self, other): return self.elm_wise(other, operator.sub)
    def __rsub__(self, other): return self.elm_wise(other, lambda x,y: operator.sub(y,x))
    def __mul__(self, other): return self.elm_wise(other, operator.mul)
    def __rmul__(self, other): return self.elm_wise(other, operator.mul)
    def __truediv__(self, other): return self.elm_wise(other, operator.truediv)
    def __rtruediv__(self, other): return self.elm_wise(other, lambda x,y: operator.truediv(y,x))
    def __floordiv__(self, other): return self.elm_wise(other, operator.floordiv)
    def __rfloordiv__(self, other): return self.elm_wise(other, lambda x,y: operator.floordiv(y,x))
    def __mod__(self, other): return self.elm_wise(other, operator.mod)

    def distance(self: 'ElmWiseMixin', other: 'ElmWiseMixin'):
        diff = other-self
        return hypot(*diff)
    
    def magnitude(vec: 'ElmWiseMixin'):
        return hypot(*vec)
    
    def norm(vec: 'ElmWiseMixin'):
        return vec / vec.magnitude()

class ElmWiseInPlaceMixin(ElmWiseMixin):
    def ielm_wise(self, other, op):
        if isinstance(other, Number):
            for i in range(len(self)):
                self[i] = op(self[i], other)
        elif isinstance(other, Sequence) and len(self) == len(other):
            for i in range(len(self)):
                self[i] = op(self[i], other[i])
        else:
            raise ValueError("Operand must be a number or a list of the same length")
        return self
    
    def __iadd__(self, other): return self.ielm_wise(other, operator.add)
    def __isub__(self, other): return self.ielm_wise(other, operator.sub)
    def __imul__(self, other): return self.ielm_wise(other, operator.mul)
    def __itruediv__(self, other): return self.ielm_wise(other, operator.truediv)
    def __ifloordiv__(self, other): return self.ielm_wise(other, operator.floordiv)
    def __imod__(self, other): return self.ielm_wise(other, operator.mod)

class MutVec(list, ElmWiseInPlaceMixin, Parsable):
    def __init__(self, *args):
        super().__init__(args[0] if len(args) == 1 and isinstance(args[0], Iterable) else args)
    @classmethod
    def compile(cls, T: type = int, N = None):
        elm = Parser.compile(T)
        if N is None:
            def parse(io: IOBase): return cls(elm(io) for _ in io.wait())
        else:
            def parse(io: IOBase):  return cls(elm(io) for _ in range(N))
        return parse

class IOBase:
    @property
    def char(io) -> bool: ...
    @property
    def writable(io) -> bool: ...
    def __next__(io) -> str: ...
    def write(io, s: str) -> None: ...
    def readline(io) -> str: ...
    def readtoken(io) -> str: ...
    def readtokens(io) -> list[str]: ...
    def readints(io) -> list[int]: ...
    def readdigits(io) -> list[int]: ...
    def readnums(io) -> list[int]: ...
    def readchar(io) -> str: ...
    def readchars(io) -> str: ...
    def readinto(io, lst: list[str]) -> list[str]: ...
    def readcharsinto(io, lst: list[str]) -> list[str]: ...
    def readtokensinto(io, lst: list[str]) -> list[str]: ...
    def readintsinto(io, lst: list[int]) -> list[int]: ...
    def readdigitsinto(io, lst: list[int]) -> list[int]: ...
    def readnumsinto(io, lst: list[int]) -> list[int]: ...
    def wait(io): ...
    def flush(io) -> None: ...
    def line(io) -> list[str]: ...
import typing
from typing import Callable, Collection

class Parser:
    def __init__(self, spec):  self.parse = Parser.compile(spec)
    def __call__(self, io: IOBase): return self.parse(io)
    @staticmethod
    def compile_type(cls, args = ()):
        if issubclass(cls, Parsable): return cls.compile(*args)
        elif issubclass(cls, (Number, str)):
            def parse(io: IOBase): return cls(next(io))              
            return parse
        elif issubclass(cls, tuple): return Parser.compile_tuple(cls, args)
        elif issubclass(cls, Collection): return Parser.compile_collection(cls, args)
        elif callable(cls):
            def parse(io: IOBase): return cls(next(io))              
            return parse
        else: raise NotImplementedError()
    @staticmethod
    def compile(spec=int):
        if isinstance(spec, (type, GenericAlias)):
            cls, args = typing.get_origin(spec) or spec, typing.get_args(spec) or tuple()
            return Parser.compile_type(cls, args)
        elif isinstance(offset := spec, Number): 
            cls = type(spec)  
            def parse(io: IOBase): return cls(next(io)) + offset
            return parse
        elif isinstance(args := spec, tuple): return Parser.compile_tuple(type(spec), args)
        elif isinstance(args := spec, Collection): return Parser.compile_collection(type(spec), args)
        elif isinstance(fn := spec, Callable): 
            def parse(io: IOBase): return fn(next(io))
            return parse
        else: raise NotImplementedError()
    @staticmethod
    def compile_line(cls, spec=int):
        if spec is int:
            def parse(io: IOBase): return cls(io.readnums())
        elif spec is str:
            def parse(io: IOBase): return cls(io.line())
        else:
            fn = Parser.compile(spec)
            def parse(io: IOBase): return cls((fn(io) for _ in io.wait()))
        return parse
    @staticmethod
    def compile_repeat(cls, spec, N):
        fn = Parser.compile(spec)
        def parse(io: IOBase): return cls([fn(io) for _ in range(N)])
        return parse
    @staticmethod
    def compile_children(cls, specs):
        fns = tuple((Parser.compile(spec) for spec in specs))
        def parse(io: IOBase): return cls([fn(io) for fn in fns])  
        return parse
    @staticmethod
    def compile_tuple(cls, specs):
        if isinstance(specs, (tuple,list)) and len(specs) == 2 and specs[1] is ...: return Parser.compile_line(cls, specs[0])
        else: return Parser.compile_children(cls, specs)
    @staticmethod
    def compile_collection(cls, specs):
        if not specs or len(specs) == 1 or isinstance(specs, set):
            return Parser.compile_line(cls, *specs)
        elif (isinstance(specs, (tuple,list)) and len(specs) == 2 and isinstance(specs[1], int)):
            return Parser.compile_repeat(cls, specs[0], specs[1])
        else:
            raise NotImplementedError()
Back to top page