Basically, how it works is it converts a number into a string, and if it finds any even in the string then it gives foundEven variable a positive value. The same goes for odd numbers.
(One thing I don't get is why if I switch the '>' sign with an '<' in if (FoundEvenSignedInt < FoundOddSignedInt) it gives you the correct result of an odd number.)
Are there any ways I could improve the code? Are there any bugs in it? I'm fairly new at C++ programing.
#include <string>
#include <cstddef>
int IsPrime(long double a)
{
int var;
long double AVar = a;
signed int FoundEvenSignedInt, FoundOddSignedInt;
std::string str = std::to_string(a);
std::size_t foundEven = str.find_last_of("2468");
std::size_t foundOdd = str.find_last_of("3579");
FoundEvenSignedInt = foundEven;
FoundOddSignedInt = foundOdd;
if (FoundEvenSignedInt < FoundOddSignedInt)
{
var = 1;
goto EndOfIsPrimeFunction;
}
if (FoundEvenSignedInt > FoundOddSignedInt)
{
var = 2;
goto EndOfIsPrimeFunction;
}
// This if statement kept giving me this weird warning so I made it like this
if (FoundEvenSignedInt == -1)
{
if (FoundOddSignedInt == -1)
{
if (AVar == 10 || 100 || 1000 || 10000 || 100000 || 1000000)
{
var = 2;
goto EndOfIsPrimeFunction;
}
}
}
EndOfIsPrimeFunction:
return var;
}
Here are some ways to improve the code.
The Collatz conjecture is about integers. long double is a data type of floating point numbers. It is unsuitable for checking the conjecture. You need to work with an integral data type such as unsigned long long. If this doesn't have enough range for you, you need to work with some kind of Bignum dat atype. There isn't any in the standard C library, you need to find a third party one.
The Collatz conjecture has nothing to do with being prime. It is about even and odd integers. It is true that all prime numbers except 2 are odd, but this fact doesn't help you.
The data type to answer yes/no questions in C++ is bool. By convention. for any other numeric data type zero means "no" and all other values mean "yes" (technically, when converted to bool, zero is converted to false and other values to true, so you can do things like if (a % 2). A function that returns 1 and 2 for yes and no is highly unconventional.
A natural method of checking whether a number is odd is this:
bool isOdd (unsigned long long a)
{
return a % 2;
}
It is somewhat faster than your code (by a factor of about 400 on my computer), gives correct results every time, is readable, and has zero goto statements.
Instead of the if(AVar == 10 || 100 || ..., you can say if(!(AVar % 10)).
Quick explanation:
I want to assign random numbers to words, in a way so every letter has different number. for convenience purposes I have used arrays instead of separate one letter variables; this way I know that "abc[1]" is letter 'b' from word "abc". The first number of a word is using different range to avoid having numbers like "075"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int abc[2];
int def[2];
void setRandom()
{
abc[0] = rand() %9+1;
do {abc[1] = rand() %10;} while (abc[1] == abc[0]);
do {abc[2] = rand() %10;} while (abc[2] == abc[1] || abc[2] == abc[0]);
printf("RANDOM abc %d %d %d", abc[0], abc[1], abc[2]); //printed just fine.
do {def[0] = rand() % 9 +1; } while (def[0] == abc[2] || def[0] == abc[1] || def[0] == abc[0]); //code seems to be stuck here
do {def[1] = rand() %10;} while (def[1] == def[0] || def[1] == abc[2] || def[1] == abc[1] || def[1] == abc[0]);
do {def[2] = rand() %10;} while (def[2] == def[1] || def[2] == def[0] || def[2] == abc[2] || def[2] == abc[1] || def[2] == abc[0]);
printf("RANDOM def %d %d %d", def[0], def[1], def[2]); //THIS CODE IS NEVER REACHED. WHY?
}
int main ()
{
setRandom();
printf("RANDOM SET");
}
I am aware that the numbers are not truly random. I am aware that the code is messy. I am aware it's innefficient to brute-force numbers. I am aware that this way of setting numbers is bad, but I couldn't think of anything better. This code will do the job for my purposes.
The problem is that the above code gets stuck while generating number for def[0]; it will infinitely generate new random numbers, it seems to be completely ignoring 'while' part of the loop.
You may either suggest a better method of doing what I'm trying to do, or simply a solution to the problem, either will do just fine since the project isn't anything big, it's just used as puzzle solver.
The problem is that you've chosen the wrong size for your arrays. def[0] and abc[2] most likely point to the same location.
Specifically, you're creating arrays of size 2, and then accessing 3 elements of them. Change:
int abc[2];
int def[2];
to:
int abc[3];
int def[3];
See also this answer as to a better way to do what you're trying to do.
Arrays in C/C++ are zero-based. creating abc[2] give you only 0 and 1 to legitimately access. Anything beyond the end of the array is undefined behaviour - in this case it's probable that abc[2] (the third, not second element) points to def[0].
Fix your code so that both declarations allocate 3 elements instead of 2.
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 a multiple of 10) { do this }
if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90
This is for a snakes and ladders board game, if it makes any more sense for my question.
I imagine the first if statement I'll need to use modulus. Would if (num == 100%10) be correct?
The second one I have no idea. I can write it out like if (num > 10 && num is < 21 || etc.), but there has to be something smarter than that.
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.
Now that you've given a better idea of what you are doing, I'd write the second one as:
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.
if (num is a multiple of 10) { do this }
if (num % 10 == 0) {
// Do something
}
if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
The trick here is to look for some sort of commonality among the ranges. Of course, you can always use the "brute force" method:
if ((num > 10 && num <= 20) ||
(num > 30 && num <= 40) ||
(num > 50 && num <= 60) ||
(num > 70 && num <= 80) ||
(num > 90 && num <= 100)) {
// Do something
}
But you might notice that, if you subtract 1 from num, you'll have the ranges:
10-19, 30-39, 50-59, 70-79, 90-99
In other words, all two-digit numbers whose first digit is odd. Next, you need to come up with a formula that expresses this. You can get the first digit by dividing by 10, and you can test that it's odd by checking for a remainder of 1 when you divide by 2. Putting that all together:
if ((num > 0) && (num <= 100) && (((num - 1) / 10) % 2 == 1)) {
// Do something
}
Given the trade-off between longer but maintainable code and shorter "clever" code, I'd pick longer and clearer every time. At the very least, if you try to be clever, please, please include a comment that explains exactly what you're trying to accomplish.
It helps to assume the next developer to work on the code is armed and knows where you live. :-)
If you are using GCC or any compiler that supports case ranges you can do this, but your code will not be portable.
switch(num)
{
case 11 ... 20:
case 31 ... 40:
case 51 ... 60:
case 71 ... 80:
case 91 ... 100:
// Do something
break;
default:
// Do something else
break;
}
This is for future visitors more so than a beginner. For a more general, algorithm-like solution, you can take a list of starting and ending values and check if a passed value is within one of them:
template<typename It, typename Elem>
bool in_any_interval(It first, It last, const Elem &val) {
return std::any_of(first, last, [&val](const auto &p) {
return p.first <= val && val <= p.second;
});
}
For simplicity, I used a polymorphic lambda (C++14) instead of an explicit pair argument. This should also probably stick to using < and == to be consistent with the standard algorithms, but it works like this as long as Elem has <= defined for it. Anyway, it can be used like this:
std::pair<int, int> intervals[]{
{11, 20}, {31, 40}, {51, 60}, {71, 80}, {91, 100}
};
const int num = 15;
std::cout << in_any_interval(std::begin(intervals), std::end(intervals), num);
There's a live example here.
The first one is easy. You just need to apply the modulo operator to your num value:
if ( ( num % 10 ) == 0)
Since C++ is evaluating every number that is not 0 as true, you could also write:
if ( ! ( num % 10 ) ) // Does not have a residue when divided by 10
For the second one, I think this is cleaner to understand:
The pattern repeats every 20, so you can calculate modulo 20.
All elements you want will be in a row except the ones that are dividable by 20.
To get those too, just use num-1 or better num+19 to avoid dealing with negative numbers.
if ( ( ( num + 19 ) % 20 ) > 9 )
This is assuming the pattern repeats forever, so for 111-120 it would apply again, and so on. Otherwise you need to limit the numbers to 100:
if ( ( ( ( num + 19 ) % 20 ) > 9 ) && ( num <= 100 ) )
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 { ... }
You basically explained the answer yourself, but here's the code just in case.
if((x % 10) == 0) {
// Do this
}
if((x > 10 && x < 21) || (x > 30 && x < 41) || (x > 50 && x < 61) || (x > 70 && x < 81) || (x > 90 && x < 101)) {
// Do this
}
You might be overthinking this.
if (x % 10)
{
.. code for 1..9 ..
} else
{
.. code for 0, 10, 20 etc.
}
The first line if (x % 10) works because (a) a value that is a multiple of 10 calculates as '0', other numbers result in their remainer, (b) a value of 0 in an if is considered false, any other value is true.
Edit:
To toggle back-and-forth in twenties, use the same trick. This time, the pivotal number is 10:
if (((x-1)/10) & 1)
{
.. code for 10, 30, ..
} else
{
.. code for 20, 40, etc.
}
x/10 returns any number from 0 to 9 as 0, 10 to 19 as 1 and so on. Testing on even or odd -- the & 1 -- tells you if it's even or odd. Since your ranges are actually "11 to 20", subtract 1 before testing.
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");
}
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.
As others have pointed out, making the conditions more concise won't speed up the compilation or the execution, and it doesn't necessarily help with readability either.
It can help in making your program more flexible, in case you decide later that you want a toddler's version of the game on a 6 x 6 board, or an advanced version (that you can play all night long) on a 40 x 50 board.
So I would code it as follows:
// What is the size of the game board?
#define ROWS 10
#define COLUMNS 10
// The numbers of the squares go from 1 (bottom-left) to (ROWS * COLUMNS)
// (top-left if ROWS is even, or top-right if ROWS is odd)
#define firstSquare 1
#define lastSquare (ROWS * COLUMNS)
// We haven't started until we roll the die and move onto the first square,
// so there is an imaginary 'square zero'
#define notStarted(num) (num == 0)
// and we only win when we land exactly on the last square
#define finished(num) (num == lastSquare)
#define overShot(num) (num > lastSquare)
// We will number our rows from 1 to ROWS, and our columns from 1 to COLUMNS
// (apologies to C fanatics who believe the world should be zero-based, which would
// have simplified these expressions)
#define getRow(num) (((num - 1) / COLUMNS) + 1)
#define getCol(num) (((num - 1) % COLUMNS) + 1)
// What direction are we moving in?
// On rows 1, 3, 5, etc. we go from left to right
#define isLeftToRightRow(num) ((getRow(num) % 2) == 1)
// On rows 2, 4, 6, etc. we go from right to left
#define isRightToLeftRow(num) ((getRow(num) % 2) == 0)
// Are we on the last square in the row?
#define isLastInRow(num) (getCol(num) == COLUMNS)
// And finally we can get onto the code
if (notStarted(mySquare))
{
// Some code for when we haven't got our piece on the board yet
}
else
{
if (isLastInRow(mySquare))
{
// Some code for when we're on the last square in a row
}
if (isRightToLeftRow(mySquare))
{
// Some code for when we're travelling from right to left
}
else
{
// Some code for when we're travelling from left to right
}
}
Yes, it's verbose, but it makes it clear exactly what's happening on the game board.
If I was developing this game to display on a phone or tablet, I'd make ROWS and COLUMNS variables instead of constants, so they can be set dynamically (at the start of a game) to match the screen size and orientation.
I'd also allow the screen orientation to be changed at any time, mid-game - all you need to do is switch the values of ROWS and COLUMNS, while leaving everything else (the current square number that each player is on, and the start/end squares of all the snakes and ladders) unchanged.
Then you 'just' have to draw the board nicely, and write code for your animations (I assume that was the purpose of your if statements) ...
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
}
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).
I am trying to solve problem PLD on SPOJ, but I'm getting a WA on the 9th testcase.
My Approach:
I am implementing Manacher's Algorithm and I believe that if something wrong is there, then it can be wrong in this code.
if((k%2==0)&&(p[i]>=k)&&(temp[i]=='#'))
count++;
if((k%2==1)&&(p[i]>=k)&&(temp[i]!='#'))
count++;
But according to my approach if character is #, then the maximum length of palindromic string centered at it can be even only, so if p[i] >= k, then I am increasing count if we are finding a palindromic string of even length.
Similarly for characters [considering input character i.e other than #] centered at i-th location but for odd length strings.
#include<stdio.h>
#include<string.h>
char a[30002],temp[60010];
int p[60010];
int min(int a,int b)
{
if(a<b)
return a;
return b;
}
int main()
{
//freopen("input.txt","r+",stdin);
//freopen("a.txt","w+",stdout);
int k,len,z;
scanf("%d",&k);
getchar();
gets(a);
len=strlen(a);
//Coverting String
temp[0]='$';
temp[1]='#';
z=2;
for(int i=1;i<=len;i++)
{
temp[z++]=a[i-1];
temp[z++]='#';
}
len=z;
int r=0,c=0,check=0,idash,t,count=0;
for(int i=1;i<len;i++)
{
check=0;
idash=c-(i-c);
p[i]=r>i?min(r-i,p[idash]):0;
t=p[i];
while(temp[i+p[i]+1]==temp[i-1-p[i]])
p[i]++;
if(r<i+p[i])
{
c=i;
r=i+p[i];
}
if((k%2==0)&&(p[i]>=k)&&(temp[i]=='#'))
count++;
if((k%2==1)&&(p[i]>=k)&&(temp[i]!='#'))
count++;
}
printf("%d",count);
//getchar();
//getchar();
return 0;
}
You may want to take advantage of C++ short-circuit evaluation of logical expressions.
For example, rearrange the order so you check for '#' first:
if ((temp[i] == '#') && (k % 2 == 0) && (p[i] >= k))
In the above rearrangement, if the character is not '#', none of the other expressions are evaluated.
You may want to extract (p[i] >= k) to an outside if statement since it is common to both:
if (p[i] >= k)
{
if ((temp[i] == '#') && (k % 2 == 0)) ++count;
if ((temp[i] != '#') && (k % 2 == 1)) ++count;
}
The above modification will result in only one evaluation of the expression (p[i] >= k).
Also examine your for loop to see if there are statements or expressions that don't change or are repeated. If a statement or expression doesn't change inside the loop, it is called an invariant, and can be moved before or after the loop.
Statements or expressions that are duplicated (such as array index calculations) can be evaluated and stored in a temporary variable. Although good compilers may do this (depending on the optimization level), in your performance requirements, you may want to help out the compiler.
Another suggestion is to replace p[i] with a pointer to the location or a reference to the location. Again, this is to help out the compiler when the optimization is not set optimally:
int& p_slot_i = p[i]; // This syntax needs checking
// or
int * p_slot_i = &p[i];
//...
t = *p_slot_i;
while(temp[i + *p_slot_i + 1] == temp[i - 1 - *p_slot_i)
{
*p_slot_i++;
}
Lastly, Elimination of spaces, blank lines and curly braces DOES NOT AFFECT PROGRAM PERFORMANCE. A program that is one line or spaced across multiply lines will have the exact assembly translation and the exact performance. So please, add spaces, blank lines and curly braces to improve readability.
Edit 1: performance of min()
You may want to declare you min() function as inline to suggest to the compiler you want the function pasted where it is called, rather than calling the function. Function calls slow down a programs execution.
gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.