21 working

This commit is contained in:
Eric Mertens 2023-04-04 21:11:22 -07:00
parent c825b34d47
commit df4c18e47b

View File

@ -7,7 +7,6 @@
#include <vector> #include <vector>
#include <boost/phoenix.hpp> #include <boost/phoenix.hpp>
#include <boost/range/irange.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <doctest.h> #include <doctest.h>
@ -85,10 +84,10 @@ auto Parse(std::istream & in) -> Input
} }
auto Eval( auto Eval(
std::unordered_map<std::string, std::int64_t> & values, std::unordered_map<std::string, double> & values,
std::unordered_map<std::string, Expr> const& exprs, std::unordered_map<std::string, Expr> const& exprs,
std::string const& var) std::string const& var)
-> std::int64_t -> double
{ {
auto it = values.find(var); auto it = values.find(var);
if (it != values.end()) { if (it != values.end()) {
@ -97,7 +96,7 @@ auto Eval(
auto const& [lhs,rhs,op] = exprs.at(var); auto const& [lhs,rhs,op] = exprs.at(var);
auto const l = Eval(values, exprs, lhs); auto const l = Eval(values, exprs, lhs);
auto const r = Eval(values, exprs, rhs); auto const r = Eval(values, exprs, rhs);
std::int64_t o; double o;
switch (op) { switch (op) {
case Op::Add: o = l + r; break; case Op::Add: o = l + r; break;
case Op::Sub: o = l - r; break; case Op::Sub: o = l - r; break;
@ -110,7 +109,7 @@ auto Eval(
auto Part1(Input const& input) -> std::int64_t auto Part1(Input const& input) -> std::int64_t
{ {
std::unordered_map<std::string, std::int64_t> values; std::unordered_map<std::string, double> values;
std::unordered_map<std::string, Expr> exprs; std::unordered_map<std::string, Expr> exprs;
for (auto const& entry : input) { for (auto const& entry : input) {
std::visit(overloaded { std::visit(overloaded {
@ -123,7 +122,7 @@ auto Part1(Input const& input) -> std::int64_t
auto Part2(Input const& input) -> std::int64_t auto Part2(Input const& input) -> std::int64_t
{ {
std::unordered_map<std::string, std::int64_t> values; std::unordered_map<std::string, double> values;
std::unordered_map<std::string, Expr> exprs; std::unordered_map<std::string, Expr> exprs;
for (auto const& entry : input) { for (auto const& entry : input) {
std::visit(overloaded { std::visit(overloaded {
@ -134,26 +133,24 @@ auto Part2(Input const& input) -> std::int64_t
exprs.at("root").op = Op::Sub; exprs.at("root").op = Op::Sub;
auto eval = [&](std::int64_t humn) -> std::int64_t { auto eval = [&](double humn) -> double {
auto values_ = values; auto values_ = values;
values_.at("humn") = humn; values_.at("humn") = humn;
return Eval(values_, exprs, "root"); return Eval(values_, exprs, "root");
}; };
auto x0 = 10; auto x0 = 10.0;
auto x1 = 20; auto x1 = 20.0;
auto fx0 = eval(x0); auto fx0 = eval(x0);
auto fx1 = eval(x1); while (std::abs(x0 - x1) > 0.01) {
std::int64_t a = 0, b = 1; auto const fx1 = eval(x1);
while (x0 != x1 || a%b != 0) { auto const x2 = x1 - fx1 * (x1 - x0) / (fx1 - fx0);
a = eval(x1) * (x1 - x0);
b = eval(x1) - eval(x0);
auto const x2 = x1 - a / b;
x0 = x1; x0 = x1;
x1 = x2; x1 = x2;
fx0 = fx1;
} }
return x0; return std::round(x1);
} }
} // namespace } // namespace