My program stops looping and i cannot figure out why - c

if the user inputs the "value" as 1223445 the output should read as follows:
After change #1: 12235
After change #2: 135
the code is meant to take out two consecutive numbers with the same value. the first loop works but then it stops and I cannot figure why. here is the code:
{
int count;
int y;
int z;
int b;
int c;
int d;
int a;
int ct;
y = 0;
z = 1;
d = 0;
count = 0;
if (value > 0)
while ((z * 10 + z) != (y % 100))
{
y = value % 10 + y * 10;
z = y % 10;
value /= 10;
count = count + 1;
}
value = value * pow(10, count - 2);
y = y / 100;
count = count - 3;
while(y > 0)
{
b = y % 10;
c = pow(10, count);
d = d + c * b;
y = y / 10;
count = count - 1;
}
value = value + d;
ct = 1;
printf("After change #%d: %d\n", ct, value);
a = value;
while (a > 1)
{
if((a % 100) - (a % 10) - (10 * (a % 10)) == 0)
Change(value);
else
a = a / 10;
}
return;
}

Here's a simple solution: (not sure how you want to handle odd numbered repeats e.g. '111', '11111')
public static long strip(long value, long sum) {
if(value==0) return sum;
long tens = value % 100;
long ones = value % 10;
if(ones*10 == tens-ones) {
return strip(value /100, sum);
}
if(sum==0) sum +=(value%10);
else {
long x = (long)Math.ceil((Math.log10(sum)));
sum =(long) (Math.pow(10,x) * ones + sum);
}
return strip(value /10, sum);
}

Related

couldn't find out how to solve this algorithm problem

I am beginner I tried so many times but I couldn't solve this problem I will be very pleased if you help me...
the question is:
Let x be an integer, and R(x) is a function that returns the reverse of the x in terms of its digits.
For example , if x:1234 then R(x)=4321.
Let’s call a positive integer mirror-friendly if it satisfies the following condition: π‘₯ + 𝑅(π‘₯) = 𝑦^2 π‘€β„Žπ‘’π‘Ÿπ‘’ 𝑦 𝑖𝑠 π‘Žπ‘› π‘–π‘›π‘‘π‘’π‘”π‘’π‘Ÿ
Write a program that reads a positive integer as n from the user and prints out a line for each of the first n mirror-friendly integers as follows: x + R(x) = y^2
Example: If the user enters 5 as n, then the program should print out the following:
2 + 2 = 2^2
8 + 8 = 4^2
29 + 92 = 11^2
38 + 83 = 11^2
47 + 74 = 11^2
Here is the my code:
int
reverse(int num)
{
int reverse,
f,
i;
reverse = 0;
i = 0;
for (; i < num + i; i++) {
f = num % 10;
reverse = (reverse * 10) + f;
num /= 10;
}
return reverse;
}
int
sqrt(int n)
{
int i = 1;
int sqrt;
for (; i <= n; i++) {
sqrt = i * i;
}
return sqrt;
}
int
main()
{
int j = 1;
int main_num = 0;
for (; main_num <= 0;) {
printf("Please enter a positive integer: \n");
scanf_s("%d", &main_num);
}
int count = 0;
for (int i = 1; i <= main_num; i++) {
for (; j <= main_num; j++) {
if (j + reverse(j) == sqrt(?)) {
printf("%d + %d = %d\n", j, reverse(j), sqrt(?));
}
}
}
}
A few issues ...
sqrt does not compute the square root
reverse seems overly complicated
main_num (i.e. n from the problem statement) is the desired maximum count of matches and not the limit on x
Too many repeated calls to sqrt and reverse
No argument given to sqrt
The if in main to detect a match is incorrect.
sqrt conflicts with a standard function.
The variables you're using don't match the names used in the problem statement.
The printf didn't follow the expected output format.
Using a function scoped variable that is the same as the function is a bit confusing (to humans and the compiler).
Unfortunately, I've had to heavily refactor the code. I've changed all the variable names to match the names used in the problem statement for clarity:
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
int
reverse(int x)
{
int r = 0;
for (; x != 0; x /= 10) {
int f = x % 10;
r = (r * 10) + f;
}
return r;
}
int
isqrt(int x)
{
int y = 1;
while (1) {
int y2 = y * y;
if (y2 >= x)
break;
++y;
}
return y;
}
int
main(int argc,char **argv)
{
int n = -1;
--argc;
++argv;
if (argc > 0) {
n = atoi(*argv);
printf("Positive integer is %d\n",n);
}
while (n <= 0) {
printf("Please enter a positive integer:\n");
scanf("%d", &n);
}
int x = 1234;
dbgprt("x=%d r=%d\n",x,reverse(x));
int count = 0;
for (x = 1; count < n; ++x) {
dbgprt("\nx=%d count=%d\n",x,count);
// get reverse of number (i.e. R(x))
int r = reverse(x);
dbgprt("r=%d\n",r);
// get x + R(x)
int xr = x + r;
dbgprt("xr=%d\n",xr);
// get y
int y = isqrt(xr);
dbgprt("y=%d\n",y);
if (xr == (y * y)) {
printf("%d + %d = %d^2\n", x, r, y);
++count;
}
}
return 0;
}
Here is the program output:
Positive integer is 5
2 + 2 = 2^2
8 + 8 = 4^2
29 + 92 = 11^2
38 + 83 = 11^2
47 + 74 = 11^2
UPDATE:
The above isqrt uses a linear search. So, it's a bit slow.
Here is a version that uses a binary search:
// isqrt -- get sqrt (binary search)
int
isqrt(int x)
{
int ylo = 1;
int yhi = x;
int ymid = 0;
// binary search
while (ylo <= yhi) {
ymid = (ylo + yhi) / 2;
int y2 = ymid * ymid;
// exact match (i.e. x == y^2)
if (y2 == x)
break;
if (y2 > x)
yhi = ymid - 1;
else
ylo = ymid + 1;
}
return ymid;
}
UPDATE #2:
The above code doesn't scale too well for very large x values (i.e. large n values).
So, main should check for wraparound to a negative number for x.
And, a possibly safer equation for isqrt is:
ymid = ylo + ((yhi - ylo) / 2);
Here is an updated version:
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
// reverse -- reverse a number (e.g. 1234 --> 4321)
int
reverse(int x)
{
int r = 0;
for (; x != 0; x /= 10) {
int f = x % 10;
r = (r * 10) + f;
}
return r;
}
// isqrt -- get sqrt (linear search)
int
isqrt(int x)
{
int y = 1;
while (1) {
int y2 = y * y;
if (y2 >= x)
break;
++y;
}
return y;
}
// isqrt2 -- get sqrt (binary search)
int
isqrt2(int x)
{
int ylo = 1;
int yhi = x;
int ymid = 0;
// binary search
while (ylo <= yhi) {
#if 0
ymid = (ylo + yhi) / 2;
#else
ymid = ylo + ((yhi - ylo) / 2);
#endif
int y2 = ymid * ymid;
// exact match (i.e. x == y^2)
if (y2 == x)
break;
if (y2 > x)
yhi = ymid - 1;
else
ylo = ymid + 1;
}
return ymid;
}
int
main(int argc,char **argv)
{
int n = -1;
--argc;
++argv;
setlinebuf(stdout);
// take number from command line
if (argc > 0) {
n = atoi(*argv);
printf("Positive integer is %d\n",n);
}
// prompt user for expected/maximum count
while (n <= 0) {
printf("Please enter a positive integer:\n");
scanf("%d", &n);
}
int x = 1234;
dbgprt("x=%d r=%d\n",x,reverse(x));
int count = 0;
for (x = 1; (x > 0) && (count < n); ++x) {
dbgprt("\nx=%d count=%d\n",x,count);
// get reverse of number (i.e. R(x))
int r = reverse(x);
dbgprt("r=%d\n",r);
// get x + R(x)
int xr = x + r;
dbgprt("xr=%d\n",xr);
// get y
#ifdef ISQRTSLOW
int y = isqrt(xr);
#else
int y = isqrt2(xr);
#endif
dbgprt("y=%d\n",y);
if (xr == (y * y)) {
printf("%d + %d = %d^2\n", x, r, y);
++count;
}
}
return 0;
}
In the above code, I've used cpp conditionals to denote old vs. new code:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
Note: this can be cleaned up by running the file through unifdef -k
for(;i<num+i;i++)
is equal to
for(; 0<num;i++)
or for(; num;i++) if we are working with positive values only.
or even to while(num)
So, we don't need variable i in reverse function.
We don't need cycle at all in sqrt function. Just return n * n; is ok. But it is not sqrt then
The last cycle is too strange. At least variable j is not initialized.

Program in C , working with 3 digits but not working with 5 digits

145 = sum of 1! + 4! + 5!. I need to write a program in C, that finds the 5 digit numbers that have this property.
I have written the code successfully for the 3 digits. I used the same code for 5 digits, but it cant find any number.
I would like to help me with my solution, in order for me to see where am I wrong.
#include <stdio.h>
int factorial(int n);
main() {
int pin[5];
int q = 1;
int w = 0;
int e = 0;
int r = 0;
int t = 0;
int result = 0;
int sum = 0;
for (q = 1; q <= 9; q++) {
for (w = 0; w <= 9; w++) {
for (e = 0; e <= 9; e++) {
for (r = 0; r <= 9; r++) {
for (t = 0; t <= 9; t++) {
pin[0] = q;
pin[1] = w;
pin[2] = e;
pin[3] = r;
pin[4] = t;
int factq = factorial(q);
int factw = factorial(w);
int facte = factorial(e);
int factr = factorial(r);
int factt = factorial(t);
sum = factq + factw + facte + factr + factt;
result = 10000 * q + 1000 * w + 100 * e + 10 * r + t * 1;
if (sum == result)
printf("ok");
}
}
}
}
}
}
int factorial(int n) {
int y;
if (n == 1) {
y = 1;
} else if (n == 0)
y = 0;
else {
y = n * factorial(n - 1);
return y;
}
}
Your factorial function doesn't return a value in all cases:
int factorial (int n) {
int y;
if (n==1) {
y = 1;
}
else
if (n==0)
y = 0;
else {
y = n * factorial(n-1);
return y;
}
}
It only returns a value when it makes a recursive call. The base cases don't return anything. Failing to return a value from a function and then attempting to use that value invokes undefined behavior.
Move the return statement to the bottom of the function so it gets called in all cases. Also the value of 0! is 1, not 0.
int factorial (int n) {
int y;
if (n<=1)
y = 1;
else
y = n * factorial(n-1);
return y;
}
Also, when you find the target value you probably want to print it:
printf("ok: %d\n", result);
dbush's answer is accurate in pointing out why your code didn't work. This is an alternative solution to reduce the amount of calculation done by your program by not re-calculating the factorial of each numeral every step of the way. The way your program currently works, it winds up being around 500,000 calls to the factorial function from your nested loop, and then in turn recursively calls the function on average 4ish times for each call from the nested loop, so that's around 2 million calls to factorial. The more digits you tack on, the faster that number grows and more expensive it gets. To avoid all these recalculations, you can create a Look-up table that stores the factorial of the numerals [0-9] and just looks them up as needed.
You can calculate these values ahead of time and initialize your LUT with these values, but if hypothetically you wanted them to be calculated by the program because this is a programming assignment where you can't cut out such a step, it is still pretty trivial to populate the LUT.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
void populate_lut(uint32_t *lut);
int main(void) {
// lut is an array holding the factorials of numerals 0-9
uint32_t lut[10];
populate_lut(lut);
for (uint8_t q = 1; q <= 9; q++) {
for (uint8_t w = 0; w <= 9; w++) {
for (uint8_t e = 0; e <= 9; e++) {
for (uint8_t r = 0; r <= 9; r++) {
for (uint8_t t = 0; t <= 9; t++) {
// now instead of calculating these factorials, just look them up in the look-up table
uint32_t sum = lut[q] + lut[w] + lut[e] + lut[r] + lut[t];
uint32_t result = 10000 * q + 1000 * w + 100 * e + 10 * r + t * 1;
if (sum == result) {
printf("Solution: %" PRIu32 "\n", result);
}
}
}
}
}
}
}
// populate your lookup table with the factorials of digits 0-9
void populate_lut(uint32_t *lut) {
lut[0] = 1;
lut[1] = 1;
for(uint8_t i = 2; i < 10; ++i) {
lut[i] = lut[i-1] * i;
}
}

How can I specifically take out numbers in an integer, in C?

Lets say I have an integer called SIN and the scanf input receives 193456787.
so SIN = 193456787;
What I want to do is add up all the other numbers after the first digit.
So 9 + 4 + 6 + 8 = 27
Can somebody please explain to a beginner how to do this?
Print the number and then sum every other digit
int sum_every_other_digit_after_first(unsigned long long x) {
char buf[sizeof x * CHAR_BIT];
sprintf(buf, "%llu", x);
char *p = buf;
int sum = 0;
while (*p) {
p++; // Skip digit
if (*p) {
sum += *p++ - '0';
}
}
return sum;
}
or as inspired by #PageNotFound
int sum_every_other_digit_after_first(unsigned long long x) {
int esum = 0;
int osum = 0;
while (x > 0) {
esum += x%10;
x /= 10;
if (x == 0) {
return osum;
}
osum += x%10;
x /= 10;
}
return esum;
}
or for fun, a recursive solution
int sum_every_other_digit_after_first_r(unsigned long long x, int esum, int osum) {
if (x >= 100) {
int digit2 = x % 100;
esum += digit2 % 10;
osum += digit2 / 10
return sum_every_other_digit_after_first_r(x / 100, esum, osum);
}
if (x >= 10) {
return esum + x % 10;
}
return osum;
}
sum_every_other_digit_after_first_r(1234567,0,0) --> 12
My solution
#include <stdio.h>
int main()
{
int SIN = 193456787;
int a = 0, b = 0, cnt = 0;
while (SIN > 0) {
if (cnt % 2) b += SIN % 10;
else a += SIN % 10;
cnt++;
SIN /= 10;
}
printf("%d\n", cnt%2 ? b : a);
return 0;
}
Note: Please comment if this is not what you intended, as your question is a little ambigous.
#include <stdio.h>
int main() {
unsigned number;
scanf("%u\n", &number);
unsigned result = 0;
unsigned tmp = number;
unsigned numberOfDigits = 0;
do
numberOfDigits++;
while((tmp /= 10) != 0);
if(numberOfDigits % 2 != 0)
number /= 10;
while(number >= 10) {
result += number % 10;
number /= 100; // Skip two digits
}
printf("%u\n", result);
}

Expression Result Unused Greedy Algorithm

I have run this program and get the error expression result unused. I may be doing something simple wrong, but I have spent the day trying to figure it out to no avail. Any help you can provide is greatly appreciated.
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x - 25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10;
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5;
} y = y + 1;
if (x >= 1 && x < 5)
{ x - 1;
y= y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
if (x >= 25)
{
x - 25; // This accomplishes nothing
y = y + 1;
}
if (x >= 10 && x < 25)
{
x - 10; // This accomplishes nothing
} y = y + 1;
if (x >= 5 && x < 10)
{
x - 5; // This accomplishes nothing
} y = y + 1;
if (x >= 1 && x < 5)
{
x - 1; // This accomplishes nothing
y= y + 1;
}
In each of those lines you're subtracting a number from x, but you're doing nothing with the result. If you're trying to update x with the result, you need to do just like you're doing with y, and put x = in front of the expression.
So if you want x to go down by 25, you should write:
x = x - 25;
Alternatively, you can write the shorthand:
x -= 25; // Note the equal sign
All the 4 statements x - 25, x- 10, x- 5, x - 1 will turn out to be useless unless you assign that value to x;
Because you are trying to subtract the value from x, but you are not assigning the new value to x.
Here is the solution of your problem:
#include <stdio.h>
#include <cs50.h>
int main()
{
int x, y = 0;
printf("Enter the amount of change ");
x = GetFloat() * 100;
while (x != 0)
{
if (x >= 25)
{
x = x - 25; //or x-=25;
y = y + 1;
}
if (x >= 10 && x < 25)
{
x = x - 10; //or x-=10;
y = y + 1;
}
if (x >= 5 && x < 10)
{
x = x - 5; //or x-=5;
y = y + 1;
}
if (x >= 1 && x < 5)
{
x = x - 1; //or x-=1; or x--; or --x; :)
y = y + 1;
}
}
printf("The number of coins neccessary is %d", y);
}
I would remain to be convinced about your loop structure. There's the division operator that can be used to good effect:
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
ncoins = amount / 25;
total += ncoins;
amount -= ncoins * 25;
assert(amount < 25);
ncoins = amount / 10;
total += ncoins;
amount -= ncoins * 10;
assert(amount < 10);
ncoins = amount / 5;
total += ncoins;
amount -= ncoins * 5;
assert(amount < 5);
total += amount;
That's written out longhand; you could devise a loop, too:
int values[] = { 25, 10, 5, 1 };
enum { N_VALUES = sizeof(values) / sizeof(values[0]) };
int total = 0;
int ncoins;
int amount = GetFloat() * 100;
assert(amount >= 0);
for (int i = 0; i < N_VALUES && amount > 0; i++)
{
ncoins = amount / values[i];
total += ncoins;
amount -= ncoins * values[i];
}
assert(amount == 0);

Why this code works with visual studio on Windows 7 and doesnt work for linux correctly

long long int fun2(int a, int b, int m)
{
long long int res = 1;
long long int c = a % m;
for (int i = 1; i <= b; i <<= 1)
{
c = c % m;
if ((b & i) != 0)
{
res = res * c;
res = res % m;
}
c = c * c;
}
return res;
}
int fun(int num, int k)
{
srand((unsigned)time(NULL));
if (num <= 1)
{
return num * 10;
}
if (num == 2 || num == 3 || num == 5)
{
return num * 10 + 1;
}
if (num % 2 == 0)
{
return num * 10;
}
if (num % 3 == 0)
{
return num * 10;
}
if(num % 5 == 0)
{
return num * 10;
}
int s = 0;
int s_pow = 1;
while ((s_pow & (num - 1)) == 0)
{
s = s + 1;
s_pow = s_pow << 1;
}
int d = num / s_pow;
for (int i = 0; i < k; i++)
{
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
if (fun2(a, d, num) != 1)
{
is_prime = false;
for (int r = 0; r <= s - 1; r++)
{
if (fun2(a, (1 << r) * d, num) == num - 1)
{
is_prime = true;
break;
}
}
if (!is_prime)
{
return num * 10;
}
}
}
return num * 10 + 1;
}
Where is a problem, maybe these long long int with int compares doesnt work correctly.
Compilation for windows and linus is without any warnings. It works but gives bad results for linux, for windows is ok. Please help.
#EDIT
I deleted code with INT_MIN and INT_MAX I just tried to fix the problem with this. (Sorry, should have delete it)
Problem SOLVED by myself !!!! Imagine that problem was in random a. I exchange this
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
with this
int a = (int)(rand()%(num-1)) + 1;
and everything works perfect – user3144540

Resources