Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // poly.cpp
- double find_root(const poly &p, bounds b)
- {
- constexpr double Delta = 1e-5;
- auto eval = [&p](double x) {
- double power = 1.0, result = 0.0;
- auto c = p.crbegin();
- const auto end = p.crend();
- while(c != end) {
- result += *c++ * power;
- power *= x;
- }
- return result;
- };
- auto mid = [&b]() {
- return b.first + (b.second - b.first) / 2.0;
- };
- while(b.second - b.first > Delta) {
- const auto m = mid(), y = eval(m);
- if(y < 0.0)
- b.first = m;
- else
- b.second = m;
- }
- return mid();
- }
- // linear.cpp
- #include <array>
- std::pair<double, double> solve(const std::string &eq)
- {
- enum Entry {
- EntryX, EntryY, EntryConstant, EntryCount
- };
- enum Side {
- SideLeft, SideRight, SideCount
- };
- constexpr auto EquationCount = 2;
- using ParsingResult = std::array<std::array<std::array<int, EntryCount>, SideCount>, EquationCount>;
- using EquationSystem = std::array<std::array<int, EntryCount>, EquationCount>;
- auto parse = [](const char *str) -> ParsingResult {
- char c;
- ParsingResult result = {};
- auto eq = 0;
- auto isNegative = false;
- auto entry = EntryConstant;
- auto value = 0;
- auto side = SideLeft;
- auto apply = [&]() mutable {
- if(entry != EntryConstant && !value)
- value = 1;
- result[eq][side][entry] += isNegative ? -value : value;
- isNegative = false;
- entry = EntryConstant;
- value = 0;
- };
- while((c = *str++)) {
- switch(c) {
- case '\n':
- apply();
- side = SideLeft;
- ++eq;
- break;
- case '+':
- apply();
- break;
- case '-':
- apply();
- isNegative = true;
- break;
- case '=':
- apply();
- side = SideRight;
- break;
- case 'x':
- entry = EntryX;
- break;
- case 'y':
- entry = EntryY;
- break;
- default:
- if(c >= '0' && c <= '9') {
- value *= 10;
- value += c - '0';
- }
- break;
- }
- }
- apply();
- return result;
- };
- auto reduce = [](ParsingResult &&parsingResult) -> EquationSystem {
- return EquationSystem{
- std::array<int, EntryCount>{
- parsingResult[0][SideLeft][EntryX] - parsingResult[0][SideRight][EntryX],
- parsingResult[0][SideLeft][EntryY] - parsingResult[0][SideRight][EntryY],
- parsingResult[0][SideRight][EntryConstant] - parsingResult[0][SideLeft][EntryConstant],
- },
- std::array<int, EntryCount>{
- parsingResult[1][SideLeft][EntryX] - parsingResult[1][SideRight][EntryX],
- parsingResult[1][SideLeft][EntryY] - parsingResult[1][SideRight][EntryY],
- parsingResult[1][SideRight][EntryConstant] - parsingResult[1][SideLeft][EntryConstant],
- }
- };
- };
- auto solve = [](EquationSystem &&equationSystem) -> std::pair<double, double> {
- auto x = 0.0, y = 0.0;
- if(!equationSystem[0][EntryX]) {
- y = double(equationSystem[0][EntryConstant]) / equationSystem[0][EntryY];
- x = (double(equationSystem[1][EntryConstant]) - y * equationSystem[1][EntryY]) / equationSystem[1][EntryX];
- }
- else if(!equationSystem[0][EntryY]) {
- x = double(equationSystem[0][EntryConstant]) / equationSystem[0][EntryX];
- y = (double(equationSystem[1][EntryConstant]) - x * equationSystem[1][EntryX]) / equationSystem[1][EntryY];
- }
- else if(!equationSystem[1][EntryX]) {
- y = double(equationSystem[1][EntryConstant]) / equationSystem[1][EntryY];
- x = (double(equationSystem[0][EntryConstant]) - y * equationSystem[0][EntryY]) / equationSystem[0][EntryX];
- }
- else if(!equationSystem[1][EntryY]) {
- x = double(equationSystem[1][EntryConstant]) / equationSystem[1][EntryX];
- y = (double(equationSystem[0][EntryConstant]) - x * equationSystem[0][EntryX]) / equationSystem[0][EntryY];
- }
- else {
- const auto
- pivot = double(equationSystem[1][EntryX]) / equationSystem[0][EntryX],
- eq1y = double(equationSystem[1][EntryY]) - equationSystem[0][EntryY] * pivot,
- eq1c = double(equationSystem[1][EntryConstant]) - equationSystem[0][EntryConstant] * pivot;
- y = eq1c / eq1y;
- x = (double(equationSystem[0][EntryConstant]) - y * equationSystem[0][EntryY]) / equationSystem[0][EntryX];
- }
- if(!x)
- x = 0.0;
- if(!y)
- y = 0.0;
- return {x, y};
- };
- return solve(reduce(parse(eq.c_str())));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement