A simple recursion problem to simulate the spread of a computer virus - c++

The problem I try to solve is:
A kind of computer virus will infect 100 computers at day 0.
Each of the 70% of the infected computer will infect one more computer.
There are 2 computer scientists fix the problem. Each of them can fix 1 Computer at day 1.
Each of the subsequent days, because of their increased experience, they can fix double so many computers as the previous day.
So, how many computers are still infected n days later ?
And how would the figures be from the day 0 to day 20?
To solve it, I wrote the following code:
#include<iostream>
#include<cmath>
using namespace std;
int computervirus(int n){ //n:Tage
int nr_virus= 100;
int nr_fixed;
int rest = 0;
if(n == 0) return 100;
if(n <= 20){
nr_virus += computervirus(n-1)*0.7;
nr_fixed = pow(2,n);
rest = nr_virus - nr_fixed;
}
return rest;
}
int main(){
cout << endl;
for(int i=0; i <= 20; i++){
cout << "at the "<< i << " .day are still "<< computervirus(i) << " infected Computers\n" <<endl;
}
return 0;
}
The output for the number(infected computers) are just not right, because the infecting speed is definitly faster als the repair at least first 9 days.
I'm not sure where the prrblem is. Can you help?

Your recursion for day n try to use 70% of the result of day n+1. This causes an infinite recursion. You must use 70% of day-1 and it will work. Now it's not 70% of the previous day, but it's 70% more so not * 0,7 but * 1,7.
And you need to take into account that there can't be a negative number of computer infected.
Finally, you overestimate the repairs: on day 1 it's 2, on day 2 it's 4, but as the 2 of day 1 were already counted in your recursion for day-1, so you deduce them twice. So you should only count the aditional computers fixed the day n. So pow(2, n-1).
The corrected code would look like:
int computervirus(int n){ //n:Tage
int nr_virus= 100;
int nr_fixed = 0;
int rest = 0;
if(n>0){
nr_virus = computervirus(n-1)*1.7; // n-1 not n+1
if (n==1)
nr_fixed = 2;
else nr_fixed = pow(2,n-1);
}
rest = nr_virus - nr_fixed;
if (rest<0)
rest = 0;
return rest;
}
Online demo

You forgot to use braces around the body of your for loop
int main(){
for(int i=0; i <= 20; i++)
{
cout << endl;
cout << "at the "<< i << " .day are still "<< computervirus(i) << " infected Computers\n" <<endl;
}
return 0;
}
Put a left brace { before the first statement in your loop, and a right brace } after the last.
Because the braces were missing only the first statement cout << endl; was inside the loop.

Related

I Need to Pass Array to a Function to Average Different Test Scores [duplicate]

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
The goal of this code is to pass an array through a function (which I'm already having a difficult time understanding). I went through with a pen and paper and traced the code and I think I just don't know enough to understand what's going wrong. All the test scores I throw in just push back a ridiculously large negative number. I'm not asking for you guys to do my homework because I really want to try and understand what I'm doing, but any help would really be appreciated right now.
#include <iostream>
//function prototype
double average(int studentScores[], int size);
double studentScores[4];
bool runAgain(void);
int main() {
do {
int studentScores[4], size = 4, result;
string score;
cout << "This program will calculate the average of four diffrent exam scores." << endl;
for (int i = 0; i < size; i++) {
studentScores[i] = 0;
cout << "Please Enter Exam Score " << i + 1 << ": ";
getline(cin, score);
}
for (int i = 0; i < size; i++) {
result = (studentScores[1] + studentScores[2] + studentScores[3] + studentScores[4]) / size;
studentScores[i]++;
}
cout << "The Average Exam score is " << result << endl;
} while (runAgain());
system("pause");
return 0;
}
//function implementation
double average(int studentScores[], int size) {
for (int i = 0; i < size; i++) {
return (studentScores[i]++ / size);
}
}
bool runAgain(void) {
char userResponse;
cout << "\nWould you like to run again (y or n): ";
cin >> userResponse;
if (userResponse == 'y' || userResponse == 'Y')
return(true);
return(false);
}
First obvious bug:
int studentScores[4]
studentScores has 4 elements, numbered studentScores[0] through studentScores[3].
But your code accesses studentScores[4] in
result = (... + studentScores[4]) / ...
which doesn't exist (and doesn't access studentScores[0], which does).
Glad to try to help ya out without giving you the answer.
I'm gonna sprinkle some questions throughout your code that you should be asking yourself in future programs whenever you get unexpected output.
#include <iostream>
//function prototype
double average(int studentScores[], int size);
double studentScores[4];
bool runAgain(void);
int main() {
do {
int studentScores[4], size = 4, result;
string score;
/* Above, you declared a string to store the user's input in.
In C++, the string "4" DOES NOT equal the integer 4.
How will you handle the fact that the variable 'score' is of type
string, but you want to work with integers?
Is there an easy way to get rid of this issue? (hint: use cin)
*/
cout << "This program will calculate the average of four diffrent exam scores." << endl;
/* In the below for-loop, think about what the value of 'score' will be
after each iteration. (Hint, getline replaces the existing value of score).
Also, where is the code that saves the user's inputted numbers to an array?
Learn how to write values to an array http://www.cplusplus.com/doc/tutorial/arrays/
*/
for (int i = 0; i < size; i++) {
studentScores[i] = 0;
cout << "Please Enter Exam Score " << i + 1 << ": ";
getline(cin, score);
}
/* In the for-loop below, you already noticed that your array has random
values in it. The comment about the above for-loop should address that issue.
Equally important though is understanding what the heck is happening in this
loop below. After you fix the bug in the for-loop above (which will
get the values in the array to equal the user's inputs), you'll be faced
with issues in this loop below.
My advice is to understand what happens when the program
executes "studentScores[i]++". First, it gets the number in the array at
the ith+1 position, then it increments that number by 1. Cool, but what
are you doing with the result of that? It's not being put to use anywhere.
Also, note that because the array is never being updated,
the line above it just calculates the same number and stores it in 'result'
every iteration of the loop.
*/
for (int i = 0; i < size; i++) {
result = (studentScores[1] + studentScores[2] + studentScores[3] + studentScores[4]) / size;
studentScores[i]++;
}
cout << "The Average Exam score is " << result << endl;
} while (runAgain());
system("pause");
return 0;
}
// this function doesn't seem to be used, but understanding what
// is wrong with it will help you understand how to code.
// First, note that once a function hits 'return', it will
// never execute any more code in that function.
// So here, your return statement in the for-loop will prevent an
// actual loop from occuring (since the function will exit as soon as the first loop iteration is entered)
// Second, note that you are just getting the value in the array and adding 1 to it
// before dividing it by 'size', which is not the formula for an average.
double average(int studentScores[], int size) {
for (int i = 0; i < size; i++) {
return (studentScores[i]++ / size);
}
}
bool runAgain(void) {
char userResponse;
cout << "\nWould you like to run again (y or n): ";
cin >> userResponse;
if (userResponse == 'y' || userResponse == 'Y')
return(true);
return(false);
}
I hope these comments helped :) Keep at it!
Don't forget that arrays start at index 0. Trying to access studentScores[4]
will give you an unexpected number.

C++ - Nothing is displayed in console, no errors displayed, -1 is returned

I've recently (very, very recently) have gotten into programming in C++. I'm writing a program to find the highest prime number below prime. However, when I execute the code, nothing is displayed, and in the console it says this:
Process returned -1 (0xFFFFFFFF) execution time : 0.409 s
Press ENTER to continue.
I've tried some debugging, and I've figured out the problematic section is lines 17-19 (the if statement), but I can't figure out what I'm doing wrong.
C++
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
//cout << "maybe here?";
int prime = 1000;
//cout << "here";
while(true){
//cout << "here2";
int testr = ceil(sqrt(prime));
cout << testr;
bool isprime = true;
for(int i = 0; i < testr; i++){
cout << i << " ";
if(testr % i == 0){
isprime = false;
}
}
if(isprime){
break;
}else{
prime--;
}
}
cout << prime;
}
Any and all help is appreciated! Thanks!
Additional Info:
I'm using Code::Blocks on Mac OSX 64 bit. I'm used to programming in Java, so it may just be a C++ thing I'm unaware of.
Quite a few issues.
1) The answer to your question "find the lowest prime number below prime" is 2, no programming required.
2) Assuming you want to find the greatest prime number below prime, you should test all numbers from prime - 1, downwards.
3) The very first iteration of your loop:
for(int i = 0; i < testr; i++){
cout << i << " ";
if(testr % i == 0){
will cause an exception: division by 0.
The reason is that you are trying to divide by 0 in your for loop you should begin with 2. Take a look at this one, it's optimal I guess.
bool isPrime(int n) {
if(n<2)
return false;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return false;
return true;
}

Return name of array which has the highest value

Just started studying C++ for a couple weeks now, and been running through some exercises. Though I am stuck on trying to return the array name which is holding the highest number in the array. For example, I made an array for 10 people, for each person I am having them enter the number of pancakes they ate, now I want to return the person who ate the most pancakes. just not sure how to do it. It falls apart at the second if statement.
int main()
{
int pancakes[9] = {0,0,0,0,0,0,0,0,0};
int max = pancakes[0];
int i;
int p;
for (int x=0; x<=9; x++)
{
cout << "Enter number " << endl;
cin >> i;
pancakes[x] = i;
if(i > max)
max = i;
pancakes[x] = p;
}
cout << endl;
cout << p << " ate the most pcakes # " << max << endl;
return 0;
}
I'm on my phone, so I do apologize if there is formatting problems.
You say that your code falls apart at your second if-statement yet there is only one if-statement, so I am assuming it is the second line in the if-statement. However, there are two problems with this.
You aren't recording the person properly with this:
pancakes[x]=p;
This "should be":
p=x;
You need to put curly braces around the entire statement. For example:
if (i > max) {
max= i;
p=x;
}
Your loop and if statement should be as follow. See details and explanation in comments:
for (int x=0; x<9; x++) // You need to exclude 9 (do not use <=) because the index start at 0
{
cout << "Enter number " << endl;
cin >> i;
//pancakes[x] = i; <-- This line and the array is not needed. With this also you actually don't need to
// store/save what people enter. You just need to keep the max and index
if(i > max) // if i (number entered) is bigger than the current max of pancakes
{
max = i; // You update the max to the new number entered (i)
p = x + 1; // you store in p the array index + 1 (your array index start at 0 not 1)
// of the current person who eat the max number of pancakes
}
}
For the initialization:
//int pancakes[9] = {0,0,0,0,0,0,0,0,0}; <- The array is not needed. See my comment in above code
int max = 0; // More clean and readable
A few things:
1) Your iteration is wrong. It should be:
for (int x = 0; x < 9; ++x)
If you use x <= 9 you will actually do 10 iterations of the loop and the last iteration will run off the end of the pancakes array and corrupt memory.
2) When you find a new max, also set p equal to x to remember who had the most pancakes.
3) You initialize max to be pancakes[0]. While that will actually give you the right answer in this instance, you should instead explicitly initialize max = -1 to indicate an invalid maximum when you start. You also should initialize p = -1 to indicate an invalid eater when you start. These initializations would allow you to distinguish and handle the case when there is no input too.
4) Optimization: you really don't need an array to remember the # of pancakes each person ate if this is all you are doing. You can just loop as many times as you want reading input and compare against max.

Program Compiles, Runs, but doesn't end in DevC++

I wrote a program to sum all odd numbers less than or equal to N. It's not the most efficient or eloquent program, but it works in the compiler on Codepad.org and does not work in DevC++. Usually when a program I wrote is stuck in some kind of infinite loop the program crashes in DevC++ and Windows stops it and lets me know.
Here, the program compiles and runs, but just sits with the cursor blinking and does nothing. Windows doesn't stop it, nothing happens, the program doesn't finish, no matter for how long I let it sit. I'm guessing this is a problem with DevC++ unless it's a problem with my code that Codepad overlooks. Will anyone explain to me what is happening here?
Here is my code:
#include <iostream>
using namespace std;
int odd(int N)
{
int i;
int sum = 0;
for(i = 0; i <= N; ++i)
{
while((i % 2) != 0)
{
sum = sum + i;
}
}
return sum;
}
int main()
{
int N;
cout << "Pick a value: ";
cin >> N;
cout << "The sum of all numbers <= to " << N << " is: " << odd(N);
return 0;
}
I've made the suggested change to an if-statement and the same problem is occuring:
#include <iostream>
using namespace std;
int odd(int N)
{
int i;
int sum = 0;
for(i = 0; i <= N; ++i)
{
if ((i % 2) != 0)
{
sum = sum + i;
}
}
return sum;
}
int main()
{
int N;
cout << "Pick a value: ";
cin >> N;
cout << "The sum of all odd numbers <= to " << N << " is: " << odd(N);
return 0;
}
while((i % 2) != 0)
{
sum = sum + i;
}
This is a infinite loop.Because if (i % 2 != 0) is true then the program will increment sum again and again.What you are probably looking to do is have an if statement instead of while
Seems like the edit is working, please try deleting the old output file and rebuilding and re-compile the entire program.
The output seems to be as follows:
Pick a value: 52
The sum of all odd numbers <= to 52 is: 676
Process exited after 1.034 seconds with return value 0
Press any key to continue . . .
make sure the window of the previous run is closed else the compiler will not recompile but just runs the previous version before you changed it.you may see this as an error stated at bottom in debug mode.
the while() is an infinite loop because i is not changed inside the while() or its {} so use if

C++ Perfect Number. Need some help revising

I need some help revising this. It keeps only displaying 0s as the temp. Thank you.
// A program to determine whether the input number is a perfect number
// A perfect number is defined by the sum of all its positive divisors excluding itself
// 28: 1+2+3+7+14 = 28.
int perfect, limit, divisor;
cout << "Please enter a positive integer in order to define whether it is a perfect integer or not: " ;
cin >> perfect;
cout << endl;
int temp = 0;
int prevtemp = 0;
limit = 1;
divisor = 1;
while (limit < perfect)
{
if ((perfect % divisor) == 0)
{
divisor = prevtemp;
temp = prevtemp + temp;
}
limit++;
divisor++;
}
if (perfect == temp)
cout << "Your number is a perfect number!" << endl;
else
cout << "Your number is not a perfect number" << endl;
return 0;
You are never setting prevtemp to anything other than 0, so adding it to temp does nothing.
I believe you meant to say
if ((perfect % divisor) == 0)
temp += divisor; // not "divisor = prevtemp;"
The line "temp = prevtemp + temp" should also be removed with this solution; there is no longer any need for the prevtemp variable.
Also, there is no need to keep separate limit and divisor variables, since they are always the same. Just remove limit and change the loop condition to use divisor.
Also, as Mark Byers pointed out, the loop would be simpler to understand if you refactored it into a for loop rather than a while.
It seems like you are making it too complicated. Here's how you could do it:
int total = 0;
for (int i = 1; i < perfect; ++i)
{
if (perfect % i == 0)
total += i;
}
if (perfect == total)
cout << "Your number is a perfect number!" << endl;
else
cout << "Your number is not a perfect number" << endl;
Note that the running total is kept in a variable called total (you called this variable temp) and it is only increased when the number is an exact divisor.
I'm not sure, but I'd guess that in the code:
if ((perfect % divisor) == 0)
divisor = prevtemp;
you intended this to be prevtemp=divisor instead. That fixes an obvious problem, but still leaves quite a bit that doesn't look like it's doing that you probably intended. For example, I can't quite figure out what limit is intended to accomplish -- you initialize it and increment it, but as far as I can see, you never use its value (well, I guess you use it, but its value is always the same as divisor's so I'm not sure why you think you need both, or how limit makes any sense as its name).
Edit: It would make sense to have a limit. In particular, factors always come in pairs: one that's less than or equal to the square root of the number, and one that matches the first that's always greater than or equal to the square root of the number. As such, you don't need to scan all the way up to the number itself looking for factors -- you can set the square root of the number as the limit, and scan only up to that point. For each factor you find up to that point, the matching factor will be perfect/divisor. Since you've already gotten one working example, I guess I might as well just hope this isn't homework, and post an example as well:
bool is_perfect(int number) {
int limit = sqrt((double)number);
int sum = 1;
for (int i=2; i<=limit; i++)
if (number % i == 0)
sum += i + number/i;
return sum == number;
}
You are never assigning anything to prevtemp after initializing it to 0, so there is nothing to add to temp on the line that reads temp = prevtemp + temp.
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
int n,i=1,sum=0;
cout<<"Enter a number: ";
cin >> n;
while(i<n){
if(n%i==0)
sum=sum+i;
i++;
}
if(sum==n)
cout << i << " is a perfect number";
else
cout << i << " is not a perfect number";
system("pause");
return 0;
}