Let say I have two ints
a = 1234
b = 45678
Now I want to "interlace" them into a third int c that looks something like this
c = 415263748 assume the the length of these don't change. So far I've been able to do this:
unsigned interlace(unsigned x, unsigned y) {
unsigned pow = 10;
while(y >= pow)
pow *= 10;
return x * pow + y;
}
You have to get digits one by one. When you say x % 10 you get the least significant digit. When you say x = x /10 you remove the least significant digit. Start doing it for y then keep alternating:
unsigned interlace(unsigned x, unsigned y)
{
//If the parameters order could be inverted...
if(x > y)
{
unsigned z = x;
x = y;
y = z;
}
unsigned ans = y % 10;
y = y/10;
unsigned exponent = 10;
while(y)
{
ans += (x%10)*exponent;
x = x/10;
exponent *= 10;
ans += (y%10)*exponent;
y = y/10;
exponent *= 10;
}
return ans;
}
A slight twist on approach can eliminate the order of parameter issue by handling the interlacing on string representations of the values. This allows a simple way to sew the two numbers together. While strlen() is used here, you can also use snprintf (NULL, 0, "%u", a) and snprintf (NULL, 0, "%u", b) to determine the number of digits in each.
A simple approach interlacing the string representations would be:
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
(note: the validations on conversion and length checks greater than zero should be added above. They were intentionally omitted for brevity)
The order of parameters is irrelevant. You can call it as interlace (a, b) or interlace (b, a) and the result will be correct each time.
A short example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMC 32
unsigned interlace (unsigned a, unsigned b)
{
char sa[NUMC], sb[NUMC], result[2*NUMC];
size_t lena, lenb, n = 0;
sprintf (sa, "%u", a);
sprintf (sb, "%u", b);
lena = strlen(sa);
lenb = strlen(sb);
if (lena > lenb) {
for (size_t i = 0, j = 0; sa[i]; i++) {
result[n++] = sa[i];
if (sb[j])
result[n++] = sb[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
for (size_t i = 0, j = 0; sb[i]; i++) {
result[n++] = sb[i];
if (sa[j])
result[n++] = sa[j++];
}
result[n] = 0;
return (unsigned)strtoul (result, NULL, 0);
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
Example Use/Output
$ ./bin/interlace_int
interlaced: 415263748
Another completely different approach, more inline with your original can make use of the div function and the div_t struct to automate handling the division and remainder. You can use the snprintf (NULL, 0, "%u", var); function to determine the number of digits so you can swap parameters if necessary.
A short example is:
#include <stdio.h>
#include <stdlib.h>
unsigned interlace (unsigned a, unsigned b)
{
unsigned result = 0, mult = 1;
div_t da = { .quot = a }, db = { .quot = b };
if (snprintf (NULL, 0, "%u", b) > snprintf (NULL, 0, "%u", a)) {
div_t tmp = da;
da = db;
db = tmp;
}
do {
da = div (da.quot, 10);
result += da.rem * mult;
mult *= 10;
if (db.quot) {
db = div (db.quot, 10);
result += db.rem * mult;
mult *= 10;
}
} while (da.quot);
return result;
}
int main (void) {
unsigned a = 1234, b = 45678;
printf ("interlaced: %u\n", interlace (a, b));
}
(note: here again, the order of parameters is irrelevant and you can provide a and b in any order and still arrive at the correct result)
Example Use/Output
$ ./bin/interlace_unsinged
interlaced: 415263748
Let me know if you have further questions. Just another way to skin the interlace cat.
This is not exactly what you asked for but maybe you can reuse some of this logic on your function....
OUTPUT:
Interlace 2 numbers as a printf
Enter number a: forty-three
Insert digit : 1234
Enter number b: 45678
Interlaced numbers: 142536478
CODE:
#include <stdio.h>
int main(void){
long int num , num2, temp , factor = 1, factor2 = 1;
puts("Interlace 2 numbers as a printf");
printf("Enter number a: ");
while(!scanf(" %ld",&num)){
while ((temp = getchar()) != '\n' && temp != EOF);
printf("Insert digit : ");
}
printf("Enter number b: ");
while(!scanf(" %ld",&num2)){
while ((temp = getchar()) != '\n' && temp != EOF);
printf("Insert digit : ");
}
temp = num;
while(temp){
temp /= 10;
factor *= 10;
}
temp = num2;
while(temp){
temp /= 10;
factor2 *= 10;
}
printf("Interlaced numbers: ");
while(factor>1)
{
factor /= 10;
printf("%ld",num/factor);
num %= factor;
if (factor2 > 1)
{
factor2 /= 10;
printf("%ld",num2/factor2);
num2 %= factor2;
}
}
while(factor2>1)
{
factor2 /= 10;
printf("%ld",num2/factor2);
num2 %= factor2;
}
putchar('\n');
return 0;
}
#include <stdio.h>
#include <math.h>
int main(void) {
int a = 1234;
int b = 45678;
int c = 0;
while(a || b)
{
if (b)
{
int m = pow(10, (int)log10(b));
c=c*10 + b/m;
b = b%m;
}
if (a)
{
int m = pow(10, (int)log10(a));
c=c*10+a/m;
a = a%m;
}
}
printf("Result: %d\n", c);
return 0;
}
Output:
Success #stdin #stdout 0s 4692KB
Result: 415263748
IDEOne Link
Appending the last digit of the two numbers alternatively to n * 10(repeated operation), gives you the reverse of the interlace.
Just to help if you are stuck in generating reversed interlace.
unsigned interlace (unsigned x, unsigned y)
{
unsigned n, r;
if( x > y)
{
temp = x;
x = y;
y = temp;
}
n = y % 10;
y = y / 10;
while (x || y) // To Generate reverse of the interlace
{
n = n * 10 + (x % 10);
x /= 10;
n = n * 10 + (y % 10);
y /= 10;
}
r = n % 10;
n = n / 10;
while(n != 0) // reverse it to get the interlaced number
{
r = r * 10 + (n % 10);
n /= 10;
}
return r;
}
I'm trying to add a quadruatic sequence in an array of integers (in C), instead of typing it manually.
#include <stdio.h>
int main ()
{
int x [100] = {0, 50, 150, 300, 500, 750, 1050, 1400};
//+0, +50, +100, +150, +200, +250, +300, +350, etc.
return 0;
}
Is there any way to do that?
num_add add 50 in each loop.
#include <stdio.h>
int main() {
int x[100];
int num_add = 50;
x[0] = 0;
for (int i = 1; i < 100; i++) {
x[i] = x[i - 1] + num_add;
num_add += 50;
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
for change main difference change the value of variable increment.
#include <stdio.h>
int main() {
int x[100];
int increment = 50;
for (int i = 0; i < 100; i++) {
x[i] = increment * i * (i+1) / 2
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
first time you add D difference,
but later difference continuously change.
change of that difference is in arithmetic progression
increment of main difference D is C constant
In your case both D & C are same, 50.
#include <stdio.h>
int main() {
int x[100];
int D = 50;
int C = 50;
for (int i = 0; i < 100; i++) {
x[i] = (D*i) + (C*i*(i - 1))/2
}
for (int i = 0; i < 100; i++) {
printf("%d ", x[i]);
}
return 0;
}
if C == D (as your case), replace one variable
x[i] = (D*i) + (C*i*(i - 1))/2
= (D*i) + (D*i*(i - 1))/2
= D * i * ( 1 + (i - 1)/2 )
= D * i * (2 + (i - 1)) / 2
= D * i * (i + 1) / 2
x[i] = D * i * (i+1) / 2
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;
}
}
So I'm very new to C, and I'm having trouble with my decimal to binary conversions.
I'm trying to convert 2 numbers - "205" and "171" too binary and put them both in separate arrays, and its working - sort of. See they both convert properly, but they both have three extra "1"s trailing them.
For example, when I use "printf" to see what is in the x array, it is "11001101111" instead of "11001101". The same happens with the y array.
Here's the program so far (I tried to annotate it to make it as clear as possible).
Note: I commented out the "printf" for the y array, but you can switch them out if you want.
int inputx = 205;
int inputy = 171;
//scanf("%d %d", &inputx, &inputy); //
int x[16] = {};
int y[16] = {};
//declaring variables for x conversion
int i = 0;
int d1 = 0;
int c = 0;
int a = 0;
int number1[16] = {};
//converting inputx from decimal into binary
while (inputx != 0){
i = i+1;
d1 = inputx % 2;
inputx = inputx / 2;
c++;
number1[c]=d1;
}//end while
//since the binary array is in reverse, this loop fixes it
for(a = 0; a < c; a = a + 1 ){
x[a]=number1[c-a];
printf("%d", x[a]); //printf just for testing
}//end for
//declaring variables for y conversion
i = 0;
d1 = 0;
int c2 = 0;
a = 0;
int number2[16] = {};
//converting inputy from decimal to binary
while (inputy != 0){
i = i+1;
d1 = inputy % 2;
inputy = inputy / 2;
c2++;
number2[c2]=d1;
}//end while
//since the binary array is in reverse, this loop fixes it
for(a = 0; a < c2; a = a + 1 ){
y[a] = number2[c2-a];
// printf("%d", y[a]); //printf just for testing
}//end for
Any help is appreciated!
I would like to convert an int to a char[4] where each byte in the char[4] contains a decimal value of 2. So in the following example:
int p = 2999999;
Convert p to the array that is identical to k where k is constructed via:
char k[4];
k[0] = 2;
k[1] = 99;
k[2] = 99;
k[3] = 99;
How can I do this in C?
Thanks in advance!
It's strange problem for me but OK. here's what I would have done:
Copy value of p so that it can be used later (I assume that this conversion doesn't intend to change its value).
Use modulo operation to get 2 last digits
cut down the copy of p to be able to read next two digits.
So complete answer is:
#include <stdio.h>
int main()
{
int p = 2999999;
char k[4];
int p_copy = p;
int i;
for(i = 3; i >=0; i--)
{
k[i] = p_copy % 100;
p_copy /= 100;
}
for(i = 0; i < 4; i++)
printf("k[%d]: %d\n",i, k[i]);
return 0;
}
And for sanity the output:
gonczor#wiktor-papu:~/tmp$ gcc test.c -o test
gonczor#wiktor-papu:~/tmp$ ./test
k[0]: 2
k[1]: 99
k[2]: 99
k[3]: 99
for (i =4; i--; k[i] = p % 100, p /= 100);