'How to interlace two integers in C?
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;
}
Solution 1:[1]
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;
}
Solution 2:[2]
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
Solution 3:[3]
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.
Solution 4:[4]
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;
}
Solution 5:[5]
#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
Solution 6:[6]
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;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | David C. Rankin |
| Solution 3 | David C. Rankin |
| Solution 4 | |
| Solution 5 | abelenky |
| Solution 6 |
