0-1 sequences without repeating 1's - c

My task is to write a program, where the input is an exponent of 2, and the output is the number of sequences (out of the maximum 2^n sequences) where there are no 1's next to each other. (n<=50)
For example, on the input of 3, the output is 5, because 2^3=8 and out of the 8 possibilities the only acceptable ones are: (000, 001, 010, 100, 101) and (110,011,111) are not acceptable because there are 2 or more 1's next to each other.
My program works fine until 31, upon the number 32 it stops working, overflow issues I guess. I tried long int and unsigned int, none of those seemed to help.
#include <stdio.h>
#include <math.h>
main(){
int t,i,n,j,ki;
scanf("%d",&t);
for (i=1;i<=t;i++){
scanf("%d",&n);
ki=pow(2,n)-(n*(n-1))/2;
printf("Scenario #%d:\n%d\n\n",i,ki);
}
return 0;
}
Help me pl0x.

For variable ki:
Step #1: Use unsigned long long instead of int.
Step #2: Use 1<<n instead of pow(2,n).
Step #3: Use llu% instead of %d.
int main()
{
int t,i,n;
unsigned long long ki,one=1;
scanf("%d",&t);
for (i=1;i<=t;i++)
{
scanf("%d",&n);
ki = (one<<n)-n*(n-1)/2;
printf("Scenario #%d:\n%llu\n\n",i,ki);
}
return 0;
}

Related

Why is there a difference in run time when datatype used is 'long long int' as compared to 'int'? [duplicate]

This question already has answers here:
Project Euler Question 14 (Collatz Problem)
(8 answers)
Closed 3 years ago.
I was writing a program which involved input up to the range of 1 million, when I was using datatype 'int' to deal with my values the run time was very very high, the program never executed itself completely so I was not able to note down the run time.
code before;
#include<stdio.h>
int main()
{
int n,m,i,maxt=0,maxn;
for(n=2;n<=1000000;n++){
m=n;
i=0;
for(i=0;m!=1;i++){
if(m%2==0)
m=m/2;
else
m=(3*m+1);
}
if(i>maxt){
maxt=i;
maxn=n;
}
}
printf("%d%d",maxn,maxt);
return 0;
}
But then while juggling with the code I changed the datatype from 'int' to 'long long int' surprisingly the run time decreased drastically(milli seconds), can anyone explain what may be the reason behind this ?
code after;
#include<stdio.h>
int main()
{
long long int n,m,i,maxt=0,maxn;
for(n=2;n<=1000000;n++){
m=n;
i=0;
for(i=0;m!=1;i++){
if(m%2==0)
m=m/2;
else
m=(3*m+1);
}
if(i>maxt){
maxt=i;
maxn=n;
}
}
printf("%lld%lld",maxn,maxt);
return 0;
}
You are calculating the Collatz conjecture. For some numbers n as input, the m's can get very large. If m gets larger than 231, with a normal int, you get a negative number. To be more explicit: when m >= 231 and m < 232 a signed 32-bit value will be interpreted as a negative number: the computer can not see such difference when only working with 32-bit.
Negative numbers for m get caught in an endless loop never reaching the m == 1 end condition. Therefore, an int type of 64 bits is needed. On the wikipedia page, 3 different loops between negative numbers are shown, for example m=-1 becomes m=-2 which again becomes m=-1 in a never ending loop.
The first time m gets larger than 231 is for n=113383 where m reaches 2482111348.
To further clarify: the problem is not with n but with m in following loop.
m=n;
for(i=0;m!=1;i++){
if(m%2==0)
m=m/2;
else
m=(3*m+1);
}
For each n, this loop gets executed many times. m starts with getting the value of n, for example 113383. In this case, after 120 steps, m reaches 2482111348, which is so big it doesn't fit anymore in a 32-bit signed integer. On most modern processors, 2482111348 gets the same representation as -1812855948. The loop now continues further with negative values. After a while, it gets in an endless loop always repeating the same 18 numbers -17, -50, -25, ..., -34, -17. And never reaching the condition m==1 needed to stop the for-loop.
Here is a small modification to your code that works with gcc
#include<stdio.h>
#include<stdlib.h>
void overflow()
{
fprintf(stderr, "Overflow\n");
exit(1);
}
int main()
{
int n,m,i,maxt=0,maxn;
for(n=2;n<=1000000;n++){
m=n;
i=0;
for(i=0;m!=1;i++){
if(m%2==0)
m=m/2;
else {
int m_prev = m;
// Replacing m = (3*m+1) with operations that checks for
// overflow
if(__builtin_mul_overflow(m,3,&m)) {
printf("%d\n", m_prev);
printf("%d\n", INT_MAX);
overflow();
}
if(__builtin_add_overflow(m,1,&m))
overflow();
}
}
if(i>maxt){
maxt=i;
maxn=n;
}
}
printf("%lld%lld",maxn,maxt);
return 0;
}
If an overflow happens, it will print "overflow" and exit. And that's what's happening. What's happening is that the result of 3*m+1 gets too large for an int to hold, which overflows it.
You can read about those gcc functions here: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html

Is there a limit to how many characters in a row getchar can scan?

I have an assignment to make a program that calculates the iterative digital sum of an integer, eg. doing the digital sum until the result is a single digit. The catch is that the number they test for are much greater that can be stored in any int type (around 10^40000) so my idea was to do the first sum using getchar(), adding up the number digit by digit.
My code
#include <stdio.h>
int main(){
long int n=0;
int c;
//first sum
while((c=getchar())!=EOF && c!='\n'){
n+=(c-'0');
}
//iterative summing
long int s;
do{
s=0;
while(n>0){
s+=n%10;
n/=10;
}
n=s;
}while (n>=10);
printf("%ld\n",s);
return 0;
}
It worked for relatively short numbers, however after some point, the sum would come out wrong. So I tried setting up a variable that'd get incremented with each character summed, and it would always show the number of 4095.
So my question is, is there an 11-bit limit to how many characters you can get from stdin using getchar()? If so, is there a way to get more?

Hacker Rank : Project Euler#1

I am new to competitive programming and I did a problem on Hacker Rank. The question statement is as follows:
"If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below N.
Input Format
First line contains T that denotes the number of test cases. This is followed by T lines, each containing an integer, N.
Output Format
For each test case, print an integer that denotes the sum of all the multiples of 3 or 5 below N."
Constraints
1≤T≤10^5
1≤N≤10^9
I've written the following code which successfully satisfies 3 test cases and fails at remaining two.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int func(int p,int n)
{
int j;
n=n-1;
j=n/p;
return (p*j*(j+1))/2;
}
int main()
{
unsigned long int n;
int t,j,count;
scanf("%d",&t);
if(t>=1 && t<=100000){
for(j=0;j<t;j++)
{
scanf("%lu",&n);
if(n>=1 && n<=1000000000)
{
count=func(3,n)+func(5,n)-func(15,n);
printf("%d\n",count);
}
}}
return 0;
}
What is the mistake in my code. Why isn't it getting accepted?
There are a couple of issues.
You are indeed overflowing your int when returning from func. Also, your printf statement should be printf("%llu\n", count);
So, the return from func, count, and the local variable j, should all be unsigned long long and your print out should reflect that as well. You need to make j unsigned long long because of the arithmetic in the return statement for func(this is at least the case in VS 2013).

power int number while in loop

OK, so my task is to get a single digit from a natural number and sum the square numbers (Using function while, which means no arrays yet :S). For instance I type 123 so sum=1*100+2*10+3*1; However the problem is that the digit could be whatever. My problem is that the power rises with int but its like so - 1, 10, 99, 1000. The problem for me is 99. Also answer is looping but I'll fix it later. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int N,
number=0,
answer=0,
a=1,
i=0;
printf("Type natural number: ");
scanf("%d",&N);
while(N>i)
{
number=N%10;
N/=10;
a=10;
a=pow(a,i);
answer+=number*number*a;
printf("%d\n", answer);
i++;
}
return 0;
}
Try it the other way around. Don't make the input an integer. Start at the beginning of the stream, get the character, convert it to an int 'number'. Then do
answer = 10 * answer;
answer += (number * number);
This will build up your answer little by little. Note that I am not sure that this is what you are asking for due to your example not seeming to match the code.
Let me know if this is off-base and I will update it.

why < is much faster than !=?

Problem : Consider the following algorithm to generate a sequence of
numbers. Start with an integer n. If n is even, divide by 2. If n is
odd, multiply by 3 and add 1. Repeat this process with the new value
of n, terminating when n = 1. The input will consist of a series of
pairs of integers i and j, one pair of integers perline. All integers
will be less than 1,000,000 and greater than 0.
For each pair of
input integers i and j, output i, j in the same order in which they
appeared in the input and then the maximum cycle length for integers
between and including i and j. These three numbers should be separated
by one space, with all three numbers on one line and with one line of
output for each line of input.
sample input :
1 10
sample output:
1 10 20
so i wrote this :
#include <stdio.h>
#include <string.h>
struct line{int in1;int in2;int result;};
int cycle(int in);
int main(int argc, char *argv[]) {
int cycle(int in);
char c;
int firstIn=0;
struct line l[500] ;
int pointer=0;
while(2<3){
l[pointer].in1=0;
l[pointer].in2=0;
scanf("%u %u",&l[pointer].in1,&l[pointer].in2);
if(l[pointer].in1<1||l[pointer].in2<1){
break;
}
int maxCyc=0;
int j,m;
int min,max;
if(l[pointer].in1>l[pointer].in2){
max=l[pointer].in1;
min=l[pointer].in2;
}
else{
max=l[pointer].in2;
min=l[pointer].in1;
}
for(j=min;j<=max;j++){
m = cycle(j);
if(m>maxCyc)
maxCyc=m;
}
l[pointer].result=maxCyc;
printf("%d %d %d\n",l[pointer].in1,l[pointer].in2,l[pointer].result);
pointer++;
}
}
int cycle(int in){
int cyc = 1;
while(in>1){
if(in%2==0){
cyc++;
in=in/2;
}
else{
cyc++;
in=in*3+1;
}
}
return cyc;
}
Its completly ok but when you change while(in>1) in cycle method to while(in!=1) it gets much more slower. my question is why?!
Time when its while(in>1) : 0.683 sec
and when its while(in!=1) : I waited more than 5 min nothing
happened yet :)
for input : 1 1000000
there is no infinite loop or something because in cant get below 1 at all(for that it must be already 1) .
Best regards
When you call cycle with the input value 113383, the process eventually sets n to
827370449, and 3*827370449+1 is 2482111348, which is greater than the maximum signed int and is interpreted as -1812855948. So there's your first negative number where there should be no negative number.
If this process then eventually sets n to -2, it will loop infinitely between -2 and -1 from then on. There may be other loops I haven't considered.
If you were to use an unsigned int, there is a possibility (I haven't checked) that this too will overflow eventually, which will not result in a negative value but will result in an incorrect value, invalidating your results.
No matter what integer representation you use, it would probably be a good idea to compare n with (maximum-1)/3 at the top of each loop, where maximum is the largest possible positive value of your integer type, just to be sure you do not overflow.
As you told me it was a simple overflow problem thx everyone.
max int value is 2,147,483,647; So when i changed int cycle(int in) to int cycle(long long int in) my problem was solved.
i also figured it out that my first answer with while(in>1) was wrong.
When an integer overflow occurs,the value will go below 0 .That was the reason while(in!=1) was an infinte loop.
I was really tired that i didn't figure it out by myself. sorry for that :)

Resources