| f | import unicodedata | f | import unicodedata |
| import asyncio | | import asyncio |
| | | |
| class YesFuture: | | class YesFuture: |
| | | |
| def __init__(self, value=None): | | def __init__(self, value=None): |
| self._value = value | | self._value = value |
| | | |
| def set(self, value): | | def set(self, value): |
| self._value = value | | self._value = value |
| | | |
| def __await__(self): | | def __await__(self): |
| | | |
| async def _inner(): | | async def _inner(): |
| return self._value | | return self._value |
| return _inner().__await__() | | return _inner().__await__() |
| | | |
| n | async def Sum(x, y): | n | async def Sum(a, b): |
| return await x + await y | | return await a + await b |
| | | |
| n | async def Mul(x, y): | n | async def Mul(a, b): |
| return await x * await y | | return await a * await b |
| | | |
| n | async def Pow(x, y): | n | async def Pow(a, b): |
| return await x ** await y | | return await a ** await b |
| | | |
| n | def _parse_superscript(exp): | n | def _parse_superscript(exp_str): |
| | | """exp_str: строка из символов-суперцифр '⁰¹²³⁴⁵⁶⁷⁸⁹'.""" |
| m = 0 | | n = 0 |
| for c in exp: | | for ch in exp_str: |
| m = m * 10 + unicodedata.digit(c) | | n = n * 10 + unicodedata.digit(ch) |
| return m | | return n |
| | | |
| n | def parse_poly(str, yesFuture): | n | def parse_poly(poly, x_future): |
| | | """ |
| | | poly: строка с многочленом (например, '3x⁵ + x² - 6x + 4') |
| | | x_future: объект YesFuture |
| | | Возвращает корутину, вычисляющую значение многочлена при текущем x_f |
| | | uture. |
| | | """ |
| text = str.replace(' ', '') | | s = poly.replace(' ', '') |
| pos = 0 | | i = 0 |
| items = [] | | terms = [] |
| polar = [] | | signs = [] |
| | | |
| n | def read_num(src, idx): | n | def parse_int(s, i): |
| beg = idx | | """Возвращает (число или None, новая_позиция).""" |
| | | start = i |
| while idx < len(src) and src[idx].isdigit(): | | while i < len(s) and s[i].isdigit(): |
| idx += 1 | | i += 1 |
| if beg == idx: | | if start == i: |
| return (None, idx) | | return (None, i) |
| return (int(src[beg:idx]), idx) | | return (int(s[start:i]), i) |
| while pos < len(text): | | while i < len(s): |
| flag = 1 | | sign = 1 |
| if text[pos] == '+': | | if s[i] == '+': |
| pos += 1 | | i += 1 |
| elif text[pos] == '-': | | elif s[i] == '-': |
| flag = -1 | | sign = -1 |
| pos += 1 | | i += 1 |
| coef, nxt = read_num(text, pos) | | coeff, i_new = parse_int(s, i) |
| if coef is None: | | if coeff is None: |
| coef = 1 | | coeff = 1 |
| pos = nxt | | i = i_new |
| mark_x = False | | has_x = False |
| if pos < len(text) and text[pos] == 'x': | | if i < len(s) and s[i] == 'x': |
| mark_x = True | | has_x = True |
| pos += 1 | | i += 1 |
| degree = 1 if mark_x else 0 | | power = 1 if has_x else 0 |
| if mark_x and pos < len(text): | | if has_x and i < len(s): |
| beg = pos | | start = i |
| while pos < len(text): | | while i < len(s): |
| char = text[pos] | | ch = s[i] |
| try: | | try: |
| n | unicodedata.digit(char) | n | unicodedata.digit(ch) |
| pos += 1 | | i += 1 |
| except (TypeError, ValueError): | | except (TypeError, ValueError): |
| break | | break |
| n | if pos > beg: | n | if i > start: |
| degree = _parse_superscript(text[beg:pos]) | | power = _parse_superscript(s[start:i]) |
| | | |
| n | async def fixed(val): | n | async def const_term(val): |
| return val | | return val |
| n | if not mark_x: | n | if not has_x: |
| term_obj = fixed(coef) | | term = const_term(coeff) |
| else: | | else: |
| | | |
| n | async def raise_pow(x_val, e_val): | n | async def make_pow(xf, p): |
| | | |
| n | async def e_future(): | n | async def p_future(): |
| return e_val | | return p |
| return await Pow(x_val, e_future()) | | return await Pow(xf, p_future()) |
| exponent_part = raise_pow(yesFuture, degree) | | pow_part = make_pow(x_future, power) |
| if coef == 1: | | if coeff == 1: |
| term_obj = exponent_part | | term = pow_part |
| else: | | else: |
| | | |
| n | async def scale(v, inner): | n | async def make_coeff_mul(c, inner): |
| | | |
| n | async def v_future(): | n | async def c_future(): |
| return v | | return c |
| return await Mul(v_future(), inner) | | return await Mul(c_future(), inner) |
| term_obj = scale(coef, exponent_part) | | term = make_coeff_mul(coeff, pow_part) |
| items.append(term_obj) | | terms.append(term) |
| polar.append(flag) | | signs.append(sign) |
| | | |
| n | async def compute_poly(): | n | async def eval_poly(): |
| | | |
| n | async def zero_val(): | n | async def const_zero(): |
| return 0 | | return 0 |
| n | accum = zero_val() | n | result = const_zero() |
| for sg, piece in zip(polar, items): | | for sign, term in zip(signs, terms): |
| if sg == 1: | | if sign == 1: |
| accum = Sum(accum, piece) | | result = Sum(result, term) |
| else: | | else: |
| | | |
| n | async def neg_one(): | n | async def minus_one(): |
| return -1 | | return -1 |
| t | inv = Mul(neg_one(), piece) | t | neg_term = Mul(minus_one(), term) |
| accum = Sum(accum, inv) | | result = Sum(result, neg_term) |
| return await accum | | return await result |
| return compute_poly() | | return eval_poly() |