Understanding number reversing using loop - c

i got into this simple program in c programing, the program is simply reversing any input number by user, using a while loop, i dont know if its okay to post such a question but i didnt realy understood how the while loop works
int n, reverse = 0;
printf("Enter a number to reverse\n");
scanf("%d",&n);
while (n != 0)
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
printf("Reverse of entered number is = %d\n", reverse);
i would be so thankfull if anyone could explain it to me

while(condition is true)
{
// Do stuff.
// Normally, but not always, the "stuff" we're doing is something that modifies
// the condition we're checking.
}
So in your case as long as the content of n is not equal to 0, you will continue to execute the loop. If 0 is entered in the scanf() the loop will be skipped altogether.
At each iteration of your loop you're using the property of integer division to make the value of n smaller by a factor of 10. ie:
n = 541
n = n / 10 = 541/10 = 54
n = n / 10 = 54/10 = 5
n = n / 10 = 5/10 = 0
So n will eventually be 0 and the loop will exit.

Related

Check if a number is a palindrome: if not sum the number and the number with reversed digits and continue checking

I´m learning C and doing the second task which is to check if an integer is a palindrome. If yes, I shall return the number; if not, I shall sum up the number and the number with reversed digits and check again.
Example:
Number: 195
195 + 591 = 786
786 + 687 = 1473
1473 + 3741 = 5214
5214 + 4125 = 9339 (is palindrome)
If the program has checked 20 times and it´s still not a palindrome, I shall return 0.
My program looks like this:
int addRev(int n) {
int count;
int reversed = 0;
int remain;
int original;
original = n;
while (n != 0) {
remain = n % 10;
reversed = reversed * 10 + remain;
n /= 10;
}
if (original==reversed){
return original;
}
else{
original+=reversed;
}
return original;
}
I have checked the program so far. If I test it with 191, it's a palindrome and returns it. If I test with 195, it is not a palindrome and the function returns 786.
But what is the next step? Do I need a second while() to continue with 786?
The key is a requrement to make up to 20 tests.
So the algorithm may look like this
for i = 1 up to 20
{
reversed = .......
if original == reversed
return original // it's a palindrome
original += reversed
}
return 0 // no palindrome after 20 iterations

My for loop seems to not be incrementing. It gets stuck on 2 (project euler 14)

I am working on project euler #14 :
Question:
The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
Problem:
When I run this code, the first for loop runs as expected. But then the variable num seems to not increment in the for loop and stays on 2 (which isn't even in the perameters of num I gave to start out with), giving the output:
2
0
1
1
repeating over and over again. Not sure why this is happening and can't find anything online.
Code:
#include <stdio.h>
int main() {
int maxcount = 0;
for (int num = 5; num < 2000000; num++) {
printf("%d\n0\n\n", num);
int count = 0;
while (num >= 1) {
count++;
if (num == 2) {
num = 1;
printf("1\n%d\n\n", count);
}
if (num > 1) {
if (num % 2 == 0) {
num = num / 2;
printf("%d\n%d\n\n", num, count);
}
else {
num = (3 * num) + 1;
printf("%d\n%d\n\n", num, count);
}
}
if (num == 1) {
break;
}
}
if (count > maxcount) {
maxcount = count;
}
}
printf("%d", maxcount);
return 0;
}
You need to introduce a new variable. You are doing:
for (int num = 5; num < 2000000; num++) {
/* collatz stuff, which modifies num, and eventually
causes it to become 1
*/
}
so when the num++ portion of the for loop runs, num becomes 2.
What you want is
for (int start = 5 ; start < 2000000 ; start++) {
int num = start;
/* collatz stuff, which modifies num */
}
since the variable start is never modified by the loop body, it will keep going up in sequence by 1, without interference.
In the while loop, you change the value of the loop variable (num).
You start with num = 5, and the inner while loop then follows Collatz's rules and gets to 1, at which point the while-loop ends.
Then the for-loop ends, and num is incremented to 2 by num++, and the next iteration of the loop begins.
In the second iteration, the while-loop immediately sees num == 2, so it sets num = 1, and the while loop ends. Then the for-loop ends, incrementing num to 2, and the cycle continues forever.
As others have said, you just need to leave the loop variable alone and use a different variable in the inner loop.

While loop condition reasoning, logic trouble, returning the sum of squares <= n (my first input

I'm having trouble with my logic and reasoning with a while loop, and returning the sum of positive numbers n, and the sum of inputs n squared. Please see my code and assist when possible, thank you.
The exercise was:
/* Write a short Java method that takes an integer n and returns the sum of the
squares of all positive integers less than or equal to n.
*
*/
public class ch1dot7
{
public static void main (String[]args)
{
Scanner input = new Scanner(System.in);
int n, m = 0, sum = 0;
System.out.print("Please enter a value for n: ");
n = input.nextInt();
System.out.println("n is currently: "+n);
if (n <= 0)
{
System.out.print("Please enter a value that is higher than 0 (integer)");
n = input.nextInt();
}
while (sum > n)
{
System.out.print("Please enter a value for m (enter a value greater than n to exit): ");
m = input.nextInt();
if (m < n)
{
sum += m*m;
System.out.println("sum of the squares is: " +sum);
}
sum += m*m;
}
}//end main
}//end class
You have misunderstood the assignment. The assignment does not ask you to take input from the user. The only input to the method is n.
The question is to make a method that takes an integer n and returns the sum of the squares of all positive integers less than n.
For example, if n is 5, you need to sum the squares of the numbers less than five which is to say the numbers 1 through 4 as follows:
(1*1) + (2*2) + (3*3) + (4*4)
1 + 4 + 9 + 16 = 30
Your method should return 30
In your while loop you are prompting the user for additional input and saving it in the variable m. This is not needed. The variable m is not needed.
Your while loop should continue while a counter variable is less than n and the counter should be incremented in each loop. Start the counter at 1 and continue to loop while that counter is less than n.
public static int sumOfSquares(int n) {
// here you can check if n is greater than 0
int counter = 1;
int sum = 0;
while (counter < n) {
// [ sum up the square of the counter ]
counter++;
}
return n;
}

Time complexity of a simple algorithm

Hello and sorry for my bad english.
I'm still trying to estimate a complexity of a following algorithm.
There is:
int f = 1, n, x, licznik = 0;
printf("Variable of n: ");
scanf("%d", &n);
printf("Variable of x: ");
scanf("%d", &x);
while(n > 0) {
if(n%2 == 0) {
x = x*x;
n = n/2;
licznik++;
}
else {
f = f*x;
n = n-1;
licznik++;
}
}
My observation:
When n = / then / licznik =
n = 0
l = 0
n = 10
l = 5
n = 100
l = 9
n = 1000
l = 15
n = 10000
l = 18
n = 1 000 000
l = 26
So it's still growing but very slowly. So it's looks like a "log n" function.
It's a good answer that time complexity for this algorithm is O(log n)? What about best option and the worst? Thanks for your help.
PS: "licznik" is a number of multiplications.
If n is an odd number you will always decrement it by one, making it even and guaranteeing that it will get divided into half in the next iteration.
In the worst case you get 2*log n which is O(log n) complexity.
Ok, lets take a wider look..
in your algorithm, once the value is halved and next time its decremented by 1.. since the decrement is almost negligible to the division (for very large values).. we can consider that the value (approximately) is just being divided once in 2 iterations.. Then the time complexity becomes `O(2logn).. which is really O(logn)..

Fastest way to calculate all the even squares from 1 to n?

I did this in c :
#include<stdio.h>
int main (void)
{
int n,i;
scanf("%d", &n);
for(i=2;i<=n;i=i+2)
{
if((i*i)%2==0 && (i*i)<= n)
printf("%d \n",(i*i));
}
return 0;
}
What would be a better/faster approach to tackle this problem?
Let me illustrate not only a fast solution, but also how to derive it. Start with a fast way of listing all squares and work from there (pseudocode):
max = n*n
i = 1
d = 3
while i < max:
print i
i += d
d += 2
So, starting from 4 and listing only even squares:
max = n*n
i = 4
d = 5
while i < max:
print i
i += d
d += 2
i += d
d += 2
Now we can shorten that mess on the end of the while loop:
max = n*n
i = 4
d = 5
while i < max:
print i
i += 2 + 2*d
d += 4
Note that we are constantly using 2*d, so it's better to just keep calculating that:
max = n*n
i = 4
d = 10
while i < max:
print i
i += 2 + d
d += 8
Now note that we are constantly adding 2 + d, so we can do better by incorporating this into d:
max = n*n
i = 4
d = 12
while i < max:
print i
i += d
d += 8
Blazing fast. It only takes two additions to calculate each square.
I like your solution. The only suggestions I would make would be:
Put the (i*i)<=n as the middle clause of your for loop, then it's checked earlier and you break out of the loop sooner.
You don't need to check and see if (i*i)%2==0, since 'i' is always positive and a positive squared is always positive.
With those two changes in mind you can get rid of the if statement in your for loop and just print.
Square of even is even. So, you really do not need to check it again. Following is the code, I would suggest:
for (i = 2; i*i <= n; i+=2)
printf ("%d\t", i*i);
The largest value for i in your loop should be the floor of the square root of n.
The reason is that the square of any i (integer) larger than this will be greater than n. So, if you make this change, you don't need to check that i*i <= n.
Also, as others have pointed out, there is no point in checking that i*i is even since the square of all even numbers is even.
And you are right in ignoring odd i since for any odd i, i*i is odd.
Your code with the aforementioned changes follows:
#include "stdio.h"
#include "math.h"
int main ()
{
int n,i;
scanf("%d", &n);
for( i = 2; i <= (int)floor(sqrt(n)); i = i+2 ) {
printf("%d \n",(i*i));
}
return 0;
}

Resources