0

I am attempting a Hacker Rank problem for my Programming II class. I can either get the program to print the correct values but out of order, or it prints out the wrong values in the right order

I've tried nesting the loops inside one another in different ways to change the order, or to keep the first input variable value so it can be read by the second loop. So far I haven't gotten the desired result.

int main() 
{
int n;

for(int k = 0; k < 2; ++k)
{
    cin >> n;
    if(n == 1)
    {
        cout << "one\n";
    }
    else if(n == 2)
    {
        cout << "two\n";
    }
    else if(n == 3)
    {
        cout << "three\n";
    }
    else if(n == 4)
    {
        cout << "four\n";
    }
    else if(n == 5)
    {
        cout << "five\n";
    }
    else if(n == 6)
    {
        cout << "six\n";
    }
    else if(n == 7)
    {
        cout << "seven\n";
    }
    else if(n == 8)
    {
        cout << "eight\n";
    }
    else if (n >= 9)
    {
        cout << "nine\n";
    }
}
for(int j = 0; j < 2; j++)
{
    if(n % 2 == 0)
    {
        cout << "even\n";
    }
    else
    {
        cout << "odd\n";
    }
}


return 0;
}

Correct result with 8 and 11 used

eight
nine
even
odd

My result

eight
nine
odd
odd

  • 1
    What is the HackerRank problem task? – David G Aug 31 '19 at 15:37
  • 1
    Are you sure you'll need to use a nested loop at all to determine even/odd? – πάντα ῥεῖ Aug 31 '19 at 15:39
  • The HackerRank task is labeled CPSC S-1.2/Fall-2019. – BraindeadCowboy Aug 31 '19 at 15:40
  • By the time you get to the second loop you've lost the first `n`. Since we shouldn't have to go to a different site to see your problem description you should explain the goal of this code here. – Retired Ninja Aug 31 '19 at 15:40
  • 1
    Instead of that big if/else if consider using an array of strings that name the numbers. eg. std::string numbername[] = { "zero", "one", ...};` and later `cout << numbername[n] << '\n';` – user4581301 Aug 31 '19 at 15:41
  • I'm not sure that it's absolutely needed, but so far with the second loop outside the first the program deletes the first int value before the second loop can run. So instead of evaluating the first and second inputs, it only evaluates the second. – BraindeadCowboy Aug 31 '19 at 15:43
  • You are absolutely correct, sir. That is exactly what's happening. Now that you fully understand what's going on, you should know exactly what needs be done to change the logic. Good luck! – Sam Varshavchik Aug 31 '19 at 15:43
  • Are you trying to solve the same problem of this: https://stackoverflow.com/questions/57206276/what-is-the-difference-between-these-for-loops/57208380#57208380 ? – Bob__ Aug 31 '19 at 16:31
  • Open your favorite C++ reference to the chapter about the `switch` statement. IMHO, the `if-else-if` ladders are ugly and cumbersome to maintain (and takes more time to code). Usually the ladders are used when the index is not integral, like strings. – Thomas Matthews Aug 31 '19 at 17:40

4 Answers4

1

The problem with your code is that after 8 is accepted as input, it is not being saved any where since it is replaced by 11 as input. Hence after the end of the first for loop, n is still 11 and hence you get odd twice. Use arrays instead.

#include<iostream>

int main() 
{
int n;
int a[2],counter=0;
for(int k = 0; k < 2; ++k)
{
    std::cin >> n;
    a[counter++] = n;
    if(n == 1)
    {
        std::cout << "one\n";
    }
    else if(n == 2)
    {
        std::cout << "two\n";
    }
    else if(n == 3)
    {
        std::cout << "three\n";
    }
    else if(n == 4)
    {
        std::cout << "four\n";
    }
    else if(n == 5)
    {
        std::cout << "five\n";
    }
    else if(n == 6)
    {
        std::cout << "six\n";
    }
    else if(n == 7)
    {
        std::cout << "seven\n";
    }
    else if(n == 8)
    {
        std::cout << "eight\n";
    }
    else if (n >= 9)
    {
        std::cout << "nine\n";
    }
}
for(int k = 0;k<counter;k++){
    if(a[k] % 2 == 0)
    {
        std::cout << "even\n";
    }
    else
    {
        std::cout << "odd\n";
    }
}


return 0;
}
T.Square
  • 201
  • 3
  • 11
  • @πάνταῥεῖ actually I used this for c++ a long time back. Is there anything better in terms of functionality or practice? – T.Square Aug 31 '19 at 15:54
  • 1
    _"Is there anything better in terms of functionality or practice?"_ Sure, just don't use it: [1](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h), [2](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). – πάντα ῥεῖ Aug 31 '19 at 15:56
  • @πάνταῥεῖ Thanks :) didn't know about it in such depth. Edited. – T.Square Aug 31 '19 at 16:01
  • Ok that works. Thanks! I am absolute crap at dealing with arrays. – BraindeadCowboy Aug 31 '19 at 16:02
0

This loop:

for(int j = 0; j < 2; j++)
{
    if(n % 2 == 0)
    {
        cout << "even\n";
    }
    else
    {
        cout << "odd\n";
    }
}

is outside of your first loop.

And you don't really want a loop at all, just an if for even or odd.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • Thanks for responding. Unfortunately I've tried this too before I came here. While it does allow for both inputs to be evaluated correctly, now they print in the wrong order. – BraindeadCowboy Aug 31 '19 at 15:51
  • Whatever bugs you have, creating this loop isn't solving anything. – Paul Evans Aug 31 '19 at 15:54
  • @PaulEvans -- it's a peculiar question, and the loop is actually going in the right direction. The code is supposed to write out the names of **all** the values, **then** write out odd/even for all the values. So the code has to save something while going through the first loop, then do a second loop over the saved values. – Pete Becker Aug 31 '19 at 16:02
0

In the second loop you aren't checking both values, but just the last one(when you assign to n using std::cin the second time you are overwriting the first value). To solve this you could declare n as an array using the syntax int n[2]; and then iterate through it in your loops writing n[k] or n[j] (in this specific program, remember that n, j and k are arbitrary names). You don't really need nested loops in this case but they can easily be achieved and are often useful.The syntax is as follows:

for(int i = 0; i < 23; i++)
{
    /*bar*/
    for(int j = 0; j < 42; j++)
    {
        /*foo*/
    }
}

in this case bar is executed 23 times and foo is executed 23*42 time

When a program has different behaviour based on a variable's value, and you only need to check for equality but against many different values it is advisable to use the switch-case block instead of if and else if.

So if I personally had to write the program that you're writing I would do it like this:

#include <iostream>
int main()
{
using namespace std;

int n[2];
for(int k = 0; k < 2; ++k)
{
    cin >> n[k];
    switch(n[k])
    {
    case 1:
        cout << "one\n";
        break;
    case 2:
        cout << "two\n";
        break;
    case 3:
        cout << "three\n";
        break;
    case 4:
        cout << "four\n";
                break;
    case 5:
        cout << "five\n";
        break;
    case 6:
        cout << "six\n";
        break;
    case 7:
        cout << "seven\n";
        break;
    case 8:
        cout << "eight\n";
        break;
    default:
        if(n[k]>=9)
            cout << "nine\n";
        break;
    }
}
for(int j = 0; j < 2; j++)
    if(n[j] % 2 == 0)
        cout << "even\n";
    else
        cout << "odd\n";


return 0;
}
0

You could do this in one loop:

static char const * const number_names[] = 
{
  "zero", "one", "two", "three", "four",
  "five", "six", "seven", "eight", "nine"
};  

for (int k = 0; k < 2; ++k)
{
    std::cin >> k;
    if ((k >= 0) && (k < 10))
    {
        std::cout << number_names[k] << "\n";
    }
    else
    {
        std::cout << "number not within range\n";
    }
    if ((k%2) == 0)
    {
        std::cout << "even";
    }
    else
    {
        std::cout << "odd";
    }
    std::cout << "\n";
}

You can use the number as an index into an array of number-names. No need for switch or if-else-if ladders. Usually, online judges don't care about how the assignment is implemented. They have other criteria.

The even/odd test is included in the same loop. This eliminates the need to remember numbers (i.e. store them into an array).

The "\n" is common to both the even and odd printing, so it is factored out. (Sorry, but a habit from the olden days).

The array is declared as static because it is private and to indicate there is only one instance.

The array contains pointers that don't change, e.g. constant.
The array contains pointers that point to constant data.

An array of string literals is chosen so it can be directly accessed from the data area of the program, without going through an intermediate data structure like std::string.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154