Advertisement
Guest User

Untitled

a guest
Jun 25th, 2017
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.16 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. #include <string>
  4. #include <sstream>
  5. #include <map>
  6. #include <set>
  7. #include <cassert>
  8.  
  9. using namespace std;
  10.  
  11. template<typename value>
  12. class expression {
  13.     public:
  14.         value result;
  15.         string latex;
  16.         enum precedence_t {
  17.             p_plusmin,
  18.             p_muldiv,
  19.             p_none
  20.         } precedence;
  21.         int badness;
  22.         expression(value result) : result(result), precedence(p_none), badness(0) {
  23.             stringstream latex_stream;
  24.             latex_stream << result;
  25.             latex = latex_stream.str();
  26.         }
  27.         expression(value result, string latex, precedence_t precedence, int badness) : result(result), latex(latex), precedence(precedence), badness(badness) {}
  28.         bool operator<(const expression & e) const {
  29.             if (result     != e.result    ) return result     < e.result;
  30.             if (badness    != e.badness   ) return badness    < e.badness;
  31.             if (precedence != e.precedence) return precedence < e.precedence;
  32.             return latex < e.latex;
  33.         }
  34.         bool operator==(const expression & e) const {
  35.             return result == e.result && badness == e.badness && precedence == e.precedence && latex == e.latex;
  36.         }
  37.         expression operator+(const expression & e) const {
  38.             int badness = this->badness + e.badness;
  39.             string a =   latex;
  40.             string b = e.latex;
  41.             badness += 200;
  42.             return expression(result + e.result, a+"+"+b, p_plusmin, badness);
  43.         }
  44.         expression operator-(const expression & e) const {
  45.             int badness = this->badness + e.badness;
  46.             string a =   latex;
  47.             string b = e.latex;
  48.             if (e.precedence == p_plusmin){ b = "\\left("+b+"\\right)"; badness += 10; }
  49.             return expression(result - e.result, a+"-"+b, p_plusmin, badness + 1);
  50.         }
  51.         expression operator*(const expression & e) const {
  52.             int badness = this->badness + e.badness;
  53.             string a =   latex;
  54.             string b = e.latex;
  55.             if (  precedence == p_plusmin){ a = "\\left("+a+"\\right)"; badness += 10; }
  56.             if (e.precedence == p_plusmin){ b = "\\left("+b+"\\right)"; badness += 10; }
  57.             return expression(result * e.result, a+"\\times"+b, p_muldiv, badness);
  58.         }
  59.         expression operator/(const expression & e) const {
  60.             int badness = this->badness + e.badness;
  61.             string a =   latex;
  62.             string b = e.latex;
  63.             return expression(result / e.result, "\\frac{"+a+"}{"+b+"}", p_muldiv, badness + 8);
  64.         }
  65. };
  66.  
  67. template<typename value>
  68. inline ostream & operator<<(ostream & out, const expression<value> & e){
  69.     return out << e.latex;
  70. }
  71.  
  72. template<typename inset, typename outset>
  73. void allexpressions(const inset numbers, outset & results, bool use_cache = false){
  74.     assert(results.empty());
  75.     if (numbers.size() == 1){
  76.         results.insert(*numbers.begin());
  77.     } else {
  78.         static map<inset,outset> cache;
  79.         if (use_cache){
  80.             typename map<inset,outset>::const_iterator cache_i = cache.find(numbers);
  81.             if (cache_i != cache.end()){
  82.                 results = cache_i->second;
  83.                 return;
  84.             }
  85.         }
  86.         for(unsigned int combination = 1; combination < (1 << numbers.size())-1; combination++){
  87.             inset a_in, b_in;
  88.             typename inset::const_iterator i = numbers.begin();
  89.             for(size_t n = 0; i != numbers.end(); n++) (combination & (1<<n) ? a_in : b_in).insert(*i++);
  90.             outset a_out, b_out;
  91.             allexpressions(a_in, a_out, true);
  92.             allexpressions(b_in, b_out, true);
  93.             for(typename outset::const_iterator a = a_out.begin(); a != a_out.end(); a++)
  94.             for(typename outset::const_iterator b = b_out.begin(); b != b_out.end(); b++){
  95.                 results.insert(*a + *b);
  96.                 results.insert(*a - *b);
  97.                 results.insert(*a * *b);
  98.                 results.insert(*a / *b);
  99.             }
  100.         }
  101.         if (use_cache) cache.insert(make_pair(numbers,results));
  102.         return;
  103.     }
  104. }
  105.  
  106. template<typename inset, typename outset>
  107. typename outset::key_type maximumpossiblevalue(const inset numbers){
  108.     outset values;
  109.     allexpressions(numbers,values,numbers.size());
  110.     typename outset::key_type max = 0;
  111.     while(values.find(++max) != values.end());
  112.     return max-1;
  113. }
  114. /*
  115. double maxsum = 0;
  116.  
  117. size_t countsumsets(double sum, size_t size, multiset<double> values){
  118.     double max = values.empty() ? sum : *values.begin();
  119.     if (size == 1){
  120.         if (sum >= 0 && sum <= max){
  121.             values.insert(sum);
  122.             double sum = maximumpossiblevalue<multiset<double>,set<double> >(values);
  123.             dump(values);
  124.             cout << ": " << sum << endl;
  125.             return 1;
  126.         }
  127.         return 0;
  128.     }
  129.     size_t count = 0;
  130.     for(double i = double; i >= 0; i--){
  131.         multiset<double> x = values;
  132.         x.insert(i);
  133.         count += countsumsets(sum-i, size-1, x);
  134.     }
  135.     return count;
  136. }*/
  137.  
  138. void printalllatexexpressions(multiset<expression<double> > values){
  139.     set<expression<double> > expressions;
  140.     allexpressions(values,expressions,values.size());
  141.     double max = 0;
  142.     cout << "\\documentclass{article}" << endl
  143.          << "\\pagestyle{empty}"  << endl
  144.          << "\\usepackage{amsmath}" << endl
  145.          << "\\begin{document}" << endl;
  146.     set<expression<double> >::iterator i = expressions.begin();
  147.     while(true){
  148.         max++;
  149.         while(i != expressions.end() && i->result < max) i++;
  150.         if (i == expressions.end() || i->result != max) break;
  151.         //if (c++) cout << "\\newpage" << endl;
  152.         cout << "$$" << max << " = " << *i << "$$" << endl;
  153.         while(++i != expressions.end() && i->result == max);
  154.     }
  155.     cout << "\\end{document}" << endl;
  156. }
  157.  
  158. int main(){
  159.     /*multiset<num> x;
  160.     cout << countsumsets(50,5,x) << endl;*/
  161.     multiset<expression<double> > x;
  162.     x.insert(2);
  163.     x.insert(4);
  164.     x.insert(9);
  165.     x.insert(12);
  166.     x.insert(23);
  167.     printalllatexexpressions(x);
  168.     return 0;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement