1. Куча / Говнокод #19350

    +1

    1. 001
    2. 002
    3. 003
    4. 004
    5. 005
    6. 006
    7. 007
    8. 008
    9. 009
    10. 010
    11. 011
    12. 012
    13. 013
    14. 014
    15. 015
    16. 016
    17. 017
    18. 018
    19. 019
    20. 020
    21. 021
    22. 022
    23. 023
    24. 024
    25. 025
    26. 026
    27. 027
    28. 028
    29. 029
    30. 030
    31. 031
    32. 032
    33. 033
    34. 034
    35. 035
    36. 036
    37. 037
    38. 038
    39. 039
    40. 040
    41. 041
    42. 042
    43. 043
    44. 044
    45. 045
    46. 046
    47. 047
    48. 048
    49. 049
    50. 050
    51. 051
    52. 052
    53. 053
    54. 054
    55. 055
    56. 056
    57. 057
    58. 058
    59. 059
    60. 060
    61. 061
    62. 062
    63. 063
    64. 064
    65. 065
    66. 066
    67. 067
    68. 068
    69. 069
    70. 070
    71. 071
    72. 072
    73. 073
    74. 074
    75. 075
    76. 076
    77. 077
    78. 078
    79. 079
    80. 080
    81. 081
    82. 082
    83. 083
    84. 084
    85. 085
    86. 086
    87. 087
    88. 088
    89. 089
    90. 090
    91. 091
    92. 092
    93. 093
    94. 094
    95. 095
    96. 096
    97. 097
    98. 098
    99. 099
    100. 100
    -- Few Scum
    import Data.Char
    import Text.Read
    import Control.Applicative
    import Data.Ratio
    import Numeric
    import Data.List
    import Data.Maybe
    data Token
        =TLetter Char
        |TNumf Rational
        |TOp Char
        |LBrace
        |RBrace
        deriving (Show, Eq)
    data Expr
        =Letter Char
        |Numf Rational
        |Op Char Expr Expr
        |Diff Expr
    instance Show Expr where
        show (Letter c)     = [c]
        show (Op c el er)   = '(' : show el ++ ')' :
            c : '(' : show er ++ ")"
        show (Numf v)       = show $ toDouble v
        show (Diff e)       = '(' : show e ++ ")'"
    
    toDouble r = fromRational r :: Double
    readUnsignedRationalMaybe f = getParseResult $ parseValue f where
        parseValue f = {- readSigned -} readFloat f :: [(Rational, String)]
        getParseResult [(value, "")] = Just value
        getParseResult _ = Nothing
    
    -- Разбиваем строку на элементы, возаращает перевернутый список токенов
    tokenize ""                     = Nothing
    tokenize sourceExpressionString = tok [] sourceExpressionString where
        tok [] (c:s)
            | c == '-'                  = tok [TOp '-', TNumf 0] s
        tok r@(LBrace:_) (c:s)
            | c == '-'                  = tok (TOp '-':TNumf 0:r) s
        tok r (c:s)
            | c == '('                  = tok (LBrace:r) s
            | c == ')'                  = tok (RBrace:r) s
            | isLetter c                = tok (TLetter c:r) s
            | isOperation c             = tok (TOp c:r) s
            | isNumber c                = parseNumf r (c:s)
        tok r ""                        = Just r
        tok resultParsedTokens sourceExpressionString = Nothing
        isOperation     = (`elem` "+-*/")
        isNumf c        = isNumber c || c == '.'
        parseNumf r s   = maybeNumber >>= makeResult where
            (numberString, tail) = span isNumf s
            maybeNumber = readUnsignedRationalMaybe numberString--readMaybe numberString
            makeResult number = tok (TNumf number:r) tail
    
    -- Дерево выражений из списка токенов
    parse reversedTokens             = reversedTokens >>= makeTree where
        priorityOps         = ["+-","/*"]
        subExpr             = splitIntoOperationAndSubExpressions
        splitIntoOperationAndSubExpressions reversedTokens =
            id =<< find isJust (map (findOp reversedTokens [] 0) priorityOps)
        findOp (LBrace:_) _ 0 _         = Nothing -- dont checked on left expression, probably can safety removed
        findOp (RBrace:l) r b ops       = findOp l (RBrace:r) (b+1) ops
        findOp (LBrace:l) r b ops       = findOp l (LBrace:r) (b-1) ops
        findOp (TOp c:l) r 0 ops
            | c `elem` ops              = Just (c, l, reverse r)
            | otherwise                 = findOp l (TOp c:r) 0 ops
        findOp leftSubExpression [] b operationsForFind
            | b > 0                     = Nothing
        findOp (c:l) r b ops            = findOp l (c:r) b ops
        findOp [] rightSubExpression braceAmount operationsForFind = Nothing
        makeTree reversedTokens     = mt reversedTokens $ subExpr reversedTokens
        mt t@(RBrace:tt) Nothing
            | last t == LBrace      = mt (init tt) $ subExpr (init tt)
        mt [TLetter v] Nothing      = Just $ Letter v
        mt [TNumf v] Nothing        = Just $ Numf v
        mt _ Nothing                = Nothing
        mt _ (Just (o, l, r))       = makeOperationExpression leftExpressionTree rightExpressionTree o where
            leftExpressionTree          = mt l $ subExpr l
            rightExpressionTree         = mt r $ subExpr r
            makeOperationExpression = moe
            moe Nothing _ _         = Nothing
            moe _ Nothing _         = Nothing
            moe (Just leftExpressionTree) (Just rightExpressionTree) operation = Just $ Op operation leftExpressionTree rightExpressionTree
    
    -- Простейшее упрощение выражений
    firstSimplify e     = simplifyTreeHeightTimes <$> e where
        stepSimplify = fs
        fs (Op '*' e (Numf 1))           = e
        fs (Op '*' (Numf 1) e)           = e
        fs (Op '+' e (Numf 0))           = e
        fs (Op '+' (Numf 0) e)           = e
        fs (Op '/' e (Numf 1))           = e
        fs (Op '-' e (Numf 0))           = e
        fs (Op '*' (Numf 0) _)           = Numf 0
        fs (Op '*' _ (Numf 0))           = Numf 0
        fs (Op '/' (Numf 0) _)           = Numf 0
        fs (Op '/' (Letter l) (Letter r))
            | l == r                     = Numf 1
        fs (Op '-' (Letter l) (Letter r))

    Новая Специальная Олимпиада объявляется открытой.

    https://ideone.com/Bottp0

    Реализовать поиск производной по выражению на любом языке. У кого получится компактнее, правильнее и больше функционала, тот и победил. Заявлять кандидата в победители (код и его автора) можно несколько раз если код улучшил или написал на другом языке. Призов, кроме почета и приятного времяпрепровождения, - не будет

    Если кто-то что-нибудь поломает, то я буду очень рад.

    Пока упрощение не работает на полную катушку и из функций производных только +-*/

    Мой друг обещает ещё версию на крестах подогнать.

    Запостил: laMer007, 26 Января 2016

    Комментарии (79) RSS

    • | l == r                     = Numf 0
          fs (Op o (Numf l) (Numf r))
              | o == '+'                   = Numf $ l + r
              | o == '-'                   = Numf $ l - r
              | o == '*'                   = Numf $ l * r
              | o == '/'                   = Numf $ l / r
          fs (Op o l r)                    = Op o (fs l) (fs r)
          fs (Diff e)                      = fs e
          fs e                             = e
          treeHeight (Letter _)     = 1
          treeHeight (Op _ l r)     = max (treeHeight l) (treeHeight r) + 1
          treeHeight (Numf _)       = 1
          treeHeight (Diff e)       = treeHeight e + 1
          simplifyTreeHeightTimes e = (last . take (1 + treeHeight e) . iterate stepSimplify) e
      
      -- Производная df/dx из дерева выражений
      diff e dx           = df <$> e where
          df (Numf _)                      = Numf 0
          df (Letter c)
              | c == dx                    = Numf 1
              | otherwise                  = Numf 0
          df (Op o l r)
              | o == '+' || o == '-'       = Op o (df l) (df r)
              | o == '*'                   = Op '+' (Op '*' (df l) r) (Op '*' l (df r))
              | o == '/'                   =
                      Op '/' (Op '-' (Op '*' (df l) r) (Op '*' l (df r))) (Op '*' r r)
          df e                             = Diff e
      
      -- Очень грязный кот (:
      main = do
          let sourceExpression = "-13.5*(x*(-13))"
          let dx = 'x'
          print "dx: "
          print dx
          print "SourceExpression: "
          print sourceExpression
          let tokens = tokenize sourceExpression
          print "Source tokens: "
          print $ reverse <$> tokens
          print "Reversed source tokens: "
          print tokens
          let expr = parse tokens
          print "Source expression tree: "
          print expr
          let fsexpr = firstSimplify expr
          print "Simplified source expression tree: "
          print fsexpr
          let df = diff fsexpr dx
          print "Diff expression tree: "
          print df
          let fsdf = firstSimplify df
          print "Simplied diff expression tree: "
          print fsdf
      Ответить
    • > версию на крестах
      Походу, надо пожелать ему удачи. У меня строк на 1000+ подобный парсер для лаб был... Правда там можно было регать новые операторы, не трогая основной код.
      Ответить
      • P.S.Вывод без лишних скобок сделай. Просто же, если приоритеты операторов известны.
        Ответить
        • Мой друг на крестах еще хочет реализовать взятие производной степенной функции a^b (a в степени b).
          И более качественное упрощение выражений.

          Но что-то мне подсказывает, что он так может ничего и не выдать, если не остепенится и не выкатит первую версию с минимальным механизмом упрощения выражений и с минимумом операций.

          А насчет лишних скобок: Это можно реализовать не передавай дополнительные параметры между функциями? Ибо хочется через стандартную виртуальную функцию show делать, но ты прав, это уже ребячество. Можно и отдельную функцию завести для вывода, а потом вызывать ее из show
          Ответить
          • > хочет реализовать взятие производной степенной функции
            А что там сложного? Просто мусорных нод много генерится, но для простых случаев (типа x^5 или 3^x) они потом отлично съедаются упрощением.

            > не передавай дополнительные параметры между функциям
            Да можно, но один фиг придётся подглядывать в дочерние или родительские узлы.
            Ответить
            • > они потом отлично съедаются упрощением.
              Я не считаю, что упрощение достаточно тривиальная задача. Иной раз сродни общета ходов в шахматах. Иной раз надо аст разростить, чтобы оно в итоге все посокрощалось. У меня так firstSimplify пока весьма туп и недотягивает даже до школьника с логарифмической линейкой.

              > А что там сложного?
              Ну я так вспомнить сходу формулу общего вида для степенных функций не могу. Там экспоненты были и простые степенные функции типа квадратов, кубов и более высоких порядков.
              Конечно я пока таблицу не гуглил и может там что-то подобное было, но без гуглежки не вспомню как найти производную f(x)^g(x). Там небось еще и логарифмы всякие появятся.
              Ответить
              • > но без гуглежки не вспомню как найти производную f(x)^g(x)

                Там будет два слагаемых. В первом предполагаем, что f(x) = const, во втором — что g(x) = const.

                А вообще f(x)^g(x) = exp(g(x) * ln(f(x))) [с некоторыми ограничениями на область значений f(x)],
                поэтому (f(x)^g(x))' = exp(g(x) * ln(f(x))) * [g(x) * ln(f(x))]' =
                = exp(g(x) * ln(f(x))) * [g'(x) * ln(f(x)) + g(x) * f'(x) / f(x)] =
                = f(x) ^ g(x) * [g'(x) * ln(f(x)) + g(x) * f'(x) / f(x)] =
                = f(x) ^ g(x) * ln(f(x)) * g'(x) + g(x) * f(x) ^ (g(x) - 1) * f'(x)
                Что совпадает с тем, что бы мы получили, если бы предположили, что там будет два слагаемых: в первом предполагаем, что f(x) = const, во втором — что g(x) = const.
                Ответить
                • Ок, вы меня обнадежили, пока читать не буду. Сначала сам подумаю. Надеюсь там формула общего вида для производной сложных степенных функций
                  Ответить
                • Ты уверен? Мне кажется что это не общая формула, а частная.
                  Ответить
      • У меня по-моему, строк 50 занимала функция вшивания нового токена в АСТ-дерево, была библиотека функций и операторов со своими приоритетами.
        Ответить
        • Ну на самом деле, я считаю, у меня коротко получилось за счет того, что парсинг не поддерживает произвольные операторы. То есть система не гибкая. Можно добавлять только односимвольные бинарные операторы без переделки парсера
          Ответить
          • > произвольные операторы
            У меня самая жопа была из-за разной ассоциативности - АСТ почти перебором строилось, чтобы ловить все неоднозначности и ругаться на них. Зато парсило даже говно, в котором операторы поналеплены без пробелов, типа a--b => a - (-b).
            Ответить
            • Грамматики твой парсер поддерживал?
              Ответить
              • Неа. Только префиксные, постфиксные и инфиксные операторы, функции, числа и переменные.
                Ответить
          • У меня похуй скольки-символьные, потому что функция взятия токена она отдельно. И она всё равно через префиксное дерево работает, можно динамически добавлять токены.
            Ответить
            • Зачем 50 строк на вшивание токенов, если делается за пару строк? И вообще зачем вшивать токены?
              Ответить
    • у кого компактнее?
      >>> from __future__ import division
      >>> from sympy import *
      >>> x, y, z, t = symbols('x y z t')
      >>> k, m, n = symbols('k m n', integer=True)
      >>> f, g, h = symbols('f g h', cls=Function)
      
      >>> from sympy.mpmath import *
      >>> mp.dps = 15; mp.pretty = True
      >>> diff(lambda x: x**2 + x, 1.0)
      3.0
      
      >>> diff(lambda x: x**2 + x, 1.0, 2)
      2.0
      
      >>> diff(lambda x: x**2 + x, 1.0, 3)
      0.0
      Ответить
      • Какой язык? И да, матпакеты как-то не честно, тут производная уже реализована за тебя, а в задаче стояло, что ты реализуешь сам.
        Ответить
        • питон же. да я и не претендую на победителя. просто решил показать, что есть удобный sympy
          Ответить
          • Ну это круто для питона кстати, а сможешь скомпилировать свой код в любом онлайн компиляторе?
            Ответить
          • Мне на самом деле интересно, как питон парсит свои же лямбдафункции, чтоб потом взять от него производную.
            Ответить
            • http://docs.sympy.org/dev/modules/mpmath/calculus/differentiation.html
              mpmath.diff(ctx, f, x, n=1, **options)

              Numerically computes the derivative of f, f′(x), or generally for an integer n≥0, the n-th derivative f(n)(x).

              Печаль, я уж подумал, что действительно как-то хитро парсит, и можно так многие функции аналитически продифференцировать.
              Ответить
              • https://jsfiddle.net/0Le5vr5y/
                Чёрт, я не спал, не пил, не ел, писал код. laMer007, демон-искуситель, зачем?
                На полноценное участие в специальной олимпиаде не претендую, т.к. обычно многословен в коде и жизни, а также лень запиливать все фичи. Просто демонстрация решения.
                Работает для функции с явно указанным списком аргументов. Если тело функции просто возвращает выражение с переменными, целыми числами, круглыми скобками и бинарными операторами *+-/, возвращается функция, вычисляющая аналитическую производную (выражение по своему желанию оптимизирует жс-движок). Иначе - функция, которая численно.
                Использование: diff(жс-функция, строка с переменной или номер аргумента, дельта аргумента для численного вычисления)
                Возвращает жс-функцию или бросает исключение.
                Ответить
                • Выглядит очень кратко для такого функционала, даже не верится. Может даже короче хаски получилось.
                  Всегда приклонялся перед людьми, пищущими парсер на каких-то регулярках. Как это возможно? Но имхо поддерживать код будет не просто. Хотя наверное мой код на хаски тоже никто ни осилил бы в поддержку
                  Рассказывай как делал, потому что я тут даже ивал и getElementById вижу.

                  Если мне захочится парсить ввод юзера, то придется сначала его преобразовать в лямбду на джс?
                  Ответить
                  • > Выглядит очень кратко для такого функционала, даже не верится.
                    Говнокод+нет поддержки крайних случаев

                    > Всегда приклонялся перед людьми, пищущими парсер на каких-то регулярках. Как это возможно?
                    а) повторное применение регулярок. Регулярки, вызванные в цикле/рекурсивной функции уже поднимаются до КС-грамматик
                    б) объединение сущностей в одну
                    Вот я сначала (41-42 строки) парсил штуки вида (a, b, c) => expression; и function (a,b,c) { return expression; }. Они описываются регулярными грамматиками. Дальше работал со списком аргументов и выражением.

                    > Если мне захочится парсить ввод юзера, то придется сначала его преобразовать в лямбду на джс?
                    Я вырывал это выражение из жс, затем его преобразовывал, затем генерировал функцию (вот тут и нужен eval). Поэтому можно обойтись без ЖС (убрать 40-43) и задать в строке 44 свои args, expr (expr надо без пробелов).
                    Собственно, можно оставить только diff(parseExpr(expr), 1): https://jsfiddle.net/kmvohnb4/1/ Численное дифференцирование тут выпилилось, в исходной версии оно описано в строках 51-57, сразу создаёт функцию.

                    > Рассказывай как делал, потому что я тут даже ивал вижу.
                    Алгоритм работы (в общем, я в этом порядке и писал):
                    1. Выделяем тело функции и аргументы (40-44)
                    2. Парсим (функция parseExpr).
                    2.1. Выделяем токены. Регулярка в строке 5 выделяет токены.
                    2.2. В цикле, пока есть изменения, несколько раз проходим по строке и сворачиваем токены
                    Строка 15 - проверка штук вида left_bracket A right_bracket; Строка 20 - проверка штук вида A op B
                    3. Рекурсивно обходим получившееся AST (функция diff на строке 30) и генерируем выражение (оптимизации выражения нет)
                    4. Генерируем функцию, имея список аргументов и тело
                    5. Если не получилось, выполняем численное дифференцирование. $$df на строке 52 вызывает f с разными значениями аргумента номер id. eval тут нужен для того, чтобы сохранить список аргументов, чтобы при повторном вызове diff можно было понять, по какому аргументу дифференцировать.
                    Ответить
                    • Подправил ссылку, добавив /1/. До этого там была исходная версия или что-то похожее на исходную.
                      Ответить
                      • Упрощения выражений конечно нет, но стало заметно короче и чище. Сразу видно поклонника своего дела! Очень круто. Вот есть у нас еще настоящие мужчины, способные принять вызовов! Спасибо!
                        Ответить
                        • > Упрощения выражений конечно нет
                          Вот отсюда вся краткость (помимо неоптимального брутфорс-парсинга)
                          Ответить
                  • Использовал бы megaparsec для парсинга и не мучался.
                    Ответить
                    • Ну так там кода не меньше небось будет. А еще его изучать надо, а зачем мне Хаскель изучать?
                      Ответить
                      • Кода меньше. Чтобы не писать так страшно как сейчас.
                        Ответить
                        • Борманд, понимаешь код от ОП? Или каша?
                          Ответить
                          • tokenize и parse - с трудом и не с первого раза.

                            Остальное - красиво, на языках без паттерн-матчинга были бы портянки говн...
                            Ответить
                            • Я кстати в упрощении ошибся, вместо
                              > fs (Diff e) = fs e
                              надо
                              fs (Diff e) = Diff $ fs e.
                              Теряет знак ' производной.

                              Еще был тонкий момент с паттерн матчингом, пока я рациональные числа вместо флоатов не пихнул - не упрощало часто, ну там 0 с 0 не матчился например и тд. Вот в крестах этого типа нет и это уже проблема

                              Еще в крестах конечно дико не хватает алгебраических типов и паттернаматчинга. Почему страус не может запилить очевидные и важные вещи?
                              Ответить
                              • >Почему страус не может запилить очевидные и важные вещи?

                                Пропозиция есть http://tinyurl.com/z5fzyfd
                                Ответить
                • Походу, этот код может найти даже производную от жквери...
                  Ответить
                  • Хм, а действительно может, но только численно.
                    По номеру аргумента даже нативную фигню может
                    > var f = (function(){ return arguments[0]*arguments[0]; }).bind(this);
                    undefined
                    > f.toString()
                    "function () { [native code] }"
                    > diff(f, 0)(2)
                    3.999999999999937

                    Но так любой дурак сможет.
                    Ответить
                  • >этот код может найти даже производную от жквери...
                    Это несложно. Производных от jquery бесконечно много, надо определиться только со значением аргумента.

                    Теоретически jQuery'(google)=angular
                    http://www.google.com.ua/search?q=jquery+derived+framework
                    Ответить
                • >Чёрт, я не спал, не пил, не ел, писал код. laMer007, демон-искуситель, зачем?

                  А мне вот теперь в свой калькулятор производные запиливать
                  Ответить
                  • Запиливай и выкладывай. Можешь отдельным говнокодом, только ссылки перекрестные кинь.
                    Ответить
                    • Там не говнокод.
                      Ответить
                      • Пруф.
                        Ответить
                      • Ты так говоришь, как-будто в ОП коде говнокод)))
                        Ответить
                        • Почему список токенов перевернутый?
                          Ответить
                          • Преждевременная оптимизация.
                            Ответить
                            • Он его потом снова переворачивает
                              Ответить
                              • Ну смотри, у меня список однонаправленный и поэтому токинизация его формирует в обратном порядке. Ну то есть я не пробегаю по всему списку, чтобы запихнуть элемент в конец списка, чтобы в итоге это все было в верном порядке. Ну и понятно структура списка в хаскель иммутабильная и поэтому бы при (++) до головы пришлось бы список весь перестроить, поэтому не делал так.

                                Ну и ещё потом парсер требует поиска операций +-*/ среди токинов в обратном порядке. Ну то есть я не смогу в парсере итерировать по списку токенов удобно и легко, если там список токенов в прямом порядке, поэтому мне в двойне повезло, что токинизатор генерирует список токенов в обратном порядке.

                                Почему парсер требует обратного поиска операций в списке токенов? Ну потом у чтобы потом операции в правильном порядке вычислялись при сворачивании дерева выражений при вычислении. Иначе же будет неправильный порядок вычисления например в случае a-b-c (a-b должно оказаться в листах дерева в данном случае)
                                Ответить
                                • Список можно нормально формировать в прямом порядке, как здесь:
                                  map f [] = []
                                  map f (x:xs) = f x : map f xs

                                  А порядок вычислений зависит от ассоциативности операторов. Твой парсер всосет на правоассоциативном операторе степени ^.
                                  Ответить
    • > на любом языке

      Однострочник на Wolfram Language катит?
      Ответить
      • Ну ты можешь конечно, но честно тебе скажу, посоны во дворе не оценят. Это не круто.
        Ответить
    • Когда-то начинал писать реализацию символьной математики для C#, но так и не довел до логического конца из-за нехватки времени. https://github.com/AlexSabaka/symbolicmath

      Можно было писать такой код:
      var x = new Variable("x");
      var y = new Variable("y");
      var f = SMath.Sin(x + y) * (x + y) ^ 2;
      Console.WriteLine(f);
      Console.WriteLine(f.Derivate(x));
      Console.WriteLine(f.Derivate(y));
      Console.WriteLine(f.Derivate(x).Derivate(y));
      Ответить
      • Пытался там реализовать символьные и численные солверы уравнений и интегрирование, особо далеко не продвинулся и забил на это дело.
        Ответить
    • Еще есть филиал Специальной олимпиады на
      http://www.gamedev.ru/flame/forum/?id=185983&page=7#m91
      (если кому интересно)
      Ответить
      • показать все, что скрытоАмериканцы считают дни до коллапса доллара. В Штатах царит паника — Американцы организуются в группы, находят схроны в горах, запасаются консервами, ящиками с бутилированной водой, скупают золото и сейфы, ружья и боеприпасы. “Глашатай элит” Линдси Виллиамс объявил, что коллапс произойдёт между 15 сентября и декабрём 2015 года. Это тот пастор, который заявляет, что “элиты” выбрали его, чтобы доставлять через него свои “мэсседжи” “скоту” — так они называют простой народ (“кэттл” / “cattle”). ЦРУшники и сотрудники АНБ массово увольняются из своих “контор”, и буквально зарываются в землю. Как старый садист Киссинджер сказал в своём знаменитом интервью 2012 года: “Скорее покупайте фермы в малолюдных местах. Людей останется гораздо меньше, но им будет жить гораздо лучше”.

        Псевдо-Глобалисты самоназванного “Нового Мирового Порядка” уже подготовили всё для коллапса доллара. Цель – обнулить, то есть, обворовать через ФОРС МАЖОР долларово-валютные резервы России и Китая. Чтобы получилось так, что Россия отдавала им свои ресурсы десятилетия бесплатно, а Китай пахал на них десятилетия бесплатно. Уже создана новая ГЛОБАЛЬНАЯ резервная валюта — СПЗ (Специальные Права Заимствования / SDR – The Spec
        Ответить
    • http://ideone.com/60SVXF
      По размеру не оптимизировал. Да и по красоте не очень.
      Можно было бы попробовать считерить и переопределить операторы чтоб не приходилось ничего парсить, но я ориентировался на то чтоб потом на паскале аналогичный код использовать.
      Зато есть функции, степени и всякое такое. Правда про правоассоциативность степени я забыл.
      Ответить
    • Реквестирую на FORTH
      Ответить
    • https://habrahabr.ru/post/310016/ Аналитическое вычисление производных на шаблонах C++
      Ответить
      • А интегрирование слабо?
        Ответить
        • > А интегрирование слабо?
          А слабо найти полином с целыми коэффицентами P(x): P(e) = 0?
          AFAIK, неопределённый интеграл большинства функций, записанных в виде суперпозиции элементарных, не выражается через элементарные функции.
          Ответить
        • Есть алгоритм Риша-Бронштейна (не знаю, реализовал ли его кто-то полностью на данный момент), который работает для ограниченного класса функций. А вот для спецфункций, кажется, есть только эвристики, и они жутко тупят.
          Ответить
        • 1/ln(x)
          Ответить
      • Вроде https://habrahabr.ru/post/149470/ ещё за 4 года до вышеупомянутого поста было. Да даже у меня где-то валяется подобная питушня.
        Или тут ещё на этапе компиляции оптимизация выражений в некоторых случаях добавлена?
        Ответить
        • показать все, что скрытоСатанинско-Сионисткий альянс провёл и по отношению к Арийским народам и Арийской истории, так что даже слово “Арий” стало преступным, хотя вся Россия покрыта реками с названиями “Арий”, “Арийка”, “Арьян”. А буквы (буквы!!!) Арийского алфавита стали подаваться как символы абсолютного зла! Ведь свастика — это всего лишь буква Арийского алфавита. Кто мне может объяснить, как БУКВА АЛФАВИТА может быль запрещена, на основе её использования негодяями, ничего не имеющими общего с историей Ариев и учением Ариев, и нанятыми ещё более преступным Сионистко-Сатанинским альянсом? (В скобках, Ашкеназы-Хазары, 92% мирового т.н. “еврейства” сами являются Ариями — Турками от Руской праматери, по своим же генетическим исследованиям. А ведь материнская / митохондриальная ДНК не меняется!)

          То же самое сейчас Сатанинсксо-Сионисткий альянс проделывает по отношению к Исламу. ИГИШ (ИГИЛ, ИГ) — это грандиозное шоу, разыгрываемое агентами Моссада по дискредитации Ислама, и заправляемое “главой Исламского Государства” Абу Бахр Аль-Багдади, кто, на самом деле, является агентом Моссада Шимоном Эллиотом.

          Цель Сатанинско-Сионисткого Альянса — уничтожить суверенные государства и суверенные валюты, и установить глобальное господство одной нации в двуклассовом обществе рабов и господ. Недаром, банковская элита исповедует Талмуд — глобальный геноцид Гое
          Ответить
    • показать все, что скрытоОбнаружен вирус!
      Сканер памяти обнаружил вредоносную программу! Очень опасно работать на компьютере, в памяти которого активен вирус. Рекомендуется назначить загрузочное сканирование.
      Ответить
      • показать все, что скрытоВопрос: кто виноват в репрессиях в СССР? Ответ — Сионисткие банкиры Нью-Йорка и Сити оф Лондон, нанявшие сброд, целью которого была дискредитация Советской власти. Этим сбродом оказались евреи просто в силу того, что были наиболее угнетённым и деклассированным элементом мирового финансового капитализма. И угнетены они были как раз своими же собственными сородичами — владельцами банков и псевдо-Иудеями, Турками от Руской праматери, незаконно присвоившими себе Иудаизм подлинных, негроидных Иудеев Танаха из Племени Сет / Племени Иуды из Земли Сет (Верхний Египет = Эфиопия и Судан).

        Репрессии в СССР и голодомор лежат на совести Иудо-Троцкистов, специально подготовленных и засланных пароходом из Нью-Йорка Сионисткими банкирами Нью-Йорка и Сити оф Лондон. Никакого отношения эти зверства не имеют к светлым идеалам свободы, равенства и братства, которые лежали в основе СССР и которые лежат в основе Православного Христианства (сейчас уже исковерканные Институционной Церковью, подмятой под себя мировым Сионизмом).

        Ту же компанию по дискредитации Сатанинско-Сионисткий альянс провёл и по отношению к Арийским народам и Арий
        Ответить

    Добавить комментарий