I am working on Project Euler, the first problem, and I've gotten this program to output the numbers I need, but I cannot figure out how to take the outputted numbers and add them together.
Here's the code:
#include <iostream>
#include <cmath>
int main(void) {
int test = 0;
while (test<1000) {
test++;
if (test%3 == 0 && test%5 == 0) {
std::cout << test << std::endl;
}
}
std::cin.get();
return 0;
}
The easiest option would be a total variable that you add to as the criteria match.
The first step is creating it and initializing it to 0, so you end up with the right number later.
int total = 0;
After that, subtotals are added to it, so that it accumulates the overall total.
total += 5;
...
total += 2;
//the two subtotals result in total being 7; no intermediate printing needed
Once you've added on the subtotals, you can just print it as the overall total.
std::cout << total;
Now, here's how it fits into the code at hand, along with some other pointers:
#include <iostream>
#include <cmath> //<-- you're not using anything in here, so get rid of it
int main() {
int test = 0;
int total = 0; //step 1; don't forget to initialize it to 0
while (test<1000) { //consider a for loop instead
test++;
if (test % 3 == 0 && test % 5 == 0) {
//std::cout << test << std::endl;
total += test; //step 2; replace above with this to add subtotals
}
}
std::cout << total << std::endl; //step 3; now we just output the grand total
std::cin.get();
return 0; //this is implicit in c++ if not provided
}
The typical way to do this is to use another variable to hold the sum. You gradually add each number to this variable until you have to total at the end of your loop.
Related
I'm trying to solve Codewars task and facing issue that looks strange to me.
Codewars task is to write function digital_root(n) that sums digits of n until the end result has only 1 digit in it.
Example: 942 --> 9 + 4 + 2 = 15 --> 1 + 5 = 6 (the function returns 6).
I wrote some bulky code with supporting functions, please see code with notes below.
The problem - digital_root function works only if I put cout line in while loop. The function returns nonsense without this cout line (please see notes in the code of the function).
My questions are:
Why isn't digital_root working without cout line?
How cout line can effect the result of the function?
Why does cout line fix the code?
Thanks a lot in advance! I'm a beginner, spent several days trying to solve the issue.
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int getDigit (int, int);
int sumDigits (int);
int digital_root (int);
int main()
{
cout << digital_root (942); // expected output result is 6 because 9 + 4 + 2 = 15 -> 1 + 5 = 6
}
int getDigit (int inputNum, int position) // returns digit of inputNum that sits on a particular position (works)
{
int empoweredTen = pow(10, position-1);
return inputNum / empoweredTen % 10;
}
int sumDigits (int inputNum) // returns sum of digits of inputNum (works)
{
int sum;
int inLen = to_string(inputNum).length();
int i = inLen;
while (inLen --)
{
sum += getDigit(inputNum, i);
i --;
}
return sum;
}
int digital_root (int inputNum) // supposed to calculate sum of digits until number has 1 digit in it (abnormal behavior)
{
int n = inputNum;
while (n > 9)
{
n = sumDigits(n);
cout << "The current n is: " << n << endl; // !!! function doesn't work without this line !!!
}
return n;
}
I've tried to rewrite the code from scratch several times with Google to find a mistake but I can't see it. I expect digital_root() to work without any cout lines in it. Currently, if I delete cout line from while loop in digital_root(), the function returns -2147483647 after 13 seconds of calculations. Sad.
Here is an implementation using integer operators instead of calling std::to_string() and std::pow() functions - this actually works with floating-point numbers. It uses two integer variables, nSum and nRem, holding the running sum and remainder of the input number.
// calculates sum of digits until number has 1 digit in it
int digital_root(int inputNum)
{
while (inputNum > 9)
{
int nRem = inputNum, nSum = 0;
do // checking nRem after the loop avoids one comparison operation (1st check would always evaluate to true)
{
nSum += nRem % 10;
nRem /= 10;
} while (nRem > 9);
inputNum = nSum + nRem;
std::cout << "The current Sum is: " << inputNum << endl; // DEBUG - Please remove this
}
return inputNum;
}
As for the original code, the problem was the uninitialized sum variable, as already pointed out by other members - it even generates a compiler error.
int sumDigits (int inputNum) // returns sum of digits of inputNum (works)
{
int sum = 0; // MAKE SURE YOU INITIALIZE THIS TO 0 BEFORE ADDING VALUES TO IT!
int inLen = to_string(inputNum).length();
int i = inLen;
while (inLen --)
{
sum += getDigit(inputNum, i);
i --;
}
return sum;
}
Initialize your variables before adding values to them, otherwise you could run into undefined behaviour. Also for the record, adding the cout line printed out something, but it wasn't the correct answer.
So the main task is to find all numbers divisible by 7 between 0 - 100 then sort them in descending order without using an array. I'm just starting c++ and one of my first lab tasks was this, however when I finished it I was told that I shouldn't have used an array. I'm now curious as to how to do so otherwise. The code here only finds the numbers divisible by 7 and naturally displays them in an ascending sort.
I'm unsure how I would sort them without storing the value in an array then changing switching the values that way.
#include <iostream>
using namespace std;
int main() {
for( int i = 0; i <= 100; i++){
if(i%7 == 0){
//Display every integer divisible by 7
cout << i << endl;
}
}
return 0;
}
One approach is to find the lagest number divisible by 7 (here, 98) and just continue removing 7 to it until you run across the lowest boundary.
Just reverse the for loop:
for( int i = 100; i >= 7; i--){ //There is no integer lower than 7 that is divisible by 7
if(i%7 == 0){
cout << i << endl;
}
}
Change your loop to go in descending order; then you won't have to sort anything.
What you can do is start at max and go down from there; as follows:
for(int i = 100; i >= 0; i--){
if(i % 7 == 0){
cout << i << endl;
}
}
Bling it like its 2020 .. (You will get great grades ;-) )
#include <iostream>
using namespace std;
int main() {
int i=101;
while(--i)i%7?cout:cout<<i<<endl;
}
I'm trying to create a array of prime numbers done by calculation. As a project to learn coding. Ultimately to build my own math library so this is something I can add onto at a variety of levels as I learn to code c++.
The following is code that works great for printing prime numbers to the screen based on the search range, but my totalPrimes iterator is stuck at 1. So each time it places the last prime found in the PrimeNumbers[1] position.
Any advice would be awesome.
#include <iostream>
#include <array>
std::array<long, 10000000> PrimeNumbers={0};
void isPrime(long x);
int main() {
for (long i = 1; i < 10; i++) {
isPrime(i);
}
for(int h = 0; h < 10; h++) {
std::cout << "\nSecond Prime is : " << PrimeNumbers[h];
}
}
void isPrime(long x) {
int count(0), totalPrimes(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
if (count == 1) {
++totalPrimes;
std::cout << '\n' << x << " is a Prime number";
PrimeNumbers[totalPrimes] = x;
}
}
You're initializing totalPrimes to 0 every time the function runs. You would need to have totalPrimes as a global variable, or better yet (because global variables can become problematic), set it equal to the first available member of PrimeNumbers before you do anything else in that function.
Keep track of a position along with your PrimeNumbers array.
size_t nLastPos=0;
...
for(size_t x = 0; 1000 > x; ++x)
{
if(isPrime(x))
{
PrimeNumbers[nLastPos++] = x;
}
}
for(size_t i = 0; nLastPos > n; ++n)
{/* print out number PrimeNumbers[n] */ }
It looks like you're having some trouble with variable scoping. The reason for your problem (as I noted in the comment) is that totalPrimes is local, so you're creating a new integer variable and setting it to 0 every time the function is called.
However, you've made PrimeNumbers global and are having the isPrime function modify it, which doesn't look like good practice.
All of this can be fixed with a little restructuring to make the code nicer:
#include <iostream>
#include <array>
bool isPrime(long x);
int main() {
std::array<long, 10000000> PrimeNumbers={0};
int totalPrimes = 0;
for (long i = 1; i < 10; i++) {
if (isPrime(i)) {
std::cout << '\n' << i << " is a Prime number";
PrimeNumbers[totalPrimes++] = i;
}
}
for(int h = 0; h < 10; h++) {
std::cout << h << " Prime is : " << PrimeNumbers[h] << std::endl;
}
}
bool isPrime(long x) {
int count(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
return count == 1;
}
Your program can be re-structured little bit to make it easier to follow and debug.
Don't put things in isPrime other than the logic to decide whether a number is prime. Make sure it returns a bool. This will make the function a bit simpler and easier to debug.
Use the return value of isPrime in the calling function to perform other bookkeeping tasks.
The logic you have used to check whether a number is prime is incorrect. That needs to be fixed.
Here's an updated version of your posted code.
#include <iostream>
#include <array>
#include <cmath>
std::array<long, 10000000> PrimeNumbers={0};
bool isPrime(long x);
int main()
{
int totalPrimes = 0;
for (long i = 1; i < 10; i++)
{
if ( isPrime(i) )
{
std::cout << i << " is a Prime number" << std::endl;
PrimeNumbers[totalPrimes] = i;
++totalPrimes;
}
}
}
bool isPrime(long x) {
// 1, 2, and 3 are primes.
if ( x <= 3 )
{
return true;
}
// Even numbers are not primes.
if ( x % 2 == 0 )
{
return false;
}
// Check the rest.
long end = (long)std::sqrt(x);
for (long a = 3; a < end; a += 2) {
if ((x % a) == 0)
{
return false;
}
}
return true;
}
and its output:
1 is a Prime number
2 is a Prime number
3 is a Prime number
5 is a Prime number
7 is a Prime number
9 is a Prime number
Everybody is talking about how your totalPrimes variable is reset each time the function is called, and this is obviously true. You could return the value from the function and increment it from main, you could use global variables having the variable being defined outside of the function so that it's not reset each time inside the function or you could use
A static variable!
Take a look at this simple case. I have a function called up_two which increases the value of by two each time the function is called. The static variable int value has a memory of each time the function up_two() is called which increments value by two each time. If I were to use a just an integer it would always reset the value and have it be zero, which is what I initially defined it to be.
The advantage of using a static variable is that I can count how many times a function has been called, and I can keep my counter specific to a particular function.
#include <iostream>
using namespace std;
void up_two();
int main()
{
for(int i = 0; i < 10; i++)
{
up_two();
}
return 0;
}
void up_two()
{
static int value = 0;
cout << value << endl;
value += 2;
}
This program doesn't solve the particular problem that you want to solve, but if you figure out how the static variable is working, it should make your workflow easier.
The magic line here is this:
static int value = 0;
With it like this my program prints the following:
0
2
4
6
8
10
12
14
16
18
Without the static declaration, you just get 10 lines of zeroes
which is troublesome.
Hope that helps you optimize your program the way you want it to be.
I try to check are my parameters are sorted. I have code but it doesn't work... Could you tell me what should I fix? I think the problem is in first loop because result can be 0 in the end of list of parameters. I don't know how should I change it, I try to make that: when atof(argv[i]) <= atof(argv[i + 1]) is not true, program should go to next for loop... It is my first C++ program.
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
int main(int argc, char *argv[])
{
int result;
for (int i = 1; i < argc - 1; i++) {
if (atof(argv[i]) <= atof(argv[i + 1])) {
result = 0;
}
}
if (result == 0) {
cout << "Sorted!" << endl;
system("pause");
}
for (int i = 1; i < argc - 1; i++) {
if (atof(argv[i]) >= atof(argv[i + 1])) {
result = 2;
}
}
if (result == 2) {
cout << "Sorted!" << endl;
system("pause");
}
else {
cout << "Bad." << endl;
system("pause");
}
system("pause");
return 0;
}
You will have to initialize result by changing int result; to int result = -1;.
Replace -1 with your desired initial value if you want.
Think about the first loop a little more. The logic you have says "if any number is less than the next number, set result to 0." So if you have a list like 5 3 4 2 1, then when 3 and 4 are compared, result will be set to 0. And because the remaining numbers are decreasing, the value of result will not change for the remainder of the loop.
One solution you may want to consider is to assume the list is sorted, then if a number is encountered that is not in sorted order, set result to -1 and break out of the loop.
I'm trying to write a program for university. The goal of the program is to make a nurse schedule for a hospital. However, i'm really stuck for the moment. Below you can find one function of the program.
The input for the function is a roster which consists of the shift each nurse has to perform on each day. In this example, we have 32 rows (32 nurses) and 28 columns (representing 28 days). Each cell contains a number from 0 to 6, indicating a day off (0) or a certain shift (1 to 6).
The function should calculate for each day, how many nurses are scheduled for a certain shift. For example, on the first day, there are 8 nurses which perform shift 2, 6 shift 3 and so forth. The output of the function is a double vector.
I think the function is mostly correct but when I call it for different rosters the program always gives the first roster gave.
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> nurses_per_shift;
int nbr_nurses_free = 0;
int nbr_nurses_shift1 = 0;
int nbr_nurses_shift2 = 0;
int nbr_nurses_shift3 = 0;
int nbr_nurses_shift4 = 0;
int nbr_nurses_shift5 = 0;
int nbr_nurses_shift6 = 0;
for (int j = 0; j < get_nbr_nurses(); j++)
{
if (roster1[j][i] == 0)
nbr_nurses_free += 1;
if (roster1[j][i] == 1)
nbr_nurses_shift1 += 1;
if (roster1[j][i] == 2)
nbr_nurses_shift2 += 1;
if (roster1[j][i] == 3)
nbr_nurses_shift3 += 1;
if (roster1[j][i] == 4)
nbr_nurses_shift4 += 1;
if (roster1[j][i] == 5)
nbr_nurses_shift5 += 1;
if (roster1[j][i] == 6)
nbr_nurses_shift6 += 1;
}
nurses_per_shift.push_back(nbr_nurses_shift1);
nurses_per_shift.push_back(nbr_nurses_shift2);
nurses_per_shift.push_back(nbr_nurses_shift3);
nurses_per_shift.push_back(nbr_nurses_shift4);
nurses_per_shift.push_back(nbr_nurses_shift5);
nurses_per_shift.push_back(nbr_nurses_shift6);
nurses_per_shift.push_back(nbr_nurses_free);
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
}
Here you can see the program:
Get_shift_assignment() and schedule_LD are other rosters.
void test_schedule_function()
{
calculate_nbr_nurses_per_shift(schedule_LD);
calculate_nbr_nurses_per_shift(get_shift_assignment());
calculate_coverage_deficit();
}
One more function you need to fully understand the problem is this one:
void calculate_coverage_deficit()
{
int deficit = 0;
for (int i = 0; i < get_nbr_days(); i++)
{
vector<int> deficit_day;
for (int j = 0; j < get_nbr_shifts(); j++)
{
deficit = get_staffing_requirements()[j] - nbr_nurses_per_shift_per_day[i][j];
deficit_day.push_back(deficit);
}
nurses_deficit.push_back(deficit_day);
}
cout << "Day 1, shift 1: there is a deficit of " << nurses_deficit[0][0] << " nurses." << endl;
cout << "Day 1, shift 2: there is a deficit of " << nurses_deficit[0][1] << " nurses." << endl;
cout << "Day 1, shift 3: there is a deficit of " << nurses_deficit[0][2] << " nurses." << endl;
cout << "Day 1, shift 4: there is a deficit of " << nurses_deficit[0][3] << " nurses." << endl;
}
So the problem is that each time I run this program it always gives me the deficits of the first roster. In this case, this is Schedule_LD. When I first run the function with input roster get_shift_assignment() than he gives me the deficits for that roster.
Apparently the nbr_nurses_per_shift_per_day[][] vector is not overwritten the second time I run the function and I don't know how to fix this... Any help would be greatly appreciated.
Let me try to summarize the comments:
By using global variables to return values from your functions it is very likely, that you forgot to remove older results from one or more of your global variables before calling functions again.
To get around this, return your results from the function instead.
Ex:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<int> nbr_nurses_per_shift_per_day; // Create the result vector
... // Do your calculations
return nbr_nurses_per_shift_per_day;
}
or if you do not want to return a vector:
void calculate_nbr_nurses_per_shift(vector<vector<int>> roster1, vector<vector<int>> nbr_nurses_per_shift_per_day)
{
... // Do your calculations
}
But clearly, the first variant is a lot less error-prone (in the second example you can forget to clear nbr_of_nurses again) and most compilers will optimize the return nbr_nurses_per_shift_per_day so the whole vector does not get copied.
The second possible issue is that ´get_nbr_days()´ might return numbers that are larger or smaller than the actual size of your vector. To work around this, use either the size() method of vector or use iterators instead.
Your first function would then look like this:
vector<vector<int>> calculate_nbr_nurses_per_shift(vector<vector<int>> roster1)
{
vector<vector<int>> nbr_nurses_per_shift_per_day;
for (vector<vector<int>>::iterator shiftsOnDay = roster1.begin(); shiftsOnDay != roster1.end(); ++shiftsOnDay)
{
vector<int> nurses_per_shift(6, 0); // Create vector with 6 elements initialized to 0
for (vector<int>::iterator shift = shiftsOnDay->begin(); shift != shiftsOnDay->end(); ++shift)
{
if (*shift == 0)
nurses_per_shift[5]++;
else
nurses_per_shift[*shift - 1]++; // This code relies on shift only containing meaningful values
}
nbr_nurses_per_shift_per_day.push_back(nurses_per_shift);
}
return nbr_nurses_per_shift_per_day;
}