#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
using namespace std;
int getSum(map<int, int> list);
void readData(map<int, float>* data);
void lowestPrice();
void findSums(int n, vector<map<int, int>>* sumsList, map<int, float>* data);
void findSum(map<int, int> currList, int x, int n, vector<map<int, int>>* sumsList, map<int, float>* data);
float getPrice(map<int, int> set, map<int, float>* data);
template <typename S>
ostream& operator<<(ostream& os, const vector<S>& vector)
{
for (auto element : vector) {
os << element << " ";
}
return os;
}
bool operator==(map<int, int> m1, map<int, int> m2)
{
if(m1.size() != m2.size())
return false;
bool ret = true;
for(auto it = m1.begin(); it !=m1.end() && ret; it++)
{
if(ret && m1.count(it->first) != m2.count(it->first))
ret = false;
if(ret && m1.count(it->first) == 1)
{
if(m1.at(it->first) != m2.at(it->first))
ret = false;
}
}
return ret;
}
int main()
{
map<int, float> data;
readData(&data);
vector<map<int, int>> *sumsList;
sumsList = new vector<map<int, int>>;
findSums(40, sumsList, &data);
for(auto el : *sumsList)
{
for(auto it = el.begin(); it != el.end(); it++)
{
cout << it->first << "->" << it->second << " ";
}
cout << getPrice(el, &data) << endl;
}
return 0;
}
float getPrice(map<int, int> set, map<int, float>* data)
{
float price = 0;
for(auto it = set.begin(); it != set.end(); it++)
{
if(data->count(it->first) == 0)
return -1;
price += data->at(it->first) * it->second;
}
return price;
}
int getSum(map<int, int> list)
{
int sum = 0;
for(auto it = list.begin(); it != list.end(); it++)
sum += it->first * it->second;
return sum;
}
void findSums(int n, vector<map<int, int>>* sumsList, map<int, float>* data)
{
map<int, int> currList;
auto it = data->begin();
while(it->first <= n && it != data->end())
{
findSum(currList, it->first, n, sumsList, data);
it++;
}
}
void findSum(map<int, int> currList, int x, int n, vector<map<int, int>>* sumsList, map<int, float>* data)
{
if(currList.count(x) == 0)
currList.emplace(x, 1);
else
{
int val = 1+ currList.at(x);
currList.erase(x);
currList.emplace(x, val);
}
int currSum = getSum(currList);
if(currSum > n)
return;
else if(currSum == n)
{
for(auto list : *sumsList)
{
if(list == currList)
return;
}
sumsList->push_back(currList);
return;
}
auto it = data->begin();
while(it->first <= n-x && it != data->end())
{
findSum(currList, it->first, n, sumsList, data);
it++;
}
}
void readData(map<int, float>* data)
{
ifstream file ("./data", ifstream::in);
if(file.is_open())
{
int i = 0;
while(!file.eof())
{
float wings, price;
string skipnl;
file >> wings;
file >> price;
data->emplace(wings, price);
getline(file, skipnl);
i++;
}
}
}