Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <map>
- #include <set>
- using namespace std;
- typedef float num;
- template<typename container> void dump(container c){
- dump(c.begin(), c.end());
- }
- template<typename iterator> void dump(iterator begin, iterator end){
- for(iterator i = begin; i != end; i++){
- cout.width(2);
- cout << *i << ' ';
- }
- }
- template<typename T>
- class expression {
- public:
- enum precedence_t {
- p_plusmin,
- p_muldiv,
- p_none
- } predence;
- }
- inline ostream & operator<<(ostream & out, const expression & e){
- e.write(out);
- return out;
- }
- pair<num,pair<char,string> > operator+(pair<num,pair<char,string> > a, pair<num,pair<char,string> > b){
- return make_pair(a.first+b.first,make_pair('+',a.second.second+"+"+b.second.second));
- }
- pair<num,pair<char,string> > operator-(pair<num,pair<char,string> > a, pair<num,pair<char,string> > b){
- if (b.second.first == '+') b.second.second = "\\left(" + b.second.second + "\\right)";
- return make_pair(a.first-b.first,make_pair('+',a.second.second+"-"+b.second.second));
- }
- pair<num,pair<char,string> > operator*(pair<num,pair<char,string> > a, pair<num,pair<char,string> > b){
- if (a.second.first == '+') a.second.second = "\\left(" + a.second.second + "\\right)";
- if (b.second.first == '+') b.second.second = "\\left(" + b.second.second + "\\right)";
- return make_pair(a.first*b.first,make_pair('*',a.second.second+"\\times"+b.second.second));
- }
- pair<num,pair<char,string> > operator/(pair<num,pair<char,string> > a, pair<num,pair<char,string> > b){
- return make_pair(a.first/b.first,make_pair('*',"\\frac{"+a.second.second+"}{"+b.second.second+"}"));
- }
- template<typename inset, typename outset>
- void allexpressions(const inset numbers, outset & results, size_t max_numbers = (size_t)-1){
- assert(results.empty());
- if (numbers.size() == 1){
- results.insert(*numbers.begin());
- } else {
- static map<inset,outset> cache;
- if (numbers.size() < max_numbers){
- typename map<inset,outset>::const_iterator cache_i = cache.find(numbers);
- if (cache_i != cache.end()){
- results = cache_i->second;
- return;
- }
- }
- for(int mask = 1; mask < (1 << (numbers.size()-1)); mask++){
- inset a_in, b_in;
- typename inset::const_iterator i = numbers.begin();
- for(size_t n = 0; i != numbers.end(); n++) (mask & (1<<n) ? a_in : b_in).insert(*i++);
- outset a_out, b_out;
- allexpressions(a_in, a_out);
- allexpressions(b_in, b_out);
- 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(*b + *a);
- results.insert(*a - *b);
- results.insert(*b - *a);
- results.insert(*a * *b);
- results.insert(*b * *a);
- results.insert(*a / *b);
- results.insert(*b / *a);
- }
- }
- if (numbers.size() < max_numbers) 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;
- }
- num maxsum = 0;
- size_t countsumsets(num sum, size_t size, multiset<num> values){
- num max = values.empty() ? sum/* - (size - 1)*/ : *values.begin();
- if (size == 1){
- if (sum >= 0 && sum <= max){
- values.insert(sum);
- num sum = maximumpossiblevalue<multiset<num>,set<num> >(values);
- dump(values);
- cout << ": " << sum << endl;
- return 1;
- }
- return 0;
- }
- size_t count = 0;
- for(num i = max; i >= 0; i--){
- multiset<num> x = values;
- x.insert(i);
- count += countsumsets(sum-i, size-1, x);
- }
- return count;
- }
- void printalllatexexpressions(multimap<num,pair<char,string> > values){
- set<pair<num,pair<char,string> > > expressions;
- allexpressions(values,expressions,values.size());
- size_t c = 0;
- num max = 0;
- cout << "\\documentclass{article}" << endl
- << "\\pagestyle{empty}" << endl
- << "\\usepackage{amsmath}" << endl
- << "\\begin{document}" << endl;
- //<< "\\Huge" << endl;
- /*cout << "\\begin{align*}" << endl;*/
- set<pair<num,pair<char,string> > >::iterator i = expressions.begin();
- while(true){
- max++;
- while(i != expressions.end() && i->first < max) i++;
- if (i == expressions.end() || i->first != max) break;
- if (c++) cout << "\\newpage" << endl;
- cout << "\\vbox to \\vsize{\\vfill"
- << "$\\displaystyle" << i->first << "=" << i->second.second << "$";
- while(++i != expressions.end() && i->first == max){
- cout << "$\\displaystyle=" << i->second.second << "$";
- }
- cout << "\\vfill}" << endl;
- /*if (c % 30 == 0){
- cout << endl << "\\end{align*}" << endl << "\\begin{align*}" << endl;
- } else {
- cout << "\\\\" << endl;
- }*/
- }
- cout << "\\end{document}" << endl;
- /*cout << "\\end{align*}" << endl;*/
- }
- int main(){
- multiset<num> x;
- cout << countsumsets(50,5,x) << endl;
- /*multimap<num,pair<char,string> > x;
- x.insert(make_pair((num)2,make_pair(' ',string("2"))));
- x.insert(make_pair((num)4,make_pair(' ',string("4"))));
- x.insert(make_pair((num)9,make_pair(' ',string("9"))));
- x.insert(make_pair((num)12,make_pair(' ',string("12"))));
- x.insert(make_pair((num)23,make_pair(' ',string("23"))));
- printalllatexexpressions(x);*/
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement