diff options
Diffstat (limited to 'impl')
-rw-r--r-- | impl/Constant.h | 22 | ||||
-rw-r--r-- | impl/Equation.h | 47 | ||||
-rw-r--r-- | impl/EquationSystem.h | 40 | ||||
-rw-r--r-- | impl/Expression.h | 12 | ||||
-rw-r--r-- | impl/Makefile | 8 | ||||
-rw-r--r-- | impl/Max.h | 22 | ||||
-rw-r--r-- | impl/Min.h | 22 | ||||
-rw-r--r-- | impl/Sum.h | 22 | ||||
-rw-r--r-- | impl/Term.h | 1 | ||||
-rw-r--r-- | impl/Variable.h | 24 | ||||
-rw-r--r-- | impl/main.cpp | 36 |
11 files changed, 256 insertions, 0 deletions
diff --git a/impl/Constant.h b/impl/Constant.h new file mode 100644 index 0000000..bab8cd9 --- /dev/null +++ b/impl/Constant.h @@ -0,0 +1,22 @@ +#ifndef CONSTANT_H +#define CONSTANT_H + +#include "Expression.h" + +template<class T> +struct Constant : public Expression<T> { + Constant(const T& value) : _value(value) { } + + T value() const { + return this->_value; + } + + T eval(const std::map<std::string, T>&) const { + return _value; + } + + private: + const T _value; +}; + +#endif diff --git a/impl/Equation.h b/impl/Equation.h new file mode 100644 index 0000000..b861768 --- /dev/null +++ b/impl/Equation.h @@ -0,0 +1,47 @@ +#ifndef EQUATION_H +#define EQUATION_H + +#include "Variable.h" +#include "Expression.h" +#include <map> +#include <string> + +template<class T> +struct Equation { + Equation(const Variable<T>& var, Expression<T>* value) + : _var(var), _value(value) { } + + Variable<T> var() const { + return _var; + } + Variable<T> var(const Variable<T>& var) { + Variable<T> old_var = _var; + _var = var; + return _var; + } + + Expression<T>* value() const { + return _value; + } + Expression<T>* value(const Expression<T>* value) { + Expression<T>* old_value = _value; + _value = value; + return old_value; + } + + std::map<std::string, T> solve(const std::map<std::string, T>& curr) { + std::map<std::string, T> result = curr; + T last; + do { + last = result[_var.name()]; + result[_var.name()] = _value->eval(result); + } while (last != result[_var.name()]); + return result; + } + + private: + Variable<T> _var; + Expression<T>* _value; +}; + +#endif diff --git a/impl/EquationSystem.h b/impl/EquationSystem.h new file mode 100644 index 0000000..9a393c8 --- /dev/null +++ b/impl/EquationSystem.h @@ -0,0 +1,40 @@ +#ifndef EQUATIONSYSTEM_H +#define EQUATIONSYSTEM_H + +#include "Equation.h" +#include <list> + +template<class T> +struct EquationSystem { + bool add(Equation<T> e) { + for (iterator it = equations.begin(); + it != equations.end(); + ++it) { + if ((*it).var().name() == e.var().name()) { + return false; + } + } + this->equations.push_back(e); + return true; + } + + std::map<std::string, T> solve(std::map<std::string, T> start) { + std::map<std::string, T> result = start; + std::map<std::string, T> comparison; + do { + comparison = result; + for (iterator it = equations.begin(); + it != equations.end(); + ++it) { + result = it->solve(result); + } + } while (comparison != result); + return result; + } + + private: + typedef typename std::list< Equation<T> >::iterator iterator; + std::list< Equation<T> > equations; +}; + +#endif diff --git a/impl/Expression.h b/impl/Expression.h new file mode 100644 index 0000000..105ad28 --- /dev/null +++ b/impl/Expression.h @@ -0,0 +1,12 @@ +#ifndef EXPRESSION_H +#define EXPRESSION_H + +#include <string> +#include <map> + +template<class T> +struct Expression { + virtual T eval(const std::map<std::string, T>&) const = 0; +}; + +#endif diff --git a/impl/Makefile b/impl/Makefile new file mode 100644 index 0000000..1d2eb4b --- /dev/null +++ b/impl/Makefile @@ -0,0 +1,8 @@ +CC=g++ +BUILD=build/ + +all: build-dir + $(CC) main.cpp -Wall -Werror -o $(BUILD)/main + +build-dir: + mkdir -p $(BUILD) diff --git a/impl/Max.h b/impl/Max.h new file mode 100644 index 0000000..b3b5d65 --- /dev/null +++ b/impl/Max.h @@ -0,0 +1,22 @@ +#ifndef MAX_H +#define MAX_H + +#include "Expression.h" + +template<class T> +struct Max : public Expression<T> { + Max(Expression<T>* left, Expression<T>* right) + : _left(left), _right(right) { } + + T eval(const std::map<std::string, T>& mappings) const { + T left = _left->eval(mappings); + T right = _right->eval(mappings); + return left < right ? right : left; + } + + private: + Expression<T>* _left; + Expression<T>* _right; +}; + +#endif diff --git a/impl/Min.h b/impl/Min.h new file mode 100644 index 0000000..9f17545 --- /dev/null +++ b/impl/Min.h @@ -0,0 +1,22 @@ +#ifndef MIN_H +#define MIN_H + +#include "Expression.h" + +template<class T> +struct Min : public Expression<T> { + Min(Expression<T>* left, Expression<T>* right) + : _left(left), _right(right) { } + + T eval(const std::map<std::string, T>& mappings) const { + T left = _left->eval(mappings); + T right = _right->eval(mappings); + return left < right ? left : right; + } + + private: + Expression<T>* _left; + Expression<T>* _right; +}; + +#endif diff --git a/impl/Sum.h b/impl/Sum.h new file mode 100644 index 0000000..bf04669 --- /dev/null +++ b/impl/Sum.h @@ -0,0 +1,22 @@ +#ifndef SUM_H +#define SUM_H + +#include "Expression.h" + +template<class T> +struct Sum : public Expression<T> { + Sum(Expression<T>* left, Expression<T>* right) + : _left(left), _right(right) { } + + T eval(const std::map<std::string, T>& mappings) const { + T left = _left->eval(mappings); + T right = _right->eval(mappings); + return left + right; + } + + private: + Expression<T>* _left; + Expression<T>* _right; +}; + +#endif diff --git a/impl/Term.h b/impl/Term.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/impl/Term.h @@ -0,0 +1 @@ + diff --git a/impl/Variable.h b/impl/Variable.h new file mode 100644 index 0000000..7433426 --- /dev/null +++ b/impl/Variable.h @@ -0,0 +1,24 @@ +#ifndef VARIABLE_H +#define VARIABLE_H + +#include <string> +#include "Expression.h" + +template<class T> +struct Variable : public Expression<T> { + Variable(const std::string& name) + : _name(name) { } + + std::string name() const { + return this->_name; + } + + T eval(const std::map<std::string, T>& values) const { + return values.find(_name)->second; + } + + private: + const std::string _name; +}; + +#endif diff --git a/impl/main.cpp b/impl/main.cpp new file mode 100644 index 0000000..814a3ee --- /dev/null +++ b/impl/main.cpp @@ -0,0 +1,36 @@ +#include "Constant.h" +#include "Variable.h" +#include "Min.h" +#include "Max.h" +#include "Sum.h" +#include "Equation.h" +#include "EquationSystem.h" + +#include <iostream> + +using namespace std; + +int main() { + std::map<std::string, int> mappings; + mappings["x"] = 10; + + Equation<int> e(Variable<int>("x"), + new Max<int>( + new Min<int>( + new Constant<int>(100), + new Sum<int>( + new Variable<int>("x"), + new Constant<int>(100))), + new Constant<int>(20))); + + Equation<int> e2(Variable<int>("x"), + new Constant<int>(200)); + + EquationSystem<int> es; + es.add(e); + es.add(e2); + std::map<std::string, int> result = es.solve(mappings); + cout << result["x"] << endl; + + return 0; +} |