final project, Dynamic Programming. Need second set of eyes - c++

I feel really stupid coming to ask this question here today after bugging everyone yesteday on understanding the algorithm. But I am not looking at this thing straight anymore. Anyways, it is a knapsack probled, solved with memoization and dynamic progrmming. The problem is that the printout of my answers is not matching the requierements.
All I want is a second look at it and if someone can point me where I am wrong at.
Appreciated for all the help.
This is the ProfitHeader.h file
#ifndef PROFITHEADER_H_
#define PROFITHEADER_H_
#include <string>
#include <map>
#include <vector>
using namespace std;
namespace kproblem{
typedef int Money;
typedef int Labor;
struct Resources{
Money liquidity;
Labor officeWork;
Labor programmingWork;
Resources(Money li, Labor of, Labor pro) : liquidity(li), officeWork(of), programmingWork(pro){}
//operator -=
Resources & operator -=( const Resources &rhs ){
liquidity -=rhs.liquidity;
officeWork -=rhs.officeWork;
programmingWork -=rhs.programmingWork;
return *this;
}
//operator< Used to make sure that key elements Match. will not modify (this)
bool operator<(const Resources & rhs) const{
if(this->liquidity < rhs.liquidity)
return true;
else if(this->liquidity > rhs.liquidity)
return false;
else if(this->officeWork < rhs.officeWork)
return true;
else if(this->officeWork > rhs.officeWork)
return false;
//this is the iff conditional
else if(this->programmingWork < rhs.programmingWork)
return true;
else
return false;
}
};
//Global Operator-. This will not modify (this).
Resources operator-( const Resources & lhs, const Resources & rhs ){
return Resources(lhs.liquidity - rhs.liquidity,
lhs.officeWork - rhs.officeWork, lhs.programmingWork - rhs.programmingWork);
}
//This is the Project Struct. It should contain the resources and data from the file.
struct Project{
string name;
Resources resources;
Money profit;
Project(string n, Resources re, Money p) : name(n), resources(re), profit(p) {}
};
//Definition of the ValueMap
typedef map<pair<Resources, vector<Project>::size_type>, pair<Money, bool>> ValueMap;
}
#endif
This is my main.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include "ProfitHeader.h"
using namespace std;
using namespace kproblem;
//The following was provided to us on the program
class IO_Exception : public runtime_error
{
public:
IO_Exception(const string & message) : runtime_error(message) { }
};
void readProjects(vector<Project> & projects, const string & fileName)
{
ifstream infile(fileName.c_str());
if (!infile)
throw IO_Exception("Could not open " + fileName);
string oneLine;
unsigned int lineNum = 0;
while (getline(infile, oneLine))
{
istringstream st(oneLine);
lineNum++;
string name;
Money liquidity;
Labor officeWork;
Labor programmingWork;
Money profit;
st >> name;
st >> liquidity;
st >> officeWork;
st >> programmingWork;
st >> profit;
if (st.fail())
{
cerr << "Skipping line number " << lineNum << ": "
<< oneLine << endl;
continue;
}
string junk;
if (st >> junk)
{
cerr << "Skipping line number " << lineNum << ": "
<< oneLine << endl;
continue;
}
projects.push_back(Project(name, Resources(liquidity, officeWork, programmingWork), profit));
}
if (!infile.eof())
throw IO_Exception("Error reading from " + fileName);
}
//Class Best Profit.
//This class will calculate the best possible profit we can get.
Money bestProfit(const vector<Project> & projects, Resources res, ValueMap & valMap,int n){
//initialize the best 2 possible solutions.
Money best1;
Money best2;
Money map; // the map where ou answers are stored
// First check if we are not at the end of the projects
if(n == 0){
return 0;
}
//now we are going to check the best project possible.
//Check the subinstance if it was solved.
if(valMap.find(make_pair(res, n-1)) != valMap.end()){
map = valMap.find(make_pair(res, n-1))->second.first;
return map;
}//check if the subinstance is solved. if it is return the value.
best1 = bestProfit(projects, res, valMap, n-1);//first best possible solution
//check the resources for the last project only. Fopr the second best possible solution.
if(res.liquidity >= projects.at(n-1).resources.liquidity
&& res.officeWork >= projects.at(n-1).resources.officeWork
&& res.programmingWork >= projects.at(n-1).resources.programmingWork){// feasability Check.
//all the above are requiered as it is necessary to check for all of them when doing the calculations.
best2 = bestProfit(projects, res - projects[n-1].resources, valMap, n-1) + projects[n-1].profit;
}
else{
best2 = 0;
}
//after the whole check compare the results and store the best possible result in the map.
if(best1 >= best2){
valMap.insert(make_pair(make_pair(res, n), make_pair(best1,false)));
return best1;
}
else{
valMap.insert(make_pair(make_pair(res, n), make_pair(best2,true)));
return best2;
}
}
//reportBestProfit. This will call Best profit and help us print the final results.
void reportBestProfit(vector<Project> projects, Resources resources){
ValueMap valueMap;
//Variables for the total resources used.
Money liq = 0;
Money ow = 0;
Money pw = 0;
int n = 1000; //number of projects, put here for fast testing
Money bestP = bestProfit(projects, resources, valueMap, n);
//Iterate the valuemap and print the best projects available to us.
cout << "Selected Projects -" << endl;
for(int i= 1; i <= 1000; i++){
//if(valueMap.find(make_pair(resources, i-1)) == valueMap.end()){
if(valueMap.find(make_pair(resources, i))->second.second == true){
//if(valueMap.find(make_pair(resources, i))->second.first != valueMap.find(make_pair(resources, i-1))->second.first){
//cout << valueMap.find(make_pair(resources, i))->second.first; //money
//cout <<" "<< valueMap.find(make_pair(resources, i))->second.second; //boolean
cout << " " << projects.at(i-1).name << " " << projects.at(i-1).resources.liquidity <<" ";//projects
cout << projects.at(i-1).resources.officeWork << " " << projects.at(i-1).resources.programmingWork;
cout << " " << projects.at(i-1).profit << endl;//profit
//}
}
}
cout << "Total Resources Used -" << endl;
//Print the resources consumed.
for(int i= 1; i <= 1000; i++){
if(valueMap.find(make_pair(resources, i))->second.second == true){
liq += projects.at(i-1).resources.liquidity;
ow += projects.at(i-1).resources.officeWork;
pw += projects.at(i-1).resources.programmingWork;
}
}
cout << " " << "Liquidity: " << liq <<endl;
cout << " " << "Office Work: " << ow <<endl;
cout << " " << "Programming Work: " << pw <<endl;
//Print the total Profit.
cout << "Profit: " << bestP << endl;
system("PAUSE");
}
int main()
{
vector<Project> projects;
try
{
readProjects(projects, "Proj5Data.txt");
}
catch (const IO_Exception & ex)
{
cerr << "IO error from: " << ex.what() << endl;
return 1;
}
//these values can be changed for different analysis on projects.
Money liquidity = 200;
Labor officeWork = 450;
Labor programmingWork = 1000;
cout << "Available resources - " << endl
<< " Liquidity: " << liquidity << endl
<< " Office Work: " << officeWork << endl
<< " Programming Work: " << programmingWork << endl;
reportBestProfit(projects, Resources(liquidity, officeWork, programmingWork));
return 0;
}
The project file that contains the projects can be downloaded temporarily here:
https://rapidshare.com/files/459861869/Proj5Data.txt
my guess is the problem is on the valmap find, but I have tried all kinds of combinations and it does not work at all.
Finally this is the final printout I should be getting from this:
But instead I am getting all these other results, including some of the ones I need:
Again thank you for the one that can slap me in the head and say, you FOO, you shouldn't be doing this anymore :).

removing this would get rid of the leading numbers on the second part of the output
cout << valueMap.find(make_pair(resources, i))->second.first; //money
cout <<" "<< valueMap.find(make_pair(resources, i))->second.second; //boolean
cout << " "
the values you print at this point haven't been filtered by and ordered by which is why i think your printing these values
but you don't have code to print "The total resources used -" part

OK, so yes I do have an answer. Is now complete (after edit)
void reportBestProfit(vector<Project> projects, Resources resources){
ValueMap valueMap;
//Variables for the total resources used.
Money liq = 0;
Money ow = 0;
Money pw = 0;
vector<Project> result;
int n = 1000; //number of projects, put here for fast testing
Money bestP = bestProfit(projects, resources, valueMap, n);
//Iterate the valuemap and print the best projects available to us.
cout << "Selected Projects -" << endl;
// this loop just iterates through the values, it does not check the initial resources.
for(int i= 999; i > 0; i--){
//if(valueMap.find(make_pair(resources, i-1)) == valueMap.end()){
//check first If I still have resources available
if(resources.liquidity >=0 && resources.officeWork >= 0 && resources.programmingWork >= 0){
if(valueMap.find(make_pair(resources, i))->second.second == true){
//when I find the first true, I need to substract the resources of it from the base resources,
//to ask the question again.
resources.liquidity -= projects.at(i-1).resources.liquidity;
resources.officeWork -= projects.at(i-1).resources.officeWork;
resources.programmingWork -= projects.at(i-1).resources.programmingWork;
//Push the results into a vector for the printout
result.push_back(Project(projects.at(i-1).name,
Resources(projects.at(i-1).resources.liquidity,
projects.at(i-1).resources.officeWork,
projects.at(i-1).resources.programmingWork),
projects.at(i-1).profit));
//Also in one shot add together the resources used
liq += projects.at(i-1).resources.liquidity;
ow += projects.at(i-1).resources.officeWork;
pw += projects.at(i-1).resources.programmingWork;
}
}
}
//Print the saved vector in reverse order
for(int size = result.size(); size != 0; size--){
cout << " " << result.at(size -1).name;
cout << " " << result.at(size -1).resources.liquidity;
cout << " " << result.at(size -1).resources.officeWork;
cout << " " << result.at(size -1).resources.programmingWork;
cout << " " << result.at(size -1).profit << endl;
}
cout << "Total Resources Used -" << endl;
////Print the resources consumed.
cout << " " << "Liquidity: " << liq <<endl;
cout << " " << "Office Work: " << ow <<endl;
cout << " " << "Programming Work: " << pw <<endl;
//Print the total Profit.
cout << "Profit: " << bestP << endl;
system("PAUSE");
}
Basically I was not substracting the resources, so I was always having over resources, but once I did that viola! it works. Thank you guys for looking at it, I guess I just needed inspiration this morning.

Related

cargo transportation system we are not sure how to display the last part of our task

Here is our code for the task we are almost finishing just the last part we are stuck at
"Fastest: 3 trips (1 Van, 3 Mini-lorry, $645) "
we are not sure how to display the values in the bracket we only able to display 3 trips.
Is there a way to also display the values in the bracket stated as well?
we use
int min = *min_element(vTrips.begin(), vTrips.end());
cout << "Fastest: " << min << " trips" << endl;
but this only display the 3 trips.
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
#include<algorithm>
using namespace std;
class CTS //cargo transport system
{
int i;
int cargo, lorryprice, vanprice, lorrysize, vansize, allOps;
public:
void set_cargo(int);
void set_lorryprice(int);
void set_vanprice(int);
void set_lorrysize(int);
void set_vansize(int);
};
void CTS::set_cargo(int total_cargo) {
cargo = total_cargo;
}
void CTS::set_lorryprice(int lorryP) {
lorryprice = lorryP;
}
void CTS::set_vanprice(int vanP) {
vanprice = vanP;
}
void CTS::set_lorrysize(int lorryS) {
lorrysize = lorryS;
}
void CTS::set_vansize(int vanS)
{
vansize = vanS;
}
int main()
{
int cargo, lorryprice, vanprice, lorrysize, vansize, options, i, no_lorry, no_van, cost, trips;
ifstream infile;
infile.open("size.txt");
if (infile.is_open()) {
infile >> cargo;
infile >> lorryprice;
infile >> vanprice;
infile >> lorrysize;
infile >> vansize;
}
CTS run;
run.set_cargo(cargo);
run.set_lorryprice(lorryprice);
run.set_vanprice(vanprice);
run.set_lorrysize(lorrysize);
run.set_vansize(vansize);
infile.close();
options = (cargo / lorrysize) + 1;
no_lorry = (cargo / lorrysize);
no_van = (cargo / vansize) + 3;
if (cargo % lorrysize == 0) {
no_van = -3;
}
if (cargo % lorrysize != 0) {
no_van = ((cargo % lorrysize) / 10) - 3;
}
/*it = numbervan.begin();
for (auto ir = numbervan.rbegin(); ir != numbervan.rend(); ++ir) {
cout << *ir << endl;
}*/
vector<int> vCost, vVan, vTrips, vLorry;
vector <int>::iterator it;
for (i = 1; i < options + 1; i++)
{
int numberlorry = no_lorry;
cout << "Option " << i << ":" << endl;
cout << "Number of Mini-Lorries : " << no_lorry-- << endl;
if (no_van >= -3) {
no_van += 3;
}
cout << "Number of Vans : " << no_van << endl;
int numbervan = no_van;
if (numberlorry > numbervan) {
trips = numberlorry;
}
else {
trips = numbervan;
}
cout << "Trips Needed : " << trips << endl;
cost = (numberlorry * lorryprice) + (no_van * vanprice);
cout << "Total Cost : $" << cost << endl;
vCost.push_back(cost);
vLorry.push_back(numberlorry);
vVan.push_back(numbervan);
vTrips.push_back(trips);
}
int counter = vCost.size() - 1;
//std::vector<int>::reverse_iterator ir = vCost.rbegin();
for (i = 1; i < 4; i++) {
//cout << "Lowest #" << i << ": "<<cost<<endl;
cout << "Lowest #" << i << ": $" << vCost[counter] << "(" << vVan[counter] << " Vans, " << vLorry[counter] << " Mini-Lorry, " << vTrips[counter] << " Trips)" << endl;
counter--;
}
int min = *min_element(vTrips.begin(), vTrips.end()); // this line of code we figured out how to
cout << "Fastest: " << min << " trips" << endl; //display the number of trips using algorithm
return 0;
}
Your design is awkward; you create an instance of CTS run; and never use it.
Assuming that you do your calculations right, you need to know at what index you found min. If you store the iterator returned by min_element(), you can get an index by subtracting vTrips.begin() from it. Then the corresponding elements in your vCost, vLorry and vVan vectors will contain the data you want.
However, it would be easier if you define a struct containing your pre-calculated values, and push that into some vector. In that case, all related data is kept together.

vector<string> in a struct doesn't work properly

I declared a vector<string> and I cannot even compile it. I tried many ways but none of them worked.
I'm trying to write out the x.surname.push_back(word)[i] but it's definetly written wrongly and I have no idea how to write it properly and make it possible to compile.
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int number, i = 0;
string word;
struct donators {
vector<string> surname;
vector<int> amount;
} x;
cout << "How many donators do you want to register? " << endl;
cin >> number;
for (i = 0; i < number; i++) {
cout << "Surname: ";
cin >> word;
x.surname.push_back(word)[i];
cout << "Amount: ";
x.amount.push_back(i);
cin >> x.amount[i];
}
cout << "OUR GORGEUS DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] >= 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
}
else if (x.amount[i] < 10000) {
cout << "Lack of surnames!" << endl;
}
}
cout << "OUR CASUAL DONATORS: " << endl;
for (i = 0; i < number; i++) {
if (x.amount[i] < 10000) {
cout << "Surname: " << x.surname(word)[i];
cout << "Amount: " << x.amount[i] << endl;
} else if (x.amount[i] >= 10000) {
cout << "Lack of surnames!" << endl;
}
}
return 0;
}
And one more thing. How to make sentence "Lack of surnames!" to be written out once? In some cases, it is written out twice or more times what is redundant.
You are putting [i] at seemingly random places in your code. Such as in x.surname.push_back(word)[i];. Don't add things like this to your code if you're unsure about what they're doing.
The x.surname(word)[i] construct are also wrong. What's x.surname(word) supposed to be? This syntax is for function calls. surname, however, is not a function. It's a std::vector<std::string>. Just put x.surname[i] instead.
And one more thing. How to make sentence "Lack of surnames!" to be
written out once? In some cases, it is written out twice or more times
what is redundant.
That's because you write it for every donor that doesn't fit the criterion. Instead, keep track if any donor fits the criterion and only print it when none ends up fitting. You can do it like this:
bool HasGorgeousDonators = false;
And then in the loop:
if (x.amount[i] >= 10000)
{
cout << "Surname: " << x.surname[i];
cout << "Amount: " << x.amount[i] << endl;
HasGorgeousDonators = true;
}
And after the loop:
if (!HasGorgeousDonators)
cout << "Lack of surnames!" << endl;
Likewise for the other loop. Also, please consider the following Q&A:
Why is "using namespace std;" considered bad practice?
It seems like you are writing C with some C++ help functions. However C++ is a different language. Sure, it supports some C structures, but there's so much more.
Take a look at some of my suggestions for implementation and compare it to your code:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
template<typename T>
T ReadCin(std::string_view const& sv = "") {
T retVal;
if (!sv.empty()) std::cout << sv;
std::cin >> retVal;
return retVal;
}
class Donator {
private:
std::string surname{};
int amount{};
public:
constexpr bool IsGenerous() const noexcept { return amount >= 10000; }
void Read() noexcept {
surname = ReadCin<decltype(surname)>("Surname: ");
amount = ReadCin<decltype(amount)>("Amount: ");
}
friend std::ostream& operator<<(std::ostream& out, Donator const& donator) noexcept {
out << "Surname: " << donator.surname << ", " << "Amount: " << donator.amount;
return out;
}
};
int main() {
std::vector<Donator> donators(ReadCin<int>("How many donators do you want to register?\n"));
for (auto& donator : donators) donator.Read();
std::cout << "OUR GENEROUS DONATORS:\n";
std::copy_if(std::cbegin(donators), std::cend(donators), std::ostream_iterator<Donator>(std::cout, "\n"),
[](Donator const& donator) { return donator.IsGenerous(); });
std::cout << "OUR CASUAL DONATORS:\n";
for (auto const& donator : donators) if (!donator.IsGenerous()) std::cout << donator << '\n'; //alternative
}
I tried to include some of the possibilities using C++. I would really advise you to get a good book on C++.

Error Variable is Protected

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
void armySkirmish();
void battleOutcome();
string commander = "";
int numberOfHumans = 0;
int numberOfZombies = 0;
class ArmyValues
{
protected:
double attackPower;
double defensePower;
double healthPoints;
public:
void setAttackPower(double a)
{
attackPower = a;
}
void setDefensePower(double d)
{
defensePower = d;
}
void setHealthPoints(double h)
{
healthPoints = h * (defensePower * .1);
}
};
class Zombies: public ArmyValues
{
};
class Humans: public ArmyValues
{
};
int main(int argc, char ** argv)
{
cout << "Input Commander's Name: " << endl;
cin >> commander;
cout << "Enter Number of Human Warriors: " << endl;
cin >> numberOfHumans;
cout << "Enter Number of Zombie Warriors: " << endl;
cin >> numberOfZombies;
armySkirmish();
battleOutcome();
return 0;
}
void armySkirmish()
{
cout << "\nThe Humans tense as the sound of the undead shuffle towards them." << endl;
cout << commander << " shuffles forward with a determined look." << endl;
cout << "The undead form up into ranks and growl a war chant!" << endl;
cout << commander <<" shouts, CHARGE!!!" << endl;
cout << endl;
cout << "Warriors from both sides blitz across the field!" << endl;
cout << endl;
cout << "*The Carnage has begun!*" << endl;
cout << "*Steal, Sparks, and Flesh flies" << endl;
}
void battleOutcome()
{
int zombieLives = numberOfZombies;
int humanLives = numberOfHumans;
int randomNumber = 0;
int humanDeath = 0;
int zombieDeath = 0;
double newHumanLife = 0;
double newZombieLife = 0;
Zombies zombieBattleData;
Humans humanBattleData;
srand(time(NULL));
zombieBattleData.setAttackPower(20.0);
humanBattleData.setAttackPower(35.0);
zombieBattleData.setDefensePower(15.0);
humanBattleData.setDefensePower(20.0);
zombieBattleData.setHealthPoints(150.0);
humanBattleData.setHealthPoints(300.0);
while(zombieLives && humanLives > 0)
{
randomNumber = 1+(rand()%10);
if(randomNumber < 6)
{
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
if(newHumanLife <= 0)
{
humanLives--;
humanDeath++;
}
}else
{
newZombieLife = zombieBattleData.healthPoints - humanBattleData.attackPower;
if(newZombieLife <= 0)
{
zombieLives--;
zombieDeath++;
}
}
}
if(zombieLives <= 0)
{
cout << "Humans have emerged victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}else if(humanLives <= 0)
{
cout << "Zombies have emerges victorious!" << endl;
cout << "Human Deaths: " << humanDeath << "Zombie Deaths: " << zombieDeath << endl;
}
I know the code wont run properly as of now. What I was doing was a test run to make sure I was receiving no errors. The two errors I'm getting are:
armySimulatorMain.cpp:25:10: error: 'double ArmyValues::healthPoints' is protected
armySimulatorMain.cpp:115:67: error: within this context.
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
This is the case for Attack Power and Health Power however, Defense power is clearing the errors. i don't understand why they are getting flagged. I'm changing the variable through the public function so shouldn't this be allowed?
Also, I'm calling three variables outside of all functions because they are being used by multiple functions. How can I plug those variables somewhere I don't like that they are floating freely above everything?
Thanks guys I can't believe I forgot about getters... Anyway the code runs now much appreciated I'll make sure to remember this time xD
It's not complaining about the line where you set the values; as you say, that uses a public function. But here, you try to read the protected member variables:
newHumanLife = humanBattleData.healthPoints - zombieBattleData.attackPower;
You only try to read two variables, and those are the ones it complains about.
You'll need a public getter function to read the values.
You need to do something like:
public:
double gethealthPoints()
{
return healthPoints;
}
because attackPower, defensePower, healthPoints are all protected, so if you want to access to any of them you need a getter, otherwise you will always receive an protect error

Trouble finding differential between two items in C++

Let me preface this by saying I'm still extremely new to C++ and want to keep things as simple as possible. I'm also pretty terrible at math.
Mostly, I'm looking to see if anyone can help my code so it will always give the correct result. I've mostly got it to do what I want, except in one scenario.
My code is trying to find out how many packages of hotdog weiners and how many packages of hotdog buns someone has purchased. Then it tells the user how many hotdogs they can make from that as well as how much leftover weiners or buns they would have. Assuming a package of weiners contains 12 and a package of buns contains 8, this is what I have come up with so far:
#include <iostream>
#include <cmath>
using namespace std;
void hotdog(int a, int b){ //a = weiner packages, b = bun packages
int weiners = 12 * a;
int buns = 8 * b;
int total = (weiners + buns) - (weiners - buns);
int leftOverWeiners = total % weiners;
int leftOverBuns = total % buns;
int totalHotDogs = total / 2;
cout << "You can make " << totalHotDogs << " hotdogs!" << endl;
if (leftOverWeiners > 0){
cout << "You have " << leftOverWeiners << " weiners left over though." << endl;
}else if (leftOverBuns > 0){
cout << "You have " << leftOverBuns << " buns left over though." << endl;
}
}
int main(){
int a;
int b;
cout << "Let's see how many hotdogs you can make!" << endl;
cout << "How many weiner packages did you purchase?: ";
cin >> a;
cout << "How many bun packages did you purchase?: ";
cin >> b;
hotdog(a, b);
return 0;
}
With this, I can always get the correct answer if the ratio of buns to weiners is the same or if there are more weiners than buns.
Because of the way I've set up total and/or leftOverBuns (lines 9, 11), I will never get the correct answer to how many left over buns there will be. I know there must be a simpler way to do this if not a way to modify my current code but I am stumped.
I know I left virtually zero notation, so if you would like some please let me know!
You're making it too complicated. Try this:
if(weiners > buns)
{
cout << "You can make " << buns << " hotdogs!" << endl;
cout << "with " << weiners-buns << " weiners left over" << endl;
return;
}
cout << "You can make " << weiners << " hotdogs!" << endl;
if(buns > weiners)
{
cout << "with " << buns-weiners << " buns left over" << endl;
}
The smaller of {buns, weiners} is the number of hot dogs, and the if-then blocks determine whether the function will report leftover buns or weiners.
#include <iostream>
void hotdog( int weinerspackages, int bunspackages ){
const int weinersPerPackage = 12;
const int bunsPerPackage = 8;
const int totalweiners = weinerspackages * weinersPerPackage;
const int totalbuns = bunspackages * bunsPerPackage;
int leftoverweiners = 0;
int leftoverbuns = 0;
int amountOfHotdogs = 0;
if( totalweiners > totalbuns ){
leftoverweiners = totalweiners - totalbuns;
amountOfHotdogs = totalbuns;
leftoverbuns = 0;
}
else if( totalbuns > totalweiners ){
leftoverbuns = totalbuns - totalweiners;
amountOfHotdogs = totalweiners;
leftoverweiners = 0;
}
else{
amountOfHotdogs = totalweiners;
leftoverweiners = 0;
leftoverbuns = 0;
}
std::cout << "You can make: " << amountOfHotdogs << " Hotdogs" << std::endl;
std::cout << "Leftover Weiners: " << leftoverweiners << " || Leftover Buns: " << leftoverbuns << std::endl;
}
int main(){
int PackagesW = 8;
int PackagesB = 12;
hotdog( PackagesW, PackagesB );
system("pause");
return 0;
}
Note: It is possible to do this with less variables, I declared this amount of variables to make it easier to understand what the numbers represent.
Assuming that it only takes one of each to make a hotdog, you can find which of the ingredients you have the least, and the amount of hotdogs you can make will be limited by the amount of that ingredient, that is why amountOfHotdogs takes the value of the lesser one. If both are equal in amount, then amountOfHotdogs can take the amount of either.
Only the ingredient with the larger amount will have leftovers, therefore leftoverweiners = totalweiners - totalbuns; when totalweiners > totalbuns and vice-versa.

Monty Hall Project

I am currently in the process of writing a C++ Monty Hall Problem Simulation and have run into some trouble. The error I keep getting is:
source.cpp(23): error C4700: uninitialized local variable 'doorReveal' used
source.cpp(25): error C4700: uninitialized local variable 'doorSwitch' used
source.cpp(52): error C4700: uninitialized local variable 'stayWin' used
source.cpp(56): error C4700: uninitialized local variable 'switchWin' used
I can't seem to figure out what is wrong. The project is supposed to simulate the wins by first staying with the original door choice on the first 100 tries and then switching when door is revealed on the next 100 tries. Thank you all for your help in advance.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
int doorChoice;
int prizeDoor;
int doorReveal;
int doorSwitch;
int count;
int switchWin;
int stayWin;
srand((unsigned int) time(0));
for (count = 0; count <= 200; count++)
{
prizeDoor = (rand() % 3) + 1;
doorChoice = (rand() % 3) + 1;
cout << "The prize door is door number " << prizeDoor << " ." << endl;
cout << "The door the contestant chose was door " << doorChoice << endl;
doorReveal != prizeDoor || doorChoice;
cout << "The host revealed door number " << doorReveal << " ." << endl;
doorSwitch != doorChoice || doorReveal;
while (count < 101)
{
if (doorChoice == prizeDoor)
{
cout << "Great Job! You won!" << endl;
}
else {
cout << "Not this time!" << endl;
}
}
while (count < 201)
{
if (doorSwitch == prizeDoor)
{
cout << "You switched and won!" << endl;
}
else {
cout << "You switched and lost!" << endl;
}
}
if (doorChoice == prizeDoor)
{
stayWin++;
}
if (doorSwitch == prizeDoor)
{
switchWin++;
}
count++;
}
cout << "Your win percentage when staying was " << stayWin << "%!" << endl;
cout << "Your win percentage when switching was " << switchWin << "%!" << endl;
return 0;
}
Problem 1: operator!=
operator != doesn't do what you think it does.
Did you mean
doorReveal = !(prizeDoor || doorChoice);
cout << "The host revealed door number " << doorReveal << " ." << endl;
doorSwitch = (doorChoice || doorReveal);
I sense another logic issue in determining the doorReveal. I'll have to think about that later.Edit: see problem 5
Problem 2: while
There's also a problem with the while loops:
while(count < 101)
// ...
while(count < 201)
They're infinite loops, because count isn't increased during the loop. I think you meant if there, instead of while.
Problem 3: Initiliazing switchWin and stayWin
These variables are only being incremented. Like #KonradRudolph suggested,
declare your variables where they are first needed
initialize them
while you're at it, mark them const as appropriate
Problem 4: rand()%3 is biased
You should probably use a uniform distribution.
See
http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx
I'll leave using std::uniform_int_distribution as an exercise for the reader here, as it is likely beyond the scope of your course. Remember to use it though, in any real life code.
Problem 5: Fix your door 'derivation'
Booleans aren't sets. Even if they were, you'd be stuck to binary sets. I propose the following model:
enum doors { door1 = 1, door2 = 2, door3 = 4, any = door1|door2|door3 };
so you can say:
doors const doorReveal = doors(~(prizeDoor | doorChoice) & any);
doors const doorSwitch = doors(~(doorChoice | doorReveal) & any);
Fixing that results in a program that appears to work:
#include <iostream>
#include <time.h>
using namespace std;
enum doors { door1 = 1, door2 = 2, door3 = 4, any = door1|door2|door3 };
static inline std::ostream& operator<<(std::ostream& os, doors val) {
switch(val) {
case door1: return os << "door #1";
case door2: return os << "door #2";
case door3: return os << "door #3";
case any: return os << "any door";
}
return os << "OOPS";
}
int main()
{
unsigned switchWin = 0;
unsigned stayWin = 0;
srand((unsigned int) time(0));
for(int count = 0; count <= 200; count++)
{
doors const prizeDoor = doors(1 << rand() / ( RAND_MAX / 3 ));
doors const doorChoice = doors(1 << rand() / ( RAND_MAX / 3 ));
cout << "The prize door is door number " << prizeDoor << " ." << endl;
cout << "The door the contestant chose was door " << doorChoice << endl;
doors const doorReveal = doors(~(prizeDoor | doorChoice) & any);
doors const doorSwitch = doors(~(doorChoice | doorReveal) & any);
cout << "The host revealed door number " << doorReveal << " ." << endl;
if(count < 101)
{
if(doorChoice == prizeDoor)
{
cout << "Great Job! You won!" << endl;
}
else
{
cout << "Not this time!" << endl;
}
};
if(count < 201)
{
if(doorSwitch == prizeDoor)
{
cout << "You switched and won!" << endl;
}
else
{
cout << "You switched and lost!" << endl;
}
};
if(doorChoice == prizeDoor)
{
stayWin++;
}
if(doorSwitch == prizeDoor)
{
switchWin++;
};
count++;
}
cout << "Your win percentage when staying was " << stayWin << "%!" << endl;
cout << "Your win percentage when switching was " << switchWin << "%!" << endl;
return 0;
}