C Code running fine on ideone, but getting WA in spoj - c

http://www.spoj.com/problems/MORENA/
Getting WA in spoj, running fine otherwise on ideone, for the test cases. any idea?
Earlier i wrote this in java, was getting NZEC. Wrote this in C then.
#include<stdio.h>
int main(){
int n,i;
scanf("%d",&n);
long num[n];
for(i=0;i<n;i++){
scanf("%ld",&num[i]);
}
int flag;
int l;
for(l=0;l<n;l++){
if(num[l+1] > num[l]){
flag = 1;
break;
}
else if(num[l+1] < num[l]){
flag = 0;
break;
}
}
int count = 1,k;
for(k =0; k<n-1; k++){
if(flag){
if (num[k+1] > num[k]){
count++;
flag = 0;
}
else if(num[k+1]==num[k]){
flag = 1;
}
else if(num[k+1]<num[k]){
//count++;
flag=1;
}
}
else{
if(num[k+1] < num[k]){
count++;
flag = 1;
}
else if(num[k+1]==num[k]){
flag = 0;
}
else if(num[k+1]>num[k]){
//count++;
flag = 0;
}
}
}
printf("%d",count);
return 0;
}

Wait what, MANY problems here.
Here are few, first:
int n,i;
scanf("%d",&n);
long num[n];
isn't possible (or isn't supposed to be possible at least) to declare an array in the size of a certain variable, use malloc() for that by doing so:
long* num = malloc(sizeof(long)*n);
Another problem, is that you cross the boundary of the array in the first loop, which is weird because you took care of it in the second one :P
Just change: for(l = 0 ; l < n ; l++) to for(l = 0 ; l < n-1 ; l++) as in your IF statement you use the array l+1 element, and when l is n-1 you actually test n-1 element compared to the Nth one - which isn't in the boundary of your array.
Other than that the code seems okay.

The question has strong bonds with competitive programming. Usually there is a problem displayed and user is expected to submit code which gives expected output for tested input for online judge, and SPOJ being one of them. And actually there is sample input and sample output displayed an almost all problems. So your code would give same output as shown in sample output for problem's sample input in ideone, but your code is tested to huge amount of data in online judge and that would result in NZEC.

Related

Getting an error only when two same odd numbers are adjacent in the array

THE PROBLEM
I am facing the problem when i was solving one of the leetcode question
Find Numbers with Even Number of Digits.
This is the code which i have written, the algorithm that i used here is using a for loop to iterate to all the array elements and then i declared the variables b=0 and l=10.then while using a while loop of condition (c!= nums[i]). The while loops happens until c(which is initialised it to nums[i]) is equal to array element.
then i check whether b%2==0 and increment integer ans
int findNumbers(int* nums, int numsSize){
int ans=0,c;
for (int i = 0; i < numsSize; ++i) {
int b=0,l=10;
while(c!=nums[i])
{
c=nums[i];
c=c%l;
l=l*10;
b++;
}
if(b%2==0 && nums[i]!=49916) {
ans++;
}
}
return ans;
}
If i take two odd digit numbers for suppose [78968,78968]. I am getting the output as 1 while the expected answer should be 0
Output for the above example
Excuse me if you had any difficulties understanding the questions. Learning to write better questions!
#include <stdio.h>
int findNumbers(int* nums, int numsSize){
int ans=0,c;
for (int i = 0; i < numsSize; ++i) {
int b=0,l=10;
c=0;
while(c!=nums[i])
{
c=nums[i];
c=c%l;
l=l*10;
b++;
}
if(b%2==0 && nums[i]!=49916)
{
ans++;
}
}
return ans;
}
int main()
{
int n[]={462,462};
printf("%d",findNumbers(n,2));
return 0;
}
This code should work for you. Actually the problem was when the loop was iterated first time the value of c will be 462 according to above code so while loop will not be iterated as c!=nums[i] will become false and value of b = 0 so if condition will become true so the value of ans will be incremented and you are getting answer as 1.

How to avoid SIGSEGV Error in Insertion Sort

I am trying to implement Insertion sort algorithm in C.
But all I get is SIGSEGV error in online IDEs and the output doesn't show up in Code::Blocks. How to avoid Such errors.
#include <stdio.h>
#include <stdlib.h>
int main()
{
/* Here i and j are for loop counters, temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter");
scanf("%d", &count);
int n[20];
printf("Enter %d elements", count);
// storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", n[i]);
}
// Implementation of insertion sort algorithm
for(i = 0; i < count; i++) {
temp = n[i];
j = i - 1;
while(temp < n[j]) {
n[j+1] = n[j];
j = j - 1;
}
n[j+1] = temp;
}
printf("Order of sorted elements");
for(i = 0; i < count; i++) {
printf("%d", n[i]);
}
return 0;
}
There are a couple of problems with your code. First of all, what is a SIGSEGV error? Well, it's another name for the good old Segmentation fault error, which is basically the error you get when accessing invalid memory (that is, memory you are not allowed to access).
tl;dr: change scanf("%d",n[i]); to scanf("%d",&n[i]);. You're trying to read the initial values with scanf("%d",n[i]);, this raises a segmentation fault error because scanf expects addresses in which put the values read, but what you're really doing is passing the value of n[i] as if it were an address (which it's not, because, as you did not set any value for it yet, it's pretty much just memory garbage). More on that here.
tl;dr: change int n[20]; to int n[count]. Your array declaration int n[20]; is going to store at most 20 integers, what happens if someone wants to insert 21 or more values? Your program reserved a certain stack (memory) space, if you exceed that space, then you're going to stumble upon another program's space and the police (kernel) will arrest you (segmentation fault). Hint: try inserting 21 and then 100 values and see what happens.
tl;dr: change for(i = 0; i < count; i++) { to for(i = 1; i <= count; i++) {. This one is a logic problem with your indexes, you are starting at i = 0 and going until i = count - 1 which would be correct in most array iteration cases, but as j assumes values of indexes before i, you need i to start from 1 (so j is 0, otherwise j = -1 in the first iteration (not a valid index)).
My final code is as follows. Hope it helped, happy coding!
#include <stdio.h>
#include <stdlib.h>
int main() {
/*Here i and j are for loop counters,temp for swapping
count for total number of elements,array for elements*/
int i, j, temp, count;
printf("How many numbers are you going to enter?\n");
scanf("%d",&count);
int n[count];
printf("Enter %d elements\n",count);
//storing elements in the array
for(i = 0; i < count; i++) {
scanf("%d", &n[i]);
}
//Implementation of insertion sort algorithm
for(i = 1; i <= count; i++) {
temp = n[i];
j = i-1;
while(temp < n[j]) {
n[j+1] = n[j];
j--;
}
n[j+1] = temp;
}
printf("Order of sorted elements\n");
for(i = 0; i < count; i++) {
printf("%d\n",n[i]);
}
return 0;
}
Edit: If you're having trouble with online IDEs, consider running your programs locally, it saves a lot of time, plus: you never know what kernel version or magic the online IDEs are using to run your code (trust me, when you're coding in C -- fairly low level language, these things make a difference sometimes). I like to go all root style using Vim as text editor and gcc for compiling as well as gdb for debugging.

While loop won't break as intended in C

I'm trying to learn how to program in C and have stumbled into a problem that seems like it should have been a simple fix, but it's giving me more issues then I anticipated. I'm trying to created a number guessing game, where you get three chances to guess the number, but my issue is that the Do While loop wont break when the right answer is guessed. Here is the function:
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
printf("winner\n");
}
}
} while(user_entry==lucky[i]||j<3);
}
Basically it's supposed to loop through the array lucky[i] and check to see if the user_entry equals any of the 20 numbers in the array. As of right now it loops through, recognizes if a winning number has been selected from the array, but doesn't break from the array.
when I change it to
}while(user_entry!=lucky[i]||j<3);
it completely ignores the counter and just loops forever.
I don't want to use break because everything I've read about it talks about it's poor programming practice. Is there another way to break, or have simply just made a mistake thats causing this issue.
Thanks in advance.
Consider for a second where your index variable "i" comes from. What happens to it after you've found a correct user entry? Where does the control flow go?
I would suggest having a look at the "break" keyword.
You wrote while (user_entry == lucky[i]..) which translates to as long as user_entry is equal to lucky[i] keep on looping. Which is clearly not what you intend to do.
Transform your condition to } while (user_entry != lucky[i] && j < 3); and you should be fine. This will translate in plain english to as long as user_entry is different of lucky[i] AND j is inferior to 3, keep looping.
But using this, you test on the value of lucky[i] even when i means nothing ( when i is equal to max, you don't want to test it, and this goes in the domain of undefined behavior).
But if you realy dont want to use break keyword, one solution is to use a flag. Set it to 1 before you start to loop, and change it to 0 when the good answer is found. Your code will become
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
char flag = 1;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
printf("winner\n");
flag = 0;
}
}
} while(flag&&j<3);
}
}while(user_entry!=lucky[i]||j<3);
That is bad logic - loop while the user's entry isn't the lucky number OR j is below three? Surely you actually want this:
}while(user_entry!=lucky[i]&&j<3);
This is only the solution to your second issue of it ignoring the counter - the main problem is solved in the other answers.
The only independent condition is that the user has more guesses left. try this while"
while(j <= 3);
The less than should be obvious, but the equals belongs there because you increment your j before the loop so it will be
j = 1 => first guess
j = 2 => second guess
j = 3 => third guess
After that the user should have no more guesses
You should find this doesn't work, that is because we want to exit the loop if the user guesses correctly. To do this, you can use a int as a bool (0-false, 1-yes).
void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
int j=0;
int exitCase = 0;
do {
j++;
printf("Please enter a number between 0 and 100\n");
scanf("%d",&user_entry);
for(i = 0; i < MAX; i++)
{
if(user_entry==lucky[i])
{
exitCase = 1;
printf("winner\n");
}
}
} while(exitCase == 0 || j <= 3);
}

why is my 3n+1 problem solution wrong

I have recently started reading "Programming Challenges" book by S. Skiena and believe or not I am kind of stuck in the very first problem.
Here's a link to the problem: 3n+1 problem
Here's my code:
#include <stdio.h>
long get_cycle(long input){
if (input == 1){
return 1;
}
else{
if (input & 1){
return 2 + get_cycle((3*input+1)>>1);
}
else{
return 1 + get_cycle(input >> 1);
}
}
}
long get_range_cycle(int k, int j){
int i;
int max = 0;
int current_cycle;
int to = k > j ? k : j;
int from = k < j ? k : j;
for (i=from; i<=to; ++i){
current_cycle = get_cycle(i);
if (current_cycle > max){
max = current_cycle;
}
}
return max;
}
int main(){
long p, q;
long re[100][3];
int i = 0;
while (scanf("%ld %ld",&p,&q) == 2){
re[i][0] = p;
re[i][1] = q;
re[i][2] = get_range_cycle(p,q);
++i;
}
int j;
for (j=0; j<i; ++j){
printf("%ld %ld %ld\n",re[j][0],re[j][1],re[j][2]);
}
}
what is wrong with my code? the input and out is exactly the same with sample.But the submission result is always run time error!
You're code seems to assume maximum 100 lines in the input file - the sample data they are testing on might be bigger? They make no explicit claim wrt the maximum set size of the input data.
I believe that the problem you seek answer for is in the answer #Elemental . If you fix that, however, your solution will time out.
What you should do is to build up a list of all answers between 0 and 1000000. This can be done in linear time (I will not give you the full answer).

Finding the largest palindrome of the product of two three digit numbers problem

So on Project Euler the Problem 4 states the following:
A palindromic number reads the same
both ways. The largest palindrome made
from the product of two 2-digit
numbers is 9009 = 91 99.
Find the largest palindrome made from
the product of two 3-digit numbers.
I have tried the following:
#include <stdio.h>
#include <stdlib.h>
int check(int result)
{
char b[7];
sprintf(b, "%d", result);
if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
{
return 1;
}
else
{
return 0;
}
}
int main () {
int i;
int g;
int final;
for (i = 999; i > 99; i--)
{
for (g = 999; g > 99; g--)
{
if (check(g*i) == 1)
{
final = g*i;
goto here;
}
}
}
here:
printf("%d", final);
}
But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.
Let me explain my program starting from int main:
int i and int g are my multipliers. They are those two three digit numbers.
int final is the number that will store the largest palindrome.
I start two for loops going to down to get every number possibility.
I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
The first palindrome should be the biggest one possible since I am counting down from the top.
Let me now explain my check:
First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that sprintf puts a \0 character at the end.
Ok, now that I have a char and all, I copied result (which i*g in int main) and put it in char b[7].
Then I just checked b to see if it equalled it self with by hard coding each slot I needed to check for.
Then I returned accordingly, 1 for true, and 2 for false.
This seems perfectly logical to me but, it does not work for some weird reason. Any hints?
This assumption is wrong:
The first palindrome should be the biggest one possible since I am counting down from the top.
You will check 999*100 = 99900 before 998*101 = 100798, so clearly you canĀ“t count on that.
The problem is that the first palindrome that you find is not the bigger one for sure.
Just an example:
i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800
The first one is smaller, but since you iterate first on i, then on g it will be discovered first.
Ok, they are not palindrome but the concept is the same..
I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.
e.g.
bool found = false;
for (int i = 998; i >= 100; i--)
{
char j[7];
sprintf(j,"%d",i);
j[3]= j[2];
j[4]= j[1];
j[5]= j[0];
int x =atoi(j);
int limit = sqrt((float) x);
for (int z = 999; z >= limit; z--)
{
if (x%z==0){
printf("%d",x);
found = true;
break;
}
}
if (found) break;
}
The first palindrome should be the biggest one possible since I am counting down from the top
The problem is that you might have found a palindrome for a large i and a small g. It's possible that there's a larger palindrome that's the product of j and k where:
i > j and
g < k
(I hope this makes sense).
Java Implementation:
public class Palindrome {
public static void main(String[] args)
{ int i, j;
int m = 1;
int k =11;
boolean flag = false;
while (true)
{;
if (flag) j = m + 1;
else j = m;
for (i = k; i > 0; i--)
{
j++;
int number, temp, remainder, sum = 0;
number = temp = (1000 - i) * (1000 - j);
while (number > 0)
{
remainder = number % 10;
number /= 10;
sum = sum * 10 + remainder;
}
if (sum == temp)
{
System.out.println("Max value:"+temp);
return;
}
}
if (flag)
m++;
k=k+11;
flag = !flag;
}
}
}
A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.
Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...
for (i = 999; i > 99; i--)
{
for (g = i; g > 99; g--)
{
...
However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...
Haven't tested it but I think you want something like this (pseudo code):
x = 999;
n = 0;
while (++n <= x)
{
j = x;
k = j - n;
while (j >= k)
{
y = j-- * k;
if (check(y))
stop looking
}
}
I found this article which might help you. It has improved brute force approach.
All the above provided answers are excellent, but still I could not restrict myself from writing the code. The code posted by #thyrgle is absolutely perfect. Only a slight correction which he needs to do is just check which product is the maximum.
The code can be as
int i,j,max=0,temp;
for(i=999;i>=100;i--){
for(j=i;j>=100;j--){
temp=i*j;
if(isPalin(temp) && temp>max){
max=temp;
}
}
}
cout<<max<<"\n";
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a[6];
void convertToString(int xy){
int i,t=100000;
for(i=0;i<6;i++){
a[i]=xy/t;
xy = xy % t;
t=t/10;
}
}
int check(){
int i;
for(i=0;i<3;i++){
if(a[i]!=a[6-i]){
return 0;
}
}
return 1;
}
void main(){
int x,y,xy,status=0;
int i=0,j=0,p=0;
for(x=999;x>99;x--){
for(y=x;y>99;y--){
xy=x*y;
convertToString(xy);
status = check();
if(status==1){
if(xy>p){
p=xy;
i=x;
j=y;
}
}
}
}
printf("\nTwo numbers are %d & %d and their product is %d",i,j,p);
}
x,y=999,999
k=0
pal=[]
while (y>99):
while (x>=100):
m=x*y
n=x*y
while (n!=0):
k=k*10+(n%10)
n=int(n/10)
if(m==k):
if k not in pal:
pal.append(k)
x=x-1
k=0
else:
y,x=y-1,999
pal.sort()
print(pal)
it gives 906609 as the largest palindrome number

Resources