So, this is one of two practice questions given by our professor on HackerRank. I came up with the code but the solution only passes 2/5 test cases. I tried thinking about the possible test cases that give an error for around 4 hours, but, I could not wrap my mind around it.
Can someone point out where I went wrong?
Below is the question.
Alice went for shopping and bought 8 goods costing different prices.
At the time of billing she realises that she did not have enough
money. Now, she have decided to remove the item costing maximum amount
and replace it with another item whose price is same as the item
costing minimum amount. Help Alice and display final prices on the
screen.
Note: if more than one element cost maximum price, replace the first
item.
Example 1:
Input: 250 1000 50 20 10 100 200 25
Output: 250 10 50 20 10 100 200 25
Example 2:
Input: 2500 2500 50 20 10 100 200 25
Output: 10 2500 50 20 10 100 200 25
Sample Input: 250 1000 50 20 10 100 200 25
Sample Output: 10 2500 50 20 10 100 200 25
Constraints
8 items prices are required
Output Format
Prints the final prices of different items after replacing
MY CODE:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int arr[8];
int check=0;
int max=0,min=0;
for(int i=0;i<8;i++)
{
cin>>arr[i];
if(i==0)
{
max =arr[0];
min =arr[0];
}
else
if(arr[i]>max)
max = arr[i];
if(arr[i]<min)
min = arr[i];
}
for(int i=0;i<8;i++)
{
if(arr[i]==max && check==0)
{
arr[i]=min;
check++;
}
cout<<arr[i]<<" ";
}
}
Related
So I'm trying to run this sim program for a class that makes us build a Bet class using sets.
Here's the class definition:
class Bet2{
private:
set<int> mainNumbers;
set<int> luckyNumbers;
public:
Bet2();
void show() const;
set<int> getMainNumbers();
set<int> getLuckyNumbers();
};
So I decided to use the random lib, since the rand() function that they gave us in class spat out the same values when creating a bunch of Bet2 objects at once, for the sim.
However, for some reason, it's not spitting out the number of values it's supposed to. Sometimes it spits out 4 main numbers (instead of 5), or just 1 lucky number (instead of 2)
Here's the code for the constructor:
Bet2::Bet2() {
random_device rd;
uniform_int_distribution<int> main(1, 50);
for (int i = 0; i < 5; i++)
mainNumbers.insert(main(rd));
uniform_int_distribution<int> star(1, 12);
for (int i = 0; i < 2; i++)
luckyNumbers.insert(star(rd));
}
I ran a few tests using the uniform_int_distribution and the random_device, in the main fucntion, and it ran without any problem. For some reason it eats up values when i initialize a Bet2 vector for my sim:
Main Numbers: 11 23 27 32 36
Star Numbers: 3 11
Main Numbers: 4 18 22 27 28
Star Numbers: 9 11
Main Numbers: 3 5 25 43 <-
Star Numbers: 1 <-
Main Numbers: 40 42 43 46 50
Star Numbers: 2 7
Main Numbers: 7 10 14 27 45
Star Numbers: 9 10
Main Numbers: 11 15 21 24 35
Star Numbers: 1 11
Main Numbers: 3 25 29 45 50
Star Numbers: 3 7
Main Numbers: 11 15 23 25 37
Star Numbers: 1 6
Main Numbers: 7 8 26 31 43
Star Numbers: 6 9
Main Numbers: 15 27 36 38 39
Star Numbers: 2 8
Tried to figure out of uniform_int_distribution can not generate a value, but didnt't find anything online.
Thanks in advance!
std::set can store only up to 1 copy of a given value.
The lack of numbers should be because the random numbers happened to become the same as the numbers that were previously seen.
If you want to store multiples of the same value, you should use std::multiset instead.
If you want to generate a unique set of defined number of values, it may be better to first generate a std::vector of candidate values, and then use std::sample() for that.
Consider the following code snippet of this class template...
template<class T>
class FileTemplate {
private:
std::vector<T> vals_;
std::string filenameAndPath_;
public:
inline FileTemplate( const std::string& filenameAndPath, const T& multiplier ) :
filenameAndPath_( filenameAndPath ) {
std::fstream file;
if ( !filenameAndPath_.empty() ) {
file.open( filenameAndPath_ );
T val = 0;
while ( file >> val ) {
vals_.push_back( val );
}
file.close();
for ( unsigned i = 0; i < vals_.size(); i++ ) {
vals_[i] *= multiplier;
}
file.open( filenameAndPath_ );
for ( unsigned i = 0; i < vals_.size(); i++ ) {
file << vals_[i] << " ";
}
file.close();
}
}
inline std::vector<T> getValues() const {
return vals_;
}
};
When used in main as such with the lower section commented out with the following pre-populated text file:
values.txt
1 2 3 4 5 6 7 8 9
int main() {
std::string filenameAndPath( "_build/values.txt" );
std::fstream file;
FileTemplate<unsigned> ft( filenameAndPath, 5 );
std::vector<unsigned> results = ft.getValues();
for ( auto r : results ) {
std::cout << r << " ";
}
std::cout << std::endl;
/*
FileTemplate<float> ft2( filenameAndPath, 2.5f );
std::vector<float> results2 = ft2.getValues();
for ( auto r : results2 ) {
std::cout << r << " ";
}
std::cout << std::endl;
*/
std::cout << "\nPress any key and enter to quit." << std::endl;
char q;
std::cin >> q;
return 0;
}
and I run this code through the debugger sure enough both the output to the screen and file are changed to
values.txt - overwritten are -
5 10 15 20 25 30 35 40 45
then lets say I don't change any code just stop the debugging or running of the application, and let's say I run this again 2 more times, the outputs respectively are:
values.txt - iterations 2 & 3
25 50 75 100 125 150 175 200 225 250
125 250 375 500 625 750 875 1000 1125 1250
Okay good so far; now lets reset our values in the text file back to default and lets uncomment the 2nd instantiation of this class template for the float with a multiplier value of 2.5f and then run this 3 times.
values.txt - reset to default
1 2 3 4 5 6 7 8 9
-iterations 1,2 & 3 with both unsigned & float the multipliers are <5,2.5> respectively. 5 for the unsigned and 2.5 for the float
- Iteration 1
cout:
5 10 15 20 25 30 35 40 45
12.5 25 37.5 50 62.5 75 87.5 100 112.5
values.txt:
12.5 25 37.5 50 62.5 75 87.5 100 112.5
- Iteration 2
cout:
60
150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25
values.txt:
150 12.5 62.5 93.75 125 156.25 187.5 218.75 250 281.25
- Iteration 3
cout:
750 60
1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125
values.txt:
1875 150 12.5 156.25 234.375 312.5 390.625 468.75 546.875 625 703.125
A couple of questions come to mind: it is two fold regarding the same behavior of this program.
The first and primary question is: Are the file read and write calls being done at compile time considering this is a class template and the constructor is inline?
After running the debugger a couple of times; why is the output incrementing the number of values in the file? I started off with 9, but after an iteration or so there are 10, then 11.
This part just for fun if you want to answer:
The third and final question yes is opinion based but merely for educational purposes for I would like to see what the community thinks about this: What are the pros & cons to this type of programming? What are the potentials and the limits? Are their any practical real world applications & production benefits to this?
In terms of the other issues. The main issue is that you are not truncating the file when you do the second file.open statement, you need :
file.open( filenameAndPath_, std::fstream::trunc|std::fstream::out );
What is happening, is that, when you are reading unsigned int from a file containing floating points, it is only reading the first number (e.g. 12.5) up to the decimal place and then stopping (e.g. reading only 12)
, because there is no other text on the line that looks like an unsigned int. This means it only reads the number 12 and then multiplies it by 5 to get the 60, and writes it to the file.
Unfortunately because you don't truncate the file when writing the 60, it leaves the original text at the end which is interpreted as additional numbers in the next read loop. Hence, 12.5 appears in the file as 60 5
stream buffers
Extracts as many characters as possible from the stream and inserts them into the output sequence controlled by the stream buffer object pointed by sb (if any), until either the input sequence is exhausted or the function fails to insert into the object pointed by sb.
(http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/)
Why is there a variation between the numbers in the output of my code, versus the expected output result (as pasted at the end)?
I went through these questions related to the calculation of the number of recursive calls:
Number of calls for nth Fibonacci number
Count number of recursive calls in fibonacci
I could not form a proper answer or a solution to my question.
I even tried re-initializing the count by writting call_count = 0; in the main() function after the for loop or also in the function definitions (as suggested in the answers of the second link above) but, it did not work or give me the expected output.
I have pasted my code below and its output below the code, and the expected output below my code output.
#include <iostream>
#include "math.h"
#include <iomanip>
using namespace std;
int call_count = 0;
int fibo(int n)
{
call_count+=1;
if(n<=2)
{
return 1;
}
else {
//call_count += 1;
return fibo(n-1) + fibo(n-2);
}
return n;
}
int main()
{
int num;
cout<<"\nenter the number of integers to be printed in the fibonacci series\n";
cin>>num;
cout<<"\nfibonacci series for first "<<num<<" numbers is\n";
cout<<"\n\nSerial Number\t"<<"FIBO_NUMBER\t"<<" NO_OF_CALLS MADE\n\n";
for(int i=1;i<=num;i++)
{
cout<<endl<<i<<"th number\t "<<fibo(i)<<"\t\t"<<call_count<<" calls\n";
}
cout<<endl<<"\n the total number of recursive calls made were "<<call_count<<endl<<endl;
system("pause");
return 0;
}
The Output for My Code:
enter the number of integers to be printed in the fibonacci series
15
fibonacci series for first 15 numbers is
Serial Number FIBO_NUMBER NO_OF_CALLS MADE
1th number 1 0 calls
2th number 1 1 calls
3th number 2 2 calls
4th number 3 5 calls
5th number 5 10 calls
6th number 8 19 calls
7th number 13 34 calls
8th number 21 59 calls
9th number 34 100 calls
10th number 55 167 calls
11th number 89 276 calls
12th number 144 453 calls
13th number 233 740 calls
14th number 377 1205 calls
15th number 610 1958 calls
the total number of recursive calls made were 3177
Press any key to continue . . .
Whereas the EXPECTED output numbers are as follows:
1 th integer of fibonacci series is 1 and it needed 0 recursive calls
2 th integer of fibonacci series is 1 and it needed 0 recursive calls
3 th integer of fibonacci series is 2 and it needed 2 recursive calls
4 th integer of fibonacci series is 3 and it needed 4 recursive calls
5 th integer of fibonacci series is 5 and it needed 8 recursive calls
6 th integer of fibonacci series is 8 and it needed 14 recursive calls
7 th integer of fibonacci series is 13 and it needed 24 recursive calls
8 th integer of fibonacci series is 21 and it needed 40 recursive calls
9 th integer of fibonacci series is 34 and it needed 66 recursive calls
10 th integer of fibonacci series is 55 and it needed 108 recursive calls
11 th integer of fibonacci series is 89 and it needed 176 recursive calls
12 th integer of fibonacci series is 144 and it needed 286 recursive calls
13 th integer of fibonacci series is 233 and it needed 464 recursive calls
14 th integer of fibonacci series is 377 and it needed 752 recursive calls
15 th integer of fibonacci series is 610 and it needed 1218 recursive calls
Press any key to continue . . .
How do I resolve this mismatch?
Reset the call_count to zero before making call to fibo() method.
#include <iostream>
#include "math.h"
#include <iomanip>
using namespace std;
int call_count = 0;
int fibo(int n)
{
call_count+=1;
if(n<=2)
{
return 1;
}
else {
//call_count += 1;
return fibo(n-1) + fibo(n-2);
}
return n;
}
int main()
{
int num;
cout<<"\nenter the number of integers to be printed in the fibonacci series\n";
cin>>num;
cout<<"\nfibonacci series for first "<<num<<" numbers is\n";
cout<<"\n\nSerial Number\t"<<"FIBO_NUMBER\t"<<" NO_OF_CALLS MADE\n\n";
for(int i=1;i<=num;i++)
{
call_count = 0;
cout<<endl<<i<<"th number\t "<<fibo(i)<<"\t\t"<<call_count<<" calls\n";
}
cout<<endl<<"\n the total number of recursive calls made were " <<call_count<<endl<<endl;
system("pause");
return 0;
}
Collectively summarizing from the pin-point inputs of #rlbond and #zeroCool, along with a tiny change to both to form a single answer:-
resetting call_count to zero on each loop iteration, and printing the call_count on a separate statement from the call to fibo (since it could be evaluated at the call point), will yield the expected output.
Also one needs to subtract 1 from call_count (for the initial call), while printing out the count statement for each fibonacci number to get the expected count.
Following Code reduces the need of an extra variable and splits the print statement evaluating to expected output. (alternatively one could refer to the link from rlbond's comment on the question above. ideone.com/8EWjOC )
#include <iostream>
#include "math.h"
#include <iomanip>
using namespace std;
int call_count = 0;
int fibo(int n)
{
call_count+=1;
if(n<=2)
{
return 1;
}
else {
return fibo(n-1) + fibo(n-2);
}
return n;
}
int main()
{
int num;
cout<<"\nenter the number of integers to be printed in the fibonacci series\n";
cin>>num;
cout<<"\nfibonacci series for first "<<num<<" numbers is\n";
cout<<"\n\nSerial Number\t"<<"FIBO_NUMBER\t"<<" NO_OF_CALLS MADE\n\n";
for(int i=1;i<=num;i++)
{
call_count = 0;
cout<<endl<<i<<"th number\t "<<fibo(i)<<"\t\t";
cout<<call_count-1<<" calls\n";
}
cout<<endl<<"\n the total number of recursive calls made were "<<call_count-1<<endl<<endl;
system("pause");
return 0;
}
Works fine, output as follows:-
enter the number of integers to be printed in the fibonacci series
15
fibonacci series for first 15 numbers is
Serial Number FIBO_NUMBER NO_OF_CALLS MADE
1th number 1 0 calls
2th number 1 0 calls
3th number 2 2 calls
4th number 3 4 calls
5th number 5 8 calls
6th number 8 14 calls
7th number 13 24 calls
8th number 21 40 calls
9th number 34 66 calls
10th number 55 108 calls
11th number 89 176 calls
12th number 144 286 calls
13th number 233 464 calls
14th number 377 752 calls
15th number 610 1218 calls
the total number of recursive calls made were 1218
Press any key to continue . . .
gratitude to everyone's contribution.
The question is: The ABC Hardware Company has hired you to write a program for it's Account Receivable dept. The master file is in ascending order by customer number with a 20 character customer name and balance due. The transaction file contains records of each transaction with customer number. You are to read in records one at a time from the two files and use the transaction file to update the info from the master file. Process all transaction records before going on to the next master record. If the transaction record contains an "O" in column 1, calculate the orderamount and add it to the balance due. If the record contains a "P" in column 1, subtract the payment from the balance due. Keep a running total of the AR balance of the ABC Company (the sum of balances for each customer). After processing a master record and all its transactions, the program should prepare an invoice for each customer which lists the customer name, number, previous balance, all transactions, and the final balance due.
The output should look like:
CUSTOMER NAME CUSTOMER NUMBER
PREVIOUS BALANCE $XXX.XX
(ALL TRANSACTIONS PER CUSTOMER:)
TRANSACTION# ITEM ORDERED $ORDER AMOOUNT
TRANSACTION# ITEM ORDERED $ORDER AMOUNT
TRANSACTION# PAYMENT $PAYMENT AMOUNT
BALANCE DUE $XXX.XX
I've tried changing up the arrays, the if statements etc. Now nothing's printing at all when I run the program. Please help!
Here is the code I have so far:
# include <iostream>
# include <fstream>
# include <iomanip>
# include <string>
using namespace std;
struct master {
double custnum;
string name;
double balance;
};
struct transactions {
char transtype;
int custnum;
int transnum;
string item;
int quantity;
double price;
double amountpaid;
};
int main ()
{
ifstream masterfile ("MASTER.txt");
ifstream transfile ("TRANSACTION.txt");
int prevbalance[7];
master main [7];
for (int i=0; !masterfile.eof(); i++) {
masterfile>>main[i].custnum>>main[i].name>>main[i].balance;
}
for (int i=0;!masterfile.eof();i++) {
cout << main[i].custnum<<" ";
cout << main[i].name<<" ";
cout << main[i].balance<<" "<<
endl<<endl;
prevbalance[i] = main[i].balance;
}
double companybalance = 0;
double orderamt=0;
transactions tran[35];
for (int i=0; !transfile.eof(); i++) {{
transfile>> tran[i].transtype;
cout<<tran[i].transtype<<" ";
if (tran[i].transtype == 'O') {
transfile>>tran[i].custnum;
cout<<tran[i].custnum<<" ";
transfile>> tran[i].transnum;
cout<<tran[i].transnum<<" ";
transfile>>tran[i].item;
cout<<tran[i].item<<" ";
transfile>>tran[i].quantity;
cout<<tran[i].quantity<<" ";
transfile>>tran[i].price;
cout<<tran[i].price<<" "<<endl<<endl;
orderamt= tran[i].price*tran[i].quantity;
main[i].balance+= orderamt;
companybalance += main[i].balance;
}
else if (tran[i].transtype == 'P'){
transfile>>tran[i].custnum;
cout<<tran[i].custnum<<" ";
transfile>> tran[i].transnum;
cout<<tran[i].transnum<<" ";
transfile>>tran[i].amountpaid;
cout<<tran[i].amountpaid<<endl<<endl<<endl;
main[i].balance-tran[i].amountpaid;
companybalance += main[i].balance;
}}
for(int i=0; i<50; i++) {
cout<<"Name: "<< main[i].name <<" Customer #: "<< main[i].custnum<<endl<<endl;
cout<<"Previous Balance "<<prevbalance[i]<<endl;
for(int j=0; j<7; j++){
cout<<"Transaction #: "<<tran[j].transnum<<" "<<tran[j].item<<" $"<<orderamt<<endl; }
cout<<"Balance Due: "<<main[i].balance<<endl;
}
}}
Here are the input two files, Masterfile:
1000 TIFFANY 7000.99
2000 MARY 6500.98
3000 JACOB 6560.99
4000 GENE 4560.98
5000 BELLA 5300.87
6000 ANNA 2340.90
7000 DEMI 4230.45
and transaction file:
O 1000 1000 PENS 20 2
O 1000 2000 CPUS 2 200
O 1000 3000 MONITER 2 100
P 1000 4000 4000
P 1000 5000 300
O 2000 6000 CPUS 3 500
O 2000 7000 MOUSE 3 50
O 2000 8000 WIRES 5 8
P 2000 9000 600
P 2000 1100 798
O 3000 1200 MONITERS 6 60
O 3000 1300 CPUS 7 300
O 3000 1400 MOUSE 30 40
O 3000 1500 SPEAKERS 20 20
P 3000 1600 5000
O 4000 1001 SPEAKERS 2 50
O 4000 2002 CABLES 4 20
P 4000 3003 400
P 4000 4004 500
P 4000 5005 68
P 5000 6001 600
P 5000 4002 55
P 5000 2003 450
O 5000 4004 SPEAKERS 4 60
O 5000 1005 LAPTOP 3 300
O 6000 6001 TVS 5 400
O 6000 8002 SPEAKERS 5 70
P 6000 6003 2000
P 6000 8004 1000
O 6000 8005 CABLES 10 15
O 7000 5001 PENS 50 2
O 7000 7002 PAPER 400 2
P 7000 4003 150
P 7000 3004 230
P 7000 6005 450
You're using masterfile.eof() as a loop condition twice.
for (int i=0; !masterfile.eof(); i++) {
masterfile>>main[i].custnum>>main[i].name>>main[i].balance;
}
for (int i=0;!masterfile.eof();i++) {
cout << main[i].custnum<<" ";
cout << main[i].name<<" ";
cout << main[i].balance<<" "<<
endl<<endl;
prevbalance[i] = main[i].balance;
}
Think about how this couldn't possibly work. You've already reached the end of the file by the time the first loop ends. The second loop is going to finish before it even starts!
Of course you could reset the file pointer to the beginning but a much better way is to keep a count of the number of records you have, and use that count for the second loop.
int iRecordCount = 0;
for (iRecordCount = 0; !masterfile.eof(); iRecordCount++) {
masterfile>>main[iRecordCount].custnum>>main[iRecordCount].name>>main[iRecordCount].balance;
}
for (int i=0; i < iRecordCount;i++) {
cout << main[i].custnum<<" ";
cout << main[i].name<<" ";
cout << main[i].balance<<" "<<
endl<<endl;
prevbalance[i] = main[i].balance;
}
Also note that you're using a fixed array (master main[7]) to store your records - what happens if you have an input file with more than 7 records in it? You'll exceed the bounds of the array. Really you should change to using a std::vector so that the array can grow dynamically, but if you don't want to do that you should put an additional check in when reading the records to make sure you don't overflow the array:
int iRecordCount = 0;
for (iRecordCount = 0; iRecordCount < sizeof(main) / sizeof(main[0]) && !masterfile.eof();
iRecordCount++) {
masterfile>>main[iRecordCount].custnum>>main[iRecordCount].name>>main[iRecordCount].balance;
}
You're also doing something weird when reading your transactions. You have things like:
orderamt= tran[i].price*tran[i].quantity;
main[i].balance+= orderamt;
If i is the transaction number (tran[i]) how can it also be the customer number as well (main[i])? You're allowed to use variable names other than i you know!
You also have this at the bottom of your code:
for(int i=0; i<50; i++) {
....
}
Again, you should use the actual number of elements in the array (iRecordCount) rather than a fixed number (and where did 50 come from since your array is only 7 elements in size?).
In addition to the suggestions made by #JonathanPotter in his answer, I want to add that using ifstream.eof() in the for loop is error prone.
Useful reading material: Why is “while ( !feof (file) )” always wrong?.
Use of !masterfile.eof() in the conditional of a for loop is wrong for exactly the same reasons.
It's better to use:
std::vector<master> masterData;
while ( masterfile )
{
// Try to read the data into a temporary object.
master m;
masterfile >> m.custnum >> m.name >> m.balance;
// If the input was successful, add it to masterData
if ( masterfile )
{
masterData.push_back(m);
}
}
You can use similar logic to read the transaction records too.
Also, you have a line:
main[i].balance - tran[i].amountpaid;
I am sure that is a typo and you meant to use:
main[i].balance -= tran[i].amountpaid;
I'm trying to implement an ACO for 01MKP. My input values are from the OR-Library mknap1.txt. According to my algorithm, first I choose an item randomly. then i calculate the probabilities for all other items on the construction graph. the probability equation depends on pheremon level and the heuristic information.
p[i]=(tau[i]*n[i]/Σ(tau[i]*n[i]).
my pheremon matrix's cells have a constant value at initial (0.2). for this reason when i try to find the next item to go, pheremon matrix is becomes ineffective because of 0.2. so, my probability function determines the next item to go, checking the heuristic information. As you know, the heuristic information equation is
n[i]=profit[i]/Ravg.
(Ravg is the average of the resource constraints). for this reason my prob. functions chooses the item which has biggest profit value. (Lets say at first iteration my algorithm selected an item randomly which has 600 profit. then at the second iteration, chooses the 2400 profit value. But, in OR-Library, the item which has 2400 profit value causes the resource violation. Whatever I do, the second chosen is being the item which has 2400 profit.
is there anything wrong my algorithm? I hope ppl who know somethings about ACO, should help me. Thanks in advance.
Input values:
6 10 3800//no of items (n) / no of resources (m) // the optimal value
100 600 1200 2400 500 2000//profits of items (6)
8 12 13 64 22 41//resource constraints matrix (m*n)
8 12 13 75 22 41
3 6 4 18 6 4
5 10 8 32 6 12
5 13 8 42 6 20
5 13 8 48 6 20
0 0 0 0 8 0
3 0 4 0 8 0
3 2 4 0 8 4
3 2 4 8 8 4
80 96 20 36 44 48 10 18 22 24//resource capacities.
My algorithm:
for i=0 to max_ant
for j=0; to item_number
if j==0
{
item=rand()%n
ant[i].value+=profit[item]
ant[i].visited[j]=item
}
else
{
calculate probabilities for all the other items in P[0..n]
find the biggest P value.
item=biggest P's item.
check if it is in visited list
check if it causes resource constraint.
if everthing is ok:
ant[i].value+=profit[item]
ant[i].visited[j]=item
}//end of else
}//next j
update pheremon matrix => tau[a][b]=rou*tau[a][b]+deltaTou
}//next i