Okay I don't know if this is even a valid question but I'm posting here because I don't know where else to turn with this. I just started studying programming this half year at a university and we just had the final exam, which I failed. Basically, there were 4 questions, and while the second one looked easy it was actually tricky and I just can't figure out how it should have been done.
Basically the problem is: There is a bank, and when people log in to do business, you need to write a program that records the time they logged in (0-24h), the minutes (0-59), the type of transaction they choose (1 for logging in with a bank card, -1 for logging out with the same bank card, 2 for money input into the account, -2 for withdrawal) and finally either their bank acc number (if they pressed 1 or -1 previously), or the amount they are withdrawing or putting in (if they chose 2 or -2).
Basically here is how we had to do it:
int n; //size of the array or number of ppl who transacted that day
cin >> n;
int bank[n][4];
for (int i=0; i<n; ++i)
{
cin >> bank[n][0];
cin >> bank[n][1];
cin >> bank[n][2];
cin >> bank[n][3];
}
This fills up all the info and then,
basically a sample input looked like this for 4 customers during the day:
11 40 1 458965
12 20 2 6000
15 40 -1 458965
16 25 -2 18000
Here is the part I could not solve:
Our test asked us: How many people were logged in from 12 o clock to 13:00 oclock?
At first I did
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
}
cout << count;
The problem with this, is that it does not account for people who log in before 12 with a 1 in the third column, but log out at later than 1 oclock with a -1. Which means they were still logged in from 12 to 1pm.
so then I did
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
if (bank[i][2]==-1)
{
count=count+1;
}
}
cout << count;
but then I realized that this would count some logins twice, because if they logged in at 12 with a 1 for example, then logged out at 3 o clock with a -1 it would count that one person twice.
It also asked us what is the longest period that any person was logged in, assuming the bank kicks everyone off at 24:00. I honestly am not even sure how to even begin that one.
EDIT: SORRY i edited a bunch of stuff to make it clearer and correct code. I'm not too good at this yet forgive my mistakes
I didn’t know how the bank system works. So I made a minimal example for you.
I also didn't know if you used classes before, so I wrote it without.
I cleaned your code a bit:
//Use these enums
enum action { action_login = 1, action_logout = -1, action_input = 2, action_output = -2 };
enum information {information_time_h, information_time_m, information_action, information_bankNumber};
//Place this in the function you have
int peapelToInput = 0; //size of the array or number of ppl who transacted that day
cin >> peapelToInput;
for (int i=0; i<peapelToInput; ++i)
{
//Maby add error handeling? When some one inputs a 'a', it won't do what you want.
cin bank[i][information_time_h];
cin bank[i][information_time_m];
cin bank[i][information_action];
cin bank[i][information_bankNumber];
}
As you can see, I made the code cleaner by adding enums. This makes developing a lot easier.
The login code:
int count=0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if (bank[i][information_time_h] == 12 && bank[i][information_action] == action_login)
count++;
}
cout << "logins at 12:00 - 12:59:" << count << endl;
You can do 2 checks in 1 if, I increment count when they were logedin from 12:00 - 12:59. Do you need exclude people that were loggedout?
The longest time code:
//A function to search when he is logedout
int findLogoutIndex(int start, int accountNumber, XXX bank)
{
int bankSize = bank.size();
for (int i=start; i < bankSize; ++i)
if( bank[i][information_action] == action_logout && bank[i][information_bankNumber] == accountNumber)
return i;
return -1; //Handle this error
}
//And how it workes
int logenst = 0;
int indexLongest = 0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if( bank[i][information_action] != action_login )
continue;
int logoutIndex = findLogoutIndex(i,bank[i][information_bankNumber],bank);
//check if logoutIndex is not -1, or handle the error on an other way.
int loginTimeHour = bank[logoutIndex][information_time_h] - bank[i][information_time_h];
int loginTimeMinute = bank[logoutIndex][information_time_m] - bank[i][information_time_m];
int loginTime = (loginTimeHour * 100) + loginTimeMinute;
if( logenst < loginTime)
{
logenst = loginTime;
indexLongest = i;
}
}
cout << "longest is: H:" << bank[indexLongest][information_time_h] << " M: " << bank[indexLongest][information_time_m] << endl;
You don't need to keep the time format, this way makes comparing a lot easier. Just save the longest login time and the index number of it. That way you can easily access all the data you want.
I didn't take the time to write "good code". But you asked how it can be done, I guess this is good enough to understand it?
I didn't test the code and wrote it in Notepad. So I don't know if it will compile.
The first thing that you need to know is what the questions are actually asking. In the first case, How many people were logged in from 12 o clock to 1 oclock? can mean multiple things. It could mean how many people were logged in during the whole period or how many people were logged in at any given time between those two hours. The difference is whether someone that logs in at 12:15 and logs out at 12:30 is counted or not. The second question is calculating the longest period someone was logged in, and that can be done at the same time.
One possible approach would be managing a lookup table from user id to login times. You read the input linearly, whenever someone logs in you add an entry (acct, time) into the table. When they log out you lookup the account number and calculate the difference of times. If the difference is greater than the maximum you store the new maximum.
For the first question, at 12 you can create a set of the people that was logged in from that lookup table. Whenever someone logs out between that time and 1 you find whether the person was in the set and you remove it if so. When you find the first operation after 1, the set contains the account numbers of all the people that was logged in for the whole period from 12 to 1.
If the question was getting all people that was logged at any time in the period, instead of removing from the set those users that log out before 1, you need to include new users that log in inside the period. At the end of the period the set contains all users that were logged in at any time within the period.
You only need to perform a single pass over the input data which means that you don't even need to store all of the transactions in memory, only the map/set required above. The overall cost of the operation is O(n log n) on the number of operations. (Disclaimer: I haven't done the math, this is a hunch :))
Haven't tested this. Nevertheless, the process followed should be correct.
I'm sure this can still be optimized in terms of execution speed.
Also, I assume by time 12 you mean 12:00 and by time 1 you mean 13:00.
int main()
{
int answer = 0;
// For each transaction
for ( int i = 0; i < count; i++ ) {
// If logged in before 12:00
// bank[i][2] > 0 tells you user logged in.
if ( bank[i][0] < 12 && bank[i][2] > 0 ) {
// Loop through each following transaction.
for ( int j = i + 1; j < count; j++ ) {
// If logged out after 13:00
if ( bank[j][0] > 13 && bank[j][2] < 0 ) {
// Now to check if it was the same user who logged in earlier - how?:
// Only way to differentiate is by comparing the transaction amounts and types.
if ( (bank[i][3] == bank[j][3]) && (bank[i][2] == -1*bank[j][2]) ) { // log-in code = -1 * log-out code.
answer++; // Number of transactions that spanned from before 12:00 till after 13:00.
// Remember, a single person can't have multiple log-ins at the same time. ( assumption )
}
}
}
}
}
}
Related
I was given an assignment in which the head of a top-secret organization, collecting statistics on retired agents
There are several secret agencies that employ spies. The time has come for the agencies to retire their employees
The given task:
The organization itself consists of 2 structures.
Agency which includes string-title, int-min_mission, int-agent_count and Spy* agents
Spy with the values name, string-speciality, int-completed_missions and bool-is_private.
I would like to point out that spies have only 3 specialty categories ("Diplomacy", "SpecOps", "DarkMistery")
Job Purpose: It is necessary to find an agency in which the maximum number of agents have been released.
In order to send them to resign the agency must check a few punuts, after surpassing which, its release from the position is accepted.
These rules are as follows:
His number of missions completed must exceed the minimum that his agency has set. If it is less, the agent cannot release him.
If the agent's speciality is "SpecOps", his minimum number of missions is 2 less than the others.
If an agent's speciality is "DarkMistery", his minimum number of missions is twice that of the others.
If the agent is Private, (that is, if the logical type is_private is == 1), then the agent will never be released
The input to test:
3
"For Angency - 1'st is Agency's name, 2'nd is min_number limit and 3'rd is number of agents" //
"For spies - 1'st is name, 2'nd is his\her speciality and 3'rd is completed missions"
BloodDragonfly 5 6
Jagternaut Diplomacy 7 0
Ditablo DarkMistery 6 0
Sartuman Diplomacy 3 1
Coltosus SpecOps 1 0
Samtanta DarkMistery 11 0
Tantos SpecOps 4 1
GoldenNose 6 4
Smith SpecOps 8 1
Smity DarkMistery 11 0
Smitens Diplomacy 5 0
Smaut DarkMistery 16 0
Lucaduca 10 5
Mario SpecOps 4 0
Puerrio Diplomacy 9 0
Luchio Diplomacy 11 1
Julietio Diplomacy 14 1
Bob DarkMistery 35 1
The value that should be displayed on the monitor OR Output:
Lucaduca
In short, I wrote a command that sorts out which agents can be released.
But I have forgotten how to remove the agents in the array that did pass the check, so that the size of the array changes.
(ignore the variable -> sum)
Here is my code.
#include "iostream"
#include "string"
using namespace std;
struct Spy { //The Spy structure
string name;
string speciality;
int missions;
bool is_private;
};
struct Agency { //The agency structure
string title;
int min_missions;
int agentCount;
Spy* agnt;
};
istream& operator >> (istream& is, Spy& sp) { //The operator to enter the values of spy
is >> sp.name >> sp.speciality >> sp.missions >> sp.is_private;
return is;
}
istream& operator >> (istream& is, Agency& agc) {//To enter the values of Agency
is >> agc.title >> agc.min_missions >> agc.agentCount;
return is;
}
int main() {
int N; cout << "Enter the number of agencies: \n";
cin >> N; //
Agency* agc = new Agency[N];
for (int i = 0; i < N; ++i) { //Creating a loop for the Agency struct, which would store the values of an individual agency
cin >> agc[i];
agc[i].agnt = new Spy[agc[i].agentCount];
for (int j = 0; j < agc[i].agentCount; ++j) { //This is for the struct Spy that will be stored inside the agentCount
cin >> agc[i].agnt[j];
}
}
for (int i = 0; i < N; ++i) {
int sum = 0;
int count = 0;
for (int j = 0; j < agc[i].agentCount; ++j) {
if (agc[i].agnt[j].is_private) { //Сonditional operator to check whether the agent is private or not
continue;
}
else {
if (agc[i].agnt[j].speciality == "DarkMistery") {//To check the speciality of agent
count = (agc[i].min_missions * 2);//If a spy's specialization is DarkMistery,
// he will get double the minimum number of missions than others
}
else if (agc[i].agnt[j].speciality == "SpecOps") {//If a spy's specialization is SpecOps,
count = (agc[i].min_missions - 2); //he/she will get 2 fewer mission than the others
}
else { //f a spy's specialization belongs to the third category
//Nothing will change for him/her
count = agc[i].min_missions;
}
if (agc[i].agnt[j].missions > count) {
sum++;
} else {
continue;
}
}
}
}
}
I tried to identify, through sum, the agency with the maximum number of non-exempt agents. But it will update every time it passes through the next agency.
I tried to use the delete command to delete the spy value, but I don't know how to use it on two-dimensional structures
I expect to see a change in the array agc[i].agentCount
so that it changes its size is dynamic if it is appropriate for this code of course.
If you only want to keep track of the number of agents an agency should release, you are almost done:
You could use a map from agency names to number of agents to be released.
Then, in your last two nested loops:
Before the inner loop, you reset a counter of agents to be released.
With each iteration of that inner loop, you update that counter.
After the inner loop, you insert a new element in the map, namely the name of the agency and the number of agents to be released.
The code below does that, although I'm afraid to say that the output is different than the expected (BloodDragonfly instead of Lucaduca). That may have to do with the input data or with the algorithm to decide if an agent has to be released.
[Demo]
using map_of_agents_to_be_released_per_agency_t = std::unordered_map<std::string, int>;
map_of_agents_to_be_released_per_agency_t agents_to_be_released{};
for (int i = 0; i < no_of_agencies; ++i) {
auto& agency{ agencies[i] };
int no_of_agents_to_be_released = 0;
for (int j = 0; j < agency.agent_count; ++j) {
auto& agent{ agency.agents[j] };
if (not agent.is_private) {
if (agent.speciality == "DarkMistery") {
if (agent.missions > agency.min_missions * 2) {
no_of_agents_to_be_released++;
}
} else if (agent.speciality == "SpecOps") {
if (agent.missions > agency.min_missions - 2) {
no_of_agents_to_be_released++;
}
} else if (agent.speciality == "Diplomacy") {
if (agent.missions > agency.min_missions) {
no_of_agents_to_be_released++;
}
}
}
}
agents_to_be_released.insert({agency.title, no_of_agents_to_be_released});
}
fmt::print("Agents to be released: {}\n", agents_to_be_released);
fmt::print("Agency with more agents to be released: {}\n",
std::ranges::max_element(
agents_to_be_released,
std::less<>{},
&map_of_agents_to_be_released_per_agency_t::value_type::second
)->first);
// Outputs:
//
// Agents to be released: {"Lucaduca": 0, "GoldenNose": 1, "BloodDragonfly": 2}
// Agency with more agents to be released: BloodDragonfly
This is the problem I am referring to. In quick summary:
Input: An integer time T; the time in minutes in which a bank closes and a set of pairs c and t that denotes the amount of cash (integer) this person carries and the time in minutes from now after which person leaves if not served. It takes one minute to serve a person and you must begin serving a person at time t at the latest.
Output: Maximum amount of money that can be collected within closing time.
My approach was this: place all the people in a map that maps money to time. I sort this map by money. I then make a queue-like structure where I take the person with the most money and place him/her as far back as possible. If the spot is occupied, then I move forward until I find a spot. If I can't then I just don't add the person.
Below is my helper function to determine whether or not I can insert a person.
// returns index where we can insert, otherwise -1
int canInsert(bool* queue, int timeToInsert) {
if (!queue[timeToInsert]) {
return timeToInsert;
} else {
int index = timeToInsert-1;
while (index >= 0) {
if (!queue[index]) {
return index;
} else {
index--;
}
}
return -1;
}
}
Here is the main driver function:
// moneyToTime is a map that maps a person's money to the time value
int Bank(int T, map<int, int> moneyToTime) {
int answer = 0;
bool queue[47] = {0};
for (map<int,int>::reverse_iterator i = moneyToTime.rbegin(); i != moneyToTime.rend(); i++) {
if (T > 0) {
// try to insert. If we can, then add to sum. Otherwise, don't.
int potentialIndex = canInsert(queue, i->second);
if (potentialIndex != -1) {
queue[potentialIndex] = 1;
answer += i->first;
T--;
}
} else {
break;
}
}
return answer;
}
Logically, this makes sense to me and it is passing almost all the test cases. There are a couple that are failing; I can not see what they are. The test case errors are in fact indicating wrong answer, as opposed to bad runtime errors. Can someone help me see the fallacy in my approach?
You don't show how you build the moneyToTime but anyway it looks like map<int, int> is a wrong type for that. Imagine you have many people with the same amount of money and different timings. How would you represent then in your moneyToTime?
If my theory is correct, an example like this should break your solution:
3 3
2000 2
2000 1
500 2
Obviously the best sum is 4000 = 2000 + 2000. I suspect you get only 2500.
I think the best sum for the TC is 4500,
3 3
2000 2
2000 1
500 2
{money, time}
{2000,0} | {2000,1} | {500,2}
Hi I am having trouble implementing a striping algorithm. I am also having a problem loading 30000 records in one vector, I tried this, but it is not working.
The program should declare variables to store ONE RECORD at a time. It should read a record and process it then read another record, and so on. Each process should ignore records that "belong" to another process. This can be done by keeping track of the record count and determining if the current record should be processed or ignored. For example, if there are 4 processes (numProcs = 4) process 0 should work on records 0, 4, 8, 12, ... (assuming we count from 0) and ignore all the other records in between.`
Residence res;
int numProcs = 4;
int linesNum = 0;
int recCount = 0;
int count = 0;
while(count <= numProcs)
{
while(!residenceFile.eof())
{
++recCount;
//distancess.push_back(populate_distancesVector(res,foodbankData));
if(recCount % processIS == linesNum)
{
residenceFile >> res.x >>res.y;
distancess.push_back(populate_distancesVector(res,foodbankData));
}
++linesNum;
}
++count;
}
Update the code
Residence res;
int numProcs = 1;
int recCount = 0;
while(!residenceFile.eof())
{
residenceFile >> res.x >>res.y;
//distancess.push_back(populate_distancesVector(res,foodbankData));
if ( recCount == processId)//process id
{
distancess.push_back(populate_distancesVector(res,foodbankData));
}
++recCount;
if(recCount == processId )
recCount = 0;
}
update sudo code
while(!residenceFile.eof())
{
residenceFile >> res.x >>res.y;
if ( recCount % numProcs == numLines)
{
distancess.push_back(populate_distancesVector(res,foodbankData));
}
else
++numLines
++recCount
}
You have tagged your post with MPI, but I don't see any place where you are checking a processor ID to see which record it should process.
Pseudocode for a solution to what I think you're asking:
While(there are more records){
If record count % numProcs == myID
ProcessRecord
else
Increment file stream pointer forward one record without processing
Increment Record Count
}
If you know the # of records you will be processing beforehand, then you can come up with a cleverer solution to move the filestream pointer ahead by numprocs records until that # is reached or surpassed.
A process that will act on records 0 and 4 must still read records 1, 2 and 3 (in order to get to 4).
Also, while(!residenceFile.eof()) isn't a good way to iterate through a file; it will read one round past the end. Do something like while(residenceFile >> res.x >>res.y) instead.
As for making a vector that contains 30,000 records, it sounds like a memory limitation. Are you sure you need that many in memory at once?
EDIT:
Look carefully at the updated code. If the process ID (numProcs) is zero, the process will act on the first record and no other; if it is something else, it will act on none of them.
EDIT:
Alas, I do not know Arabic. I will try to explain clearly in English.
You must learn a simple technique, before you attempt a difficult technique. If you guess at the algorithm, you will fail.
First, write a loop that iterates {0,1,2,3,...} and prints out all of the numbers:
int i=0;
while(i<10)
{
cout << i << endl;
++i;
}
Understand this before going farther. Then write a loop that iterates the same way, but prints out only {0,4,8,...}:
int i=0;
while(i<10)
{
if(i%4==0)
cout << i << endl;
++i;
}
Understand this before going farther. Then write a loop that prints out only {1,5,9,...}. Then write a loop that reads the file, and reports on every record. Then combine that with the logic from the previous exercise, and report on only one record out of every four.
Start with something small and simple. Add complexity in small measures. Develop new techniques in isolation. Test every step. Never add to code that doesn't work. This is the way to write code that works.
I'm trying to answer this problem as an exercise:
here are set of coins of {50,25,10,5,1} cents in a box.Write a program to find the number of ways a 1 dollar can be created by grouping the coins.
My solution involves making a tree with each edge having one of the values above. Each node would then hold a sum of the coins. I could then populate this tree and look for leaves that add up to 100. So here is my code
class TrieNode
{
public:
TrieNode(TrieNode* Parent=NULL,int sum=0,TrieNode* FirstChild=NULL,int children=0, bool key =false )
:pParent(Parent),pChild(FirstChild),isKey(key),Sum(sum),NoChildren(children)
{
if(Sum==100)
isKey=true;
}
void SetChildren(int children)
{
pChild = new TrieNode[children]();
NoChildren=children;
}
~TrieNode(void);
//pointers
TrieNode* pParent;
TrieNode* pChild;
int NoChildren;
bool isKey;
int Sum;
};
void Populate(TrieNode* Root, int coins[],int size)
{
//Set children
Root->SetChildren(size);
//add children
for(int i=0;i<size;i++)
{
TrieNode* child = &Root->pChild[0];
int c = Root->Sum+coins[i];
if(c<=100)
{
child = new TrieNode(Root,c);
if(!child->isKey) //recursively populate if not a key
Populate(child,coins,size);
}
else
child = NULL;
}
}
int getNumKeys(TrieNode* Root)
{
int keys=0;
if(Root == NULL)
return 0;
//increment keys if this is a key
if(Root->isKey)
keys++;
for(int i=0; i<Root->NoChildren;i++)
{
keys+= getNumKeys(&Root->pChild[i]);
}
return keys;
}
int _tmain(int argc, _TCHAR* argv[])
{
TrieNode* RootNode = new TrieNode(NULL,0);
int coins[] = {50,25,10,5,1};
int size = 5;
Populate(RootNode,coins,size);
int combos = getNumKeys(RootNode);
printf("%i",combos);
return 0;
}
The problem is that the tree is so huge that after a few seconds the program crashes. I'm running this on a windows 7, quad core, with 8gb ram. A rough calculation tells me I should have enough memory.
Are my calculations incorrect?
Does the OS limit how much memory I have access to?
Can I fix it while still using this solution?
All feedback is appreciated. Thanks.
Edit1:
I have verified that the above approach is wrong. By trying to build a tree with a set of only 1 coin.
coins[] = {1};
I found that the algorithm still failed.
After reading the post from Lenik and from João Menighin
I came up with this solution that ties both Ideas together to make a recursive solution
which takes any sized array
//N is the total the coins have to amount to
int getComobs(int coins[], int size,int N)
{
//write base cases
//if array empty | coin value is zero or N is zero
if(size==0 || coins[0]==0 ||N==0)
return 0;
int thisCoin = coins[0];
int atMost = N / thisCoin ;
//if only 1 coin denomination
if(size==1)
{
//if all coins fit in N
if(N%thisCoin==0)
return 1;
else
return 0;
}
int combos =0;
//write recursion
for(int denomination =0; denomination<atMost;denomination++)
{
coins++;//reduce array ptr
combos+= getComobs(coins, size-1,N-denomination*thisCoin);
coins--;//increment array ptr
}
return combos;
}
Thanks for all the feedback
Tree solution is totally wrong for this problem. It's like catching 10e6 tigers and then let go all of them but one, just because you need a single tiger. Very time and memory consuming -- 99.999% of your nodes are useless and should be ignored in the first place.
Here's another approach:
notice your cannot make a dollar to contain more than two 50 cents
notice again your cannot make a dollar to contain more than four 25 cent coins
notice... (you get the idea?)
Then your solution is simple:
for( int fifty=0; fifty<3; fifty++) {
for( int quarters=0; quarters<5; quarters++) {
for( int dimes=0; dimes<11; dimes++) {
for( int nickels=0; nickels<21; nickels++) {
int sum = fifty * 50 + quarters * 25 + dimes * 10 + nickels * 5;
if( sum <= 100 ) counter++; // here's a combination!!
}
}
}
}
You may ask, why did not I do anything about single cent coins? The answer is simple, as soon as the sum is less than 100, the rest is filled with 1 cents.
ps. hope this solution is not too simple =)
Ok, this is not a full answer but might help you.
You can try perform (what i call) a sanity check.
Put a static counter in TrieNode for every node created, and see how large it grows. If you did some calculations you should be able to tell if it goes to some insane values.
The system can limit the memory available, however it would be really bizarre. Usually the user/admin can set such limits for some purposes. This happens often in dedicated multi-user systems. Other thing could be having a 32bit app in 64bit windows environment. Then mem limit would be 4GB, however this would also be really strange. Any I don't think being limited by the OS is an issue here.
On a side note. I hope you do realize that you kinda defeated all object oriented programming concept with this code :).
I need more time to analyze your code, but for now I can tell that this is a classic Dynamic Programming problem. You may find some interesting texts here:
http://www.algorithmist.com/index.php/Coin_Change
and here
http://www.ccs.neu.edu/home/jaa/CSG713.04F/Information/Handouts/dyn_prog.pdf
There is a much easier way to find a solution:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
int w[101];
memset(w, 0, sizeof(w));
w[0] = 1;
int d[] = {1, 5, 10, 25, 50};
for (int i = 0 ; i != 5 ; i++) {
for (int k = d[i] ; k <= 100 ; k++) {
w[k] += w[k-d[i]];
}
}
cout << w[100] << endl;
return 0;
}
(link to ideone)
The idea is to incrementally build the number of ways to make change by adding coins in progressively larger denomination. Each iteration of the outer loop goes through the results that we already have, and for each amount that can be constructed using the newly added coin adds the number of ways the combination that is smaller by the value of the current coin can be constructed. For example, if the current coin is 5 and the current amount is 7, the algorithm looks up the number of ways that 2 can be constructed, and adds it to the number of ways that 7 can be constructed. If the current coin is 25 and the current amount is 73, the algorithm looks up the number of ways to construct 48 (73-25) to the previously found number of ways to construct 73. In the end, the number in w[100] represents the number of ways to make one dollar (292 ways).
I really do believe someone has to put the most efficient and simple possible implementation, it is an improvement on lenik's answer:
Memory: Constant
Running time: Considering 100 as n, then running time is about O(n (lg(n))) <-I am unsure
for(int fifty=0; fifty <= 100; fifty+=50)
for(int quarters=0; quarters <= (100 - fifty); quarters+=25)
for(int dimes=0; dimes <= (100 - fifty - quarters); dimes+=10)
counter += 1 + (100 - fifty - quarters - dimes)/5;
I think this can be solved in constant time, because any sequence sum can be represented with a linear formula.
Problem might be infinite recursion. You are not incrementing c any where and loop runs with c<=100
Edit 1: I am not sure if
int c = Root->Sum+coins[i];
is actually taking it beyond 100. Please verify that
Edit 2: I missed the Sum being initialized correctly and it was corrected in the comments below.
Edit 3: Method to debug -
One more thing that you can do to help is, Write a print function for this tree or rather print on each level as it progresses deeper in the existing code. Add a counter which terminates loop after say total 10 iterations. The prints would tell you if you are getting garbage values or your c is gradually increasing in a right direction.
I am having a hard time with two functions. Here are the project instructions:
Assignment:
Write a program which keeps track of the number of roaches in two adjacent houses for a number of weeks. The count of the roaches in the houses will be determined by the following:
The initial count of roaches for each house is a random number between 10 and 100.
Each week, the number of roaches increases by 30%.
The two houses share a wall, through which the roaches may migrate from one to the other. In a given week, if one house has more roaches than the other, roaches from the house with the higher population migrate to the house with the lower population. Specifically, 30% of the difference (rounded down) in population migrates.
Every four weeks, one of the houses is visited by an exterminator, resulting in a 90% reduction (rounded down) in the number of roaches in that house.
Here's my code:
#include <iostream>
#include <cmath>
using namespace std;
int house, increase, roaches, moreRoaches, fewerRoaches, filthyBeasts, change; // My variables for my four functions
int initialCount(int house);
int weeklyIncrease(int increase);
double roachesMigration(int moreRoaches, int fewerRoaches, int change);
int exterminationTime (int filthyBeasts);
// My four function prototypes
int main()
{
int houseA, houseB;
houseA = initialCount(houseA); //Initializing the initial count of House A.
houseB = initialCount(houseB); //Initializing the initial count of House B.
int week = 0;
for (week = 0; week < 11; week++) // My for loop iterating up to 11 weeks.
{
houseA = weeklyIncrease(houseA);
houseB = weeklyIncrease(houseB);
cout << "For week " << week << ", the total number of roaches in House A is " << houseA << endl;
cout << "For week " << week << ", the total number of roaches in House B is " << houseB << endl;
if((houseA > houseB)) // Migration option 1
{
roachesMigration(moreRoaches, fewerRoaches, change);
}
else if((houseB > houseA)) // Migration option 2
{
roachesMigration(moreRoaches, fewerRoaches, change);
}
if ((week + 1) % 4 == 0) // It's extermination time!
{
if ((rand() % 2) == 0) // Get a random number between 0 and 1.
{
houseB = exterminationTime(houseB);
}
else
{
houseA = exterminationTime(houseA);
}
}
}
return 0;
}
int initialCount(int house) // Initializing both houses to random numbers between 10 and 100.
{
int num;
num = (rand() % 91) + 10;
return num;
}
int weeklyIncrease(int increaseHouses) // Increasing the roaches in both houses by 30% weekly.
{
int increase = 0;
increase = (increaseHouses * .3) + increaseHouses;
return increase;
}
double roachesMigration(int moreRoaches, int fewerRoaches, int change)
{
more -= change;
fewer += change;
change = ((more - fewer) * .3);
return change;
}
int exterminationTime(int filthyBeasts) // Getting rid of the filthy little beasts!
{
filthyBeasts = (filthyBeasts * .1);
return filthyBeasts;
}
The issues are with the migration and extermination functions. My code runs fine, but at weeks 4 and 8, the randomly selected house should get exterminated, and the number of roaches in that house should be 90% less than the previous week. What do you guys think I should do to correct these issues? I really need all the help I can get!
Regarding this line:
roachesMigration(change);
change is not declared in your main function, hence the error. Also, roachesMigration function expects 3 parameters and not 1.
The variable change is not a global variable, but appears inside main (so it has no meaning inside main).
Your roachesMigration fonction is declared with three formal arguments (without default values), but you use it with one actual argument.
Ask your compiler to give you all the warnings and to produce debugging information (g++ -Wall -g on Linux). Improve the code till you get no warnings.
Learn to use a debugger (e.g. gdb on Linux).
Have fun.
Depending on the instructor, you will get zero marks for this code, even if you can get it to work perfectly! This is because you have not used any object orientated design in building your code. In C++, that means classes.
What sort of object do you need for this problem. A house!
What sort of attribute should your house have? Roaches!
So something like this:
class cHouse
{
int MyRoachCount;
...
};
If you start fresh, like this, you will find things start to fall neatly into place.
One possible way to handle the migration is like this pseudocode:
// compute size of migration
count = migration(houseA, houseB)
if (houseA < houseB)
add count to houseA
subtract count from houseB
else
add count to houseB
subtract count from houseA