As a new learner of C, I managed to go this far in this little exercice, the code works (kind of). It doesn't work for the second time, the output just adds up.
int i = 0;
void inverse(unsigned int n) {
int reste;
if (n != 0) {
reste = n % 10;
i = (i * 10) + reste;
inverse(n / 10);
} else {
printf("%d \n", i);
}
}
void main() {
inverse(1589);
inverse(42);
}
Output:
9851
985124
Your approach fails because i is not cleared before each new case. You could clear i after the printf, but a better approach is to avoid global variables. You can modify inverse for this purpose by removing the recursion:
#include <stdio.h>
void inverse(unsigned int n) {
unsigned int i = 0;
while (n != 0) {
unsigned int reste = n % 10;
i = i * 10 + reste;
n = n / 10;
}
printf("%u\n", i);
}
int main() {
inverse(1589);
inverse(42);
return 0;
}
Note these remarks:
you must include <stdio.h> to use printf()
main return type is int.
for consistency, i should have type unsigned int.
Some numbers will produce incorrect output as their inverse exceeds the range of unsigned int eg: 1000000009. You can remove this shortcoming by printing the digits instead of combining them as a number:
void inverse(unsigned int n) {
while (n > 9) {
putchar('0' + n % 10);
n = n / 10;
}
putchar('0' + n);
putchar('\n');
}
You need to reset i at some point. The most straight forward and horrible way is to simply do it after the printf().
But you should better redesign the recursion to work without global variables. Which is not easily done with any similarity to the shown code.
This is (I realised a little late) more or less what luk2302 recommended in a comment on a deleted answer.
#include <stdio.h>
int i = 0;
void inverse(unsigned int n){
int reste;
if (n != 0) {
reste = n % 10;
i = (i * 10) + reste;
inverse(n / 10);
}
else {
printf("%d \n", i);
i=0;
}
}
void inverse2(int number, int reversed)
{
if (number < 1)
{
printf("%d \n",reversed);
} else
{
inverse2(number/10, reversed*10+number%10);
}
}
void main(){
inverse(1589);
inverse(42);
inverse(123);
inverse2(1589,0);
inverse2(42,0);
inverse2(123,0);
}
Output:
9851
24
321
9851
24
321
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm stuck on an basic algorithmic issue and I can't figure out how to solve it.
Basically I wanna list all numbers that are proper descendants of an integer. That is to say, if my number is 21, I want to use its binary representation (10101) and list all numbers which have at least one common bit of value 1 with 21 and are lower than 21. The result here should be 10100, 10001, 10000, 101, 100, 1.
The mathematical definition of proper descendants is as follows:
Let h be a nonnegative number less than 2^m. h = d0 + d1*2^1 + ... + dm-1*2^(m-1) where di = 0 or 1.
Let h' be another nonnegative such as h' = d0' + d1'*2^1 + ... + dm-1'*2^(m-1) where di' = 0 or 1.
h' is a descendant of h if di'<=di for 0<=i<m
I've tried many implementations in both Python and C and tried the old pen and paper technique, but all of them failed. I know it's rather simple but I can't seem to figure it out. I'm coding in C so if you find a solution that works in C that would be ideal, but I'd take anything right now.
Here is a very simple approach: enumerate all integers between n-1 and 1 and print those that are strictly included in n, ie: (i & n) == i.
void list_descendants(int n) {
printf("descendants of %d:", n);
for (int i = n; i --> 1;) {
if ((i & n) == i)
printf(" %d", i);
}
printf("\n");
}
Ok so I finally came up with a code in C that is far from good looking and probably horribly optimised but still works as intended. There are probably much simpler solutions but here is mine for knowledge purposes :
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
unsigned int pui(unsigned int a, unsigned int b)
{
if (b == 0)
return 1;
if (b == 1)
return a;
if (b % 2 == 0)
return pui(a * a, b / 2);
else
return pui(a * a, (b - 1) / 2);
}
unsigned int testBit(unsigned int h, unsigned int offset)
{
unsigned int mask = 1 << offset;
return (h & mask);
}
bool isInList(unsigned int x, unsigned int *output_size, unsigned int **output)
{
for (int i = 0; i < *output_size; i++)
{
if (*(*output + i) == x)
{
return true;
}
}
return false;
}
void listDescendants(unsigned int h, unsigned int *output_size, unsigned int **output, int *currently_processing)
{
unsigned int max_offset = 0;
unsigned int temp_h = h;
unsigned int initial_output_size = *output_size;
while (temp_h > 0)
{
max_offset++;
temp_h /= 2;
}
unsigned int h_radix2[max_offset];
for (int i = 0; i < max_offset; i++)
{
if (testBit(h, i))
{
if (h > pui(2, i) && !isInList(h - pui(2, i), output_size, output))
{
*(*output + *output_size) = h - pui(2, i);
*output_size += 1;
}
}
}
if (*currently_processing < (int)*output_size)
{
*currently_processing += 1;
listDescendants(*(*output + *currently_processing), output_size, output, currently_processing);
}
}
int main()
{
int currently_processing = -1;
unsigned int size = 0;
unsigned int *output = malloc(300 * sizeof(unsigned int));
listDescendants(21, &size, &output, ¤tly_processing);
printf("size = %u\n", size);
for (int i = 0; i < size; i++)
{
printf("%u ", output[i]);
}
printf("\n");
return 0;
}
You can use a recursive solution, such as the following one.
I'm a bit lazy, so I didn't put the numbers in a list but simply printed them, and I also printed 0 and the given number.
I believe you can easily adjust the code so it will do what you desire.
#include <stdio.h>
#define CHAR_BIT 8
void ProperDescendantsRecursive(unsigned int num, unsigned int bit_index)
{
if (CHAR_BIT * sizeof(unsigned int) - 1 == bit_index)
{
printf("%u\n", num);
}
else
{
unsigned int mask = 1U << bit_index;
if (num & mask)
{
/* with the bit at index bit_index is off */
ProperDescendantsRecursive(num ^ mask, bit_index + 1);
/* with the bit at index bit_index is on */
ProperDescendantsRecursive(num, bit_index + 1);
}
else
{
ProperDescendantsRecursive(num, bit_index + 1);
}
}
}
void ProperDescendants(unsigned int num)
{
ProperDescendantsRecursive(num, 0);
}
int main(void)
{
ProperDescendants(21);
return 0;
}
compiling and running results this output:
0
16
4
20
1
17
5
21
I try to solve the problem of N queens solution and manage to create an algorithm that gives me all possibilities and prints it (I try to understand everything but as backtracking is a little new to me, it is hard).
My program looks at every possibility and prints the position of the queens one by colones, it looks like it works well, even if I don't understand my stopping condition.
My problem is that I need to print the position in a certain a order (start from first queen position 0 - N), but it prints in a random way.
I could store it in an array and sort it, but it will take too much time, so i would like to know if people can look at my code and point out possible problems and give some tips or feedback.
#include <unistd.h>
#include <stdio.h>
#define N 10
void print(int tab[N][N])
{
int i;
int a;
char c;
i = -1;
while (++i < N)
{
a = -1;
while (++a < N)
if (tab[a][i])
{
c = '0' + a;
write(1, &c, 1);
}
}
write(1, "\n", 1);
}
int check(int tab[N][N] , int x, int y)
{
int i;
int j;
i = 0;
while (i < x)
if (tab[i++][y])
return (0);
i = x;
j = y;
while (j >= 0 && i >= 0)
if (tab[i--][j--])
return (0);
i = x;
j = y;
while (i >= 0 && j < N)
if (tab[i--][j++])
return (0);
return (1);
}
int backtrack(int tab[N][N],int x ,int y, int *nbr)
{
if (x >= N)
{
print(tab);
*nbr += 1;
}
while (++y < N)
if (check(tab, x, y))
{
tab[x][y] = 1;
if (backtrack(tab, x + 1, -1, nbr))
return (1);
tab[x][y] = 0;
}
return (0);
}
int ft_ten_queens_puzzle(void)
{
int tab[N][N];
int nbr;
int b;
nbr = -1;
while(++nbr < N)
{
b = -1;
while (++b < N)
tab[nbr][b] = 0;
}
nbr = 0;
backtrack(tab,0,-1, &nbr);
return (nbr);
}
int main()
{
printf("%d\n",ft_ten_queens_puzzle());
}
Your output is coming out random due to a couple of bugs in your print function :
a) If you are printing out a grid, then EVERY cell must be output, but you are not printing cells where tab[a][i] is 0
b) You need a newline at the end of EVERY line, but your write statement is in the wrong place
So the function should be like :
void print(int tab[N][N])
{
char c;
for (int i=0; i < N; i++)
{
for (int a=0; a < N; a++)
{
if (tab[a][i])
{
c = '0' + a;
}
else
{
c = ' ';
}
write(1, &c, 1);
}
write(1, "\n", 1);
}
}
A couple of tips/feedback :
Use full easy-to-understand variable names.
Don't use that awkward "int x = -1; while (++x < N) {" format - the standard for (int x=0; x < N; x++) { format is better
Indent your code correctly. for example, in print, you had the write for the newline out side of it's intended loop, which was easily missed due to indentation issues
Yes, the language allows you to skip the "{","}" for single-statement loops and if statements. I would STRONGLY recommend to never skip them, but always put them on all loops and ifs; It is so much easier to both prevent, and also to track down bugs (especially when indentation is not consistent)
Just my thoughts, I hope they help :)
The code runs just fine but instead of using "for loop" to iterate upto 200000 , I think there can be a better alternative and I am having trouble finding it. I need help to optimise this solution.The time taken by this solution currently is 56ms.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
int isPrime(long long int number)
{
int i;
for (i=2; i*i<=number; i++) {
if (number % i == 0) return 0;
}
return 1;
}
int returnNPrime(int N)
{
int counter = 0;
int i ;
if(N == 1) return 2;
for(i=3;i<200000;i+=2)
{
if(isPrime(i))
{
counter++;
if(counter == (N-1))
return i;
}
}
return 0;
}
int main(int argc, char *argv[])
{
printf("%d",returnNPrime(10001));
return 0;
}
Don't put an arbitrary stop condition. You know that the list of primes is infinite and that the loop will eventually stop. Write it like this:
int returnNPrime (int N)
{
int counter = 0;
int i;
if (N == 1) return 2;
for (i = 3; ; i += 2)
{
if (isPrime(i))
{
counter++;
if (counter == (N - 1))
return i;
}
}
}
That being said, this solution is inefficient because you don't store previously found primes.
Try something like this:
#include <stdio.h>
#include <stdbool.h>
#define N 10001
int primes[N] = { 2, 3 };
int main ()
{
for (int n = 2; n < N; n++) {
for (int x = primes[n - 1] + 2; ; x += 2) {
bool prime = true;
for (int i = 0; i < n; i++) {
int p = primes[i];
if (p * p > x) {
break;
}
if (x % p == 0) {
prime = false;
break;
}
}
if (prime) {
primes[n] = x;
break;
}
}
}
printf ("%d\n", primes[N - 1]);
}
Read this paper http://cr.yp.to/bib/1996/deleglise.pdf which describes how to count the number of primes <= N in O (n^(2/3)) or so and implement the algorithm. It's substantially faster than the Eratosthenes sieve, because it doesn't actually find any primes but just counts how many there are.
Make an educated guess how large the n-th prime would be. Say the guess is x. Use the algorithm above to find out how many primes <= x there are, then use a sieve if you are close enough, or use a better guess with the information you just found and try again. Total time O (n^(2/3)).
With some decent hardware and a lot of patience this will let you find solutions up to n = 10^22 or so.
OP's method consumes a lot of time with as it does not take advantage that there is no need to determine the remainder if i is not a prime.
for (i=2; i*i<=number; i++) {
if (number % i == 0) return 0;
The Sieve_of_Eratosthenes is likely faster yet is a dramatic change from OP's code.
Suspect this code is still too slow for OP.
The follows adjust OP's code by only attempting to test against previously found primes. Also it uses pcandidate / plist[index] as part of a terminating condition. Optimized compilers often can provide this at a small cost once pcandidate % plist[index] is computed.
bool prime_test(const unsigned long *plist, unsigned long long pcandidate) {
if (pcandidate <= 2) return pcandidate == 2;
for (size_t index = 0; ; index++) {
unsigned long long remainder = pcandidate % plist[index];
if (remainder == 0) return false;
unsigned long long quotient = pcandidate / plist[index];
if (quotient < plist[index]) return true;
}
assert(0);
return true;
}
unsigned long long prime_nth(size_t n) {
unsigned long plist[n+1];
plist[0] = 2;
unsigned long long pcandidate = plist[0];
for (size_t index = 0; index <= n; index++) {
while (!prime_test(plist, pcandidate)) pcandidate++;
plist[index] = (unsigned long) pcandidate;
pcandidate++;
}
return plist[n];
}
A classic simplification involves only seeking new primes amongst odd numbers. Also change all math to unsigned. Left for OP.
It's a test in a website, here is the code
#include <stdio.h>
void Print_Factorial ( const int N );
int main()
{
int N;
scanf("%d",&N);
Print_Factorial(N--);
return 0;
}
/* your code will be put in here*/
#include <math.h>
int getFactLength(int N){
double length = 0;
while(N){
length += log10(N--);
}
return (int)length+1;
}
void printFact(int fact[], int length){
while(length--){
printf("%d",*fact++);
}
}
void initialNums(int nums[], int length, int num){
while(length--){
*nums++ = num;
}
}
void Print_Factorial( const int N ){
if(N < 0){
printf("Invalid input");
return ;
}
int NT = N;
if(NT>=0 && NT<15){
int fact = 1;
while(NT){
fact *= NT--;
}
printf("%d",fact);
return ;
}
int length = getFactLength(N);
int fact[length];
initialNums(fact, length, 0);
fact[length-1] = 1;
int lastNoneZeroIndex = length-1;
while(NT > 1){
int lengthT = length;
int carry = 0;
while(lengthT-- > lastNoneZeroIndex){
int result = NT*fact[lengthT] + carry;
fact[lengthT] = result % 10;
carry = result / 10;
}
while(carry){
fact[--lastNoneZeroIndex] = carry % 10;
carry /= 10;
}
NT--;
}
printFact(fact, length);
}
I use values from 0 to 20 to test it, all of them are right. But when I submit it in that website, a test case always do not pass. I don't know what that case is. But, there are 5 cases, all test cases are between 0 and 1000, and two of them are no more than 15, one of them is negative, one of them use most time to pass, so I think the case that didnt pass is a number that smaller than 1000. That's all I know, I can't imagine that 1000 was passed, but the number smaller than 1000 didn't pass. I don't know what is wrong with my lovely code. I hope you can watch my code, and find some bugs.
There create a overflow in the fact variable, here you use int type for fact variable.
For input 13,14, it gives wrong answer.
Solution:
long long int fact = 1;
or,
change the condition- if(NT>=0 && NT<13)
I am writing a C program which should display me all numbers between 100 and 1000 which sum of digit is 20. I tried this code down here, but it just displays 0 as an ouput when I compile it, can you help me? I also tried moving if(iVsota==20) outside of the while loop. I am using Orwell Dev C++ IDE.
#include <stdio.h>
int main (void)
{
int iVnos=0;
int iOstanek=0;
int iVsota=1;
int iStevec1=100;
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
while(iStevec1>0)
{
iOstanek=iStevec1%100;
iStevec1=iStevec1/10;
iVsota=iOstanek+iVsota;
if(iVsota==20)
{
printf("%i\n", iStevec1);
}
}
}
return(0);
I hope this is better.
Your loop should look like :
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
int c2 = iStevec1/100; // extract third digit
int c1 = (iStevec1%100)/10; // extract second digit
int c0 = (iStevec1%10); // extract first digit
if((c0+c1+c2)==20) // sum and verify
{
printf("%i\n", iStevec1);
}
}
This should work for you:
(Changed the variable names so it's more readable)
#include <stdio.h>
int add_digits(int n) {
static int sum = 0;
if (n == 0)
return 0;
sum = n%10 + add_digits(n/10);
return sum;
}
int main() {
int start, end;
start = 100, end = 1000;
for(start = 100; start <= end; start++) {
if(add_digits(start) == 20)
printf("Number: %d\n", start);
}
return 0;
}
EDIT:
(Your code fixed with comments as explanation)
#include <stdio.h>
int main() {
int iVnos=0;
int iOstanek=0;
int iVsota=0;
int iStevec1=100;
int temp; //temp needed
for(iStevec1=100; iStevec1<=1000; iStevec1++)
{
temp =iStevec1; //assign number to temp
iVsota=0; //set sum every iteration to 0
while(temp>0)
{
iOstanek=temp%10; //You need only % 10 to get the last digit of a number
temp = temp / 10; //'delete' last digit of the number
iVsota+=iOstanek; //add digit to sum
}
if(iVsota==20) //You only need to check the digits after sum is calculated
printf("Number %d\n", iStevec1);
}
return 0;
}
Here's a more generalised method to get the sum of all individual numbers in an integer (assumes positive integers):
int getSumOfDigits(int x)
{
int sum = 0;
while (x > 0)
{
sum += x % 10;
x = x / 10;
}
return sum;
}
int main()
{
for (int i = 100; i <= 1000; i++)
{
if (getSumOfDigits(i) == 20)
{
printf("%d\n", x);
}
}
}
The expression x % 10 is the last digit in the integer. Hence, that's what we add. Then we chop off the last digit in the integer by dividing it by 10. Repeat until we hit zero.
Alternative method, taking advantage of the specifics.
#include <stdio.h>
int main()
{
int c0, c1, c2; /* 3 digits sum to 20 */
for(c0 = 2; c0 < 10; c0++){
c1 = 11 - c0;
c2 = 9;
while(c1 < 10){
printf("%d%d%d\n", c0, c1, c2);
/* or printf("%3d\n", (c0*10+c1)*10+c2); */
c1++;
c2--;
}
}
return(0);
}
Just change 1 thing and you will get what you want
int main (void)
{
int iVnos=0;
int iOstanek=0;
int iVsota=1;
int iStevec1=100;
int temp;
for(iStevec1=100; iStevec1<1000; iStevec1++)
{
temp = iStevec1;
while(temp>0)
{
iOstanek=temp%100;
temp=temp/10;
iVsota=iOstanek+iVsota;
if(iVsota==20)
{
printf("%i\n", iStevec1);
}
}
}
return(0);
}
Enjoy Coding Enjoy Life...