Advertisement
xgallom

Untitled

Jun 13th, 2020
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.22 KB | None | 0 0
  1. // poly.cpp
  2.  
  3. double find_root(const poly &p, bounds b)
  4. {
  5.     constexpr double Delta = 1e-5;
  6.  
  7.     auto eval = [&p](double x) {
  8.         double power = 1.0, result = 0.0;
  9.  
  10.         auto c = p.crbegin();
  11.         const auto end = p.crend();
  12.  
  13.         while(c != end) {
  14.             result += *c++ * power;
  15.             power *= x;
  16.         }
  17.  
  18.         return result;
  19.     };
  20.  
  21.     auto mid = [&b]() {
  22.         return b.first + (b.second - b.first) / 2.0;
  23.     };
  24.  
  25.     while(b.second - b.first > Delta) {
  26.         const auto m = mid(), y = eval(m);
  27.  
  28.         if(y < 0.0)
  29.             b.first = m;
  30.         else
  31.             b.second = m;
  32.     }
  33.  
  34.     return mid();
  35. }
  36.  
  37.  
  38.  
  39. // linear.cpp
  40.  
  41. #include <array>
  42.  
  43. std::pair<double, double> solve(const std::string &eq)
  44. {
  45.     enum Entry {
  46.         EntryX, EntryY, EntryConstant, EntryCount
  47.     };
  48.     enum Side {
  49.         SideLeft, SideRight, SideCount
  50.     };
  51.     constexpr auto EquationCount = 2;
  52.  
  53.     using ParsingResult = std::array<std::array<std::array<int, EntryCount>, SideCount>, EquationCount>;
  54.     using EquationSystem = std::array<std::array<int, EntryCount>, EquationCount>;
  55.  
  56.     auto parse = [](const char *str) -> ParsingResult {
  57.         char c;
  58.         ParsingResult result = {};
  59.  
  60.         auto eq = 0;
  61.         auto isNegative = false;
  62.         auto entry = EntryConstant;
  63.         auto value = 0;
  64.         auto side = SideLeft;
  65.  
  66.         auto apply = [&]() mutable {
  67.             if(entry != EntryConstant && !value)
  68.                 value = 1;
  69.             result[eq][side][entry] += isNegative ? -value : value;
  70.  
  71.             isNegative = false;
  72.             entry = EntryConstant;
  73.             value = 0;
  74.         };
  75.  
  76.         while((c = *str++)) {
  77.             switch(c) {
  78.                 case '\n':
  79.                     apply();
  80.                     side = SideLeft;
  81.                     ++eq;
  82.                     break;
  83.  
  84.                 case '+':
  85.                     apply();
  86.                     break;
  87.  
  88.                 case '-':
  89.                     apply();
  90.                     isNegative = true;
  91.                     break;
  92.  
  93.                 case '=':
  94.                     apply();
  95.                     side = SideRight;
  96.                     break;
  97.  
  98.                 case 'x':
  99.                     entry = EntryX;
  100.                     break;
  101.  
  102.                 case 'y':
  103.                     entry = EntryY;
  104.                     break;
  105.  
  106.                 default:
  107.                     if(c >= '0' && c <= '9') {
  108.                         value *= 10;
  109.                         value += c - '0';
  110.                     }
  111.                     break;
  112.             }
  113.         }
  114.  
  115.         apply();
  116.  
  117.         return result;
  118.     };
  119.  
  120.     auto reduce = [](ParsingResult &&parsingResult) -> EquationSystem {
  121.         return EquationSystem{
  122.                 std::array<int, EntryCount>{
  123.                         parsingResult[0][SideLeft][EntryX] - parsingResult[0][SideRight][EntryX],
  124.                         parsingResult[0][SideLeft][EntryY] - parsingResult[0][SideRight][EntryY],
  125.                         parsingResult[0][SideRight][EntryConstant] - parsingResult[0][SideLeft][EntryConstant],
  126.                 },
  127.                 std::array<int, EntryCount>{
  128.                         parsingResult[1][SideLeft][EntryX] - parsingResult[1][SideRight][EntryX],
  129.                         parsingResult[1][SideLeft][EntryY] - parsingResult[1][SideRight][EntryY],
  130.                         parsingResult[1][SideRight][EntryConstant] - parsingResult[1][SideLeft][EntryConstant],
  131.                 }
  132.         };
  133.     };
  134.  
  135.     auto solve = [](EquationSystem &&equationSystem) -> std::pair<double, double> {
  136.         auto x = 0.0, y = 0.0;
  137.  
  138.         if(!equationSystem[0][EntryX]) {
  139.             y = double(equationSystem[0][EntryConstant]) / equationSystem[0][EntryY];
  140.             x = (double(equationSystem[1][EntryConstant]) - y * equationSystem[1][EntryY]) / equationSystem[1][EntryX];
  141.         }
  142.         else if(!equationSystem[0][EntryY]) {
  143.             x = double(equationSystem[0][EntryConstant]) / equationSystem[0][EntryX];
  144.             y = (double(equationSystem[1][EntryConstant]) - x * equationSystem[1][EntryX]) / equationSystem[1][EntryY];
  145.         }
  146.         else if(!equationSystem[1][EntryX]) {
  147.             y = double(equationSystem[1][EntryConstant]) / equationSystem[1][EntryY];
  148.             x = (double(equationSystem[0][EntryConstant]) - y * equationSystem[0][EntryY]) / equationSystem[0][EntryX];
  149.         }
  150.         else if(!equationSystem[1][EntryY]) {
  151.             x = double(equationSystem[1][EntryConstant]) / equationSystem[1][EntryX];
  152.             y = (double(equationSystem[0][EntryConstant]) - x * equationSystem[0][EntryX]) / equationSystem[0][EntryY];
  153.         }
  154.         else {
  155.             const auto
  156.                     pivot = double(equationSystem[1][EntryX]) / equationSystem[0][EntryX],
  157.                     eq1y = double(equationSystem[1][EntryY]) - equationSystem[0][EntryY] * pivot,
  158.                     eq1c = double(equationSystem[1][EntryConstant]) - equationSystem[0][EntryConstant] * pivot;
  159.  
  160.             y = eq1c / eq1y;
  161.             x = (double(equationSystem[0][EntryConstant]) - y * equationSystem[0][EntryY]) / equationSystem[0][EntryX];
  162.         }
  163.  
  164.         if(!x)
  165.             x = 0.0;
  166.         if(!y)
  167.             y = 0.0;
  168.  
  169.         return {x, y};
  170.     };
  171.  
  172.     return solve(reduce(parse(eq.c_str())));
  173. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement