I have a few loops that I need in my program. I can write out the pseudo code, but I\'m not entirely sure how to write them logically.
I need -
if (num is
For the first one, to check if a number is a multiple of use:
if (num % 10 == 0) // It's divisible by 10
For the second one:
if(((num - 1) / 10) % 2 == 1 && num <= 100)
But that's rather dense, and you might be better off just listing the options explicitly.
int getRow(int num) {
return (num - 1) / 10;
}
if (getRow(num) % 2 == 0) {
}
It's the same logic, but by using the function we get a clearer idea of what it means.
I know that this question has so many answers, but I will thrown mine here anyway...
Taken from Steve McConnell's Code Complete, 2nd Edition:
"Stair-Step Access Tables:
Yet another kind of table access is the stair-step method. This access method isn’t as direct as an index structure, but it doesn’t waste as much data space. The general idea of stair-step structures, illustrated in Figure 18-5, is that entries in a table are valid for ranges of data rather than for distinct data points.
Figure 18-5 The stair-step approach categorizes each entry by determining the level at which it hits a “staircase.” The “step” it hits determines its category.
For example, if you’re writing a grading program, the “B” entry range might be from 75 percent to 90 percent. Here’s a range of grades you might have to program someday:
To use the stair-step method, you put the upper end of each range into a table and then write a loop to check a score against the upper end of each range. When you find the point at which the score first exceeds the top of a range, you know what the grade is. With the stair-step technique, you have to be careful to handle the endpoints of the ranges properly. Here’s the code in Visual Basic that assigns grades to a group of students based on this example:
Although this is a simple example, you can easily generalize it to handle multiple students, multiple grading schemes (for example, different grades for different point levels on different assignments), and changes in the grading scheme."
Code Complete, 2nd Edition, pages 426 - 428 (Chapter 18).
With a couple of good comments in the code, it can be written quite concisely and readably.
// Check if it's a multiple of 10
if (num % 10 == 0) { ... }
// Check for whether tens digit is zero or even (1-10, 21-30, ...)
if ((num / 10) % 2 == 0) { ... }
else { ... }
A plea for readability
While you already have some good answers, I would like to recommend a programming technique that will make your code more readable for some future reader - that can be you in six months, a colleague asked to perform a code review, your successor, ...
This is to wrap any "clever" statements into a function that shows exactly (with its name) what it is doing. While there is a miniscule impact on performance (from "function calling overhead") this is truly negligible in a game situation like this.
Along the way you can sanitize your inputs - for example, test for "illegal" values. Thus you might end up with code like this - see how much more readable it is? The "helper functions" can be hidden away somewhere (the don't need to be in the main module: it is clear from their name what they do):
#include <stdio.h>
enum {NO, YES, WINNER};
enum {OUT_OF_RANGE=-1, ODD, EVEN};
int notInRange(int square) {
return(square < 1 || square > 100)?YES:NO;
}
int isEndOfRow(int square) {
if (notInRange(square)) return OUT_OF_RANGE;
if (square == 100) return WINNER; // I am making this up...
return (square % 10 == 0)? YES:NO;
}
int rowType(unsigned int square) {
// return 1 if square is in odd row (going to the right)
// and 0 if square is in even row (going to the left)
if (notInRange(square)) return OUT_OF_RANGE; // trap this error
int rowNum = (square - 1) / 10;
return (rowNum % 2 == 0) ? ODD:EVEN; // return 0 (ODD) for 1-10, 21-30 etc.
// and 1 (EVEN) for 11-20, 31-40, ...
}
int main(void) {
int a = 12;
int rt;
rt = rowType(a); // this replaces your obscure if statement
// and here is how you handle the possible return values:
switch(rt) {
case ODD:
printf("It is an odd row\n");
break;
case EVEN:
printf("It is an even row\n");
break;
case OUT_OF_RANGE:
printf("It is out of range\n");
break;
default:
printf("Unexpected return value from rowType!\n");
}
if(isEndOfRow(10)==YES) printf("10 is at the end of a row\n");
if(isEndOfRow(100)==WINNER) printf("We have a winner!\n");
}
You can try the following:
// Multiple of 10
if ((num % 10) == 0)
{
// Do something
}
else if (((num / 10) % 2) != 0)
{
// 11-20, 31-40, 51-60, 71-80, 91-100
}
else
{
// Other case
}
For the first one:
if (x % 10 == 0)
will apply to:
10, 20, 30, .. 100 .. 1000 ...
For the second one:
if (((x-1) / 10) % 2 == 1)
will apply for:
11-20, 31-40, 51-60, ..
We basically first do x-1
to get:
10-19, 30-39, 50-59, ..
Then we divide them by 10
to get:
1, 3, 5, ..
So we check if this result is odd.