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