Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <map>
- #include <set>
- #include <cassert>
- using namespace std;
- template<typename value>
- class expression {
- public:
- value result;
- string latex;
- enum precedence_t {
- p_plusmin,
- p_muldiv,
- p_none
- } precedence;
- int badness;
- expression(value result) : result(result), precedence(p_none), badness(0) {
- stringstream latex_stream;
- latex_stream << result;
- latex = latex_stream.str();
- }
- expression(value result, string latex, precedence_t precedence, int badness) : result(result), latex(latex), precedence(precedence), badness(badness) {}
- bool operator<(const expression & e) const {
- if (result != e.result ) return result < e.result;
- if (badness != e.badness ) return badness < e.badness;
- if (precedence != e.precedence) return precedence < e.precedence;
- return latex < e.latex;
- }
- bool operator==(const expression & e) const {
- return result == e.result && badness == e.badness && precedence == e.precedence && latex == e.latex;
- }
- expression operator+(const expression & e) const {
- int badness = this->badness + e.badness;
- string a = latex;
- string b = e.latex;
- badness += 200;
- return expression(result + e.result, a+"+"+b, p_plusmin, badness);
- }
- expression operator-(const expression & e) const {
- int badness = this->badness + e.badness;
- string a = latex;
- string b = e.latex;
- if (e.precedence == p_plusmin){ b = "\\left("+b+"\\right)"; badness += 10; }
- return expression(result - e.result, a+"-"+b, p_plusmin, badness + 1);
- }
- expression operator*(const expression & e) const {
- int badness = this->badness + e.badness;
- string a = latex;
- string b = e.latex;
- if ( precedence == p_plusmin){ a = "\\left("+a+"\\right)"; badness += 10; }
- if (e.precedence == p_plusmin){ b = "\\left("+b+"\\right)"; badness += 10; }
- return expression(result * e.result, a+"\\times"+b, p_muldiv, badness);
- }
- expression operator/(const expression & e) const {
- int badness = this->badness + e.badness;
- string a = latex;
- string b = e.latex;
- return expression(result / e.result, "\\frac{"+a+"}{"+b+"}", p_muldiv, badness + 8);
- }
- };
- template<typename value>
- inline ostream & operator<<(ostream & out, const expression<value> & e){
- return out << e.latex;
- }
- template<typename inset, typename outset>
- void allexpressions(const inset numbers, outset & results, bool use_cache = false){
- assert(results.empty());
- if (numbers.size() == 1){
- results.insert(*numbers.begin());
- } else {
- static map<inset,outset> cache;
- if (use_cache){
- typename map<inset,outset>::const_iterator cache_i = cache.find(numbers);
- if (cache_i != cache.end()){
- results = cache_i->second;
- return;
- }
- }
- for(unsigned int combination = 1; combination < (1 << numbers.size())-1; combination++){
- inset a_in, b_in;
- typename inset::const_iterator i = numbers.begin();
- for(size_t n = 0; i != numbers.end(); n++) (combination & (1<<n) ? a_in : b_in).insert(*i++);
- outset a_out, b_out;
- allexpressions(a_in, a_out, true);
- allexpressions(b_in, b_out, true);
- for(typename outset::const_iterator a = a_out.begin(); a != a_out.end(); a++)
- for(typename outset::const_iterator b = b_out.begin(); b != b_out.end(); b++){
- results.insert(*a + *b);
- results.insert(*a - *b);
- results.insert(*a * *b);
- results.insert(*a / *b);
- }
- }
- if (use_cache) cache.insert(make_pair(numbers,results));
- return;
- }
- }
- template<typename inset, typename outset>
- typename outset::key_type maximumpossiblevalue(const inset numbers){
- outset values;
- allexpressions(numbers,values,numbers.size());
- typename outset::key_type max = 0;
- while(values.find(++max) != values.end());
- return max-1;
- }
- /*
- double maxsum = 0;
- size_t countsumsets(double sum, size_t size, multiset<double> values){
- double max = values.empty() ? sum : *values.begin();
- if (size == 1){
- if (sum >= 0 && sum <= max){
- values.insert(sum);
- double sum = maximumpossiblevalue<multiset<double>,set<double> >(values);
- dump(values);
- cout << ": " << sum << endl;
- return 1;
- }
- return 0;
- }
- size_t count = 0;
- for(double i = double; i >= 0; i--){
- multiset<double> x = values;
- x.insert(i);
- count += countsumsets(sum-i, size-1, x);
- }
- return count;
- }*/
- void printalllatexexpressions(multiset<expression<double> > values){
- set<expression<double> > expressions;
- allexpressions(values,expressions,values.size());
- double max = 0;
- cout << "\\documentclass{article}" << endl
- << "\\pagestyle{empty}" << endl
- << "\\usepackage{amsmath}" << endl
- << "\\begin{document}" << endl;
- set<expression<double> >::iterator i = expressions.begin();
- while(true){
- max++;
- while(i != expressions.end() && i->result < max) i++;
- if (i == expressions.end() || i->result != max) break;
- //if (c++) cout << "\\newpage" << endl;
- cout << "$$" << max << " = " << *i << "$$" << endl;
- while(++i != expressions.end() && i->result == max);
- }
- cout << "\\end{document}" << endl;
- }
- int main(){
- /*multiset<num> x;
- cout << countsumsets(50,5,x) << endl;*/
- multiset<expression<double> > x;
- x.insert(2);
- x.insert(4);
- x.insert(9);
- x.insert(12);
- x.insert(23);
- printalllatexexpressions(x);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement