Reversing a string to int conversion - c

I have a function PostProcess that is fixed and cannot change. It takes an array of 6 bytes and outputs a 24-bit value.
I'm trying to work out that for a given 24-bit number what function PreProcess would give me the same output and input values.
For example if I set my input value to be 2^24 -1 = 16777215 then I would expect to get 16777215 on the output.
It's not clear how I would implement this functionality. I've added the code below with a test and the functionality of PostProcess
void PreProcess(unsigned int in, unsigned char out[]);
int PostProcess(unsigned char pu8Input[]);
int main()
{
unsigned int InputVal = 16777215; // max value for 24 bits
unsigned char PreProcessed[6] = {0};
PreProcess(InputVal,PreProcessed);
unsigned int OutputVal = PostProcess(PreProcessed);
if(InputVal == OutputVal)
printf("True!");
else
printf("False");
return 0;
}
void PreProcess(unsigned int in, unsigned char out[])
{
//TODO
}
int PostProcess(unsigned char pu8Input[])
{
unsigned int u32Out = 0u;
u32Out += (pu8Input[0] - '0') * 100000;
u32Out += (pu8Input[1] - '0') * 10000;
u32Out += (pu8Input[2] - '0') * 1000;
u32Out += (pu8Input[3] - '0') * 100;
u32Out += (pu8Input[4] - '0') * 10;
u32Out += (pu8Input[5] - '0') * 1;
u32Out &= 0xFFFFFF;
return u32Out;
}

Reverse the operation
Note; with in > 999999, out[0] will be outside the '0'-'9' range.
void PreProcess(unsigned int in, unsigned char out[]) {
in &= 0xFFFFFFu; // Enforce 24-bit limit.
for (int index = 5; index > 0; index--) {
out[index] = in%10u + '0';
in /= 10u;
}
// `in` will be 0 to 167
out[0] = in + '0;
// With ASCII, `out[0]` will be 48 to 215
}

The input integer can have the maximum value of 2^24 - 1, the array of characters is 6 bytes long... having the possibility to change PostProcess() it would have been easy: 6 characters are exactly those required to store a 24 bit integer in HEX format. A character every 4 bytes; maximum value (0x) FFFFFF.
But PostProcess() implementation is fixed and it is designed as a sort of "max-6-digits-atoi". So, if the input buffer's value is {'3', '4', '5', '6', '7', '8'}, then the integer 345678.
It seems that 999999 can be printed at most, but here comes the trick: who bounds us to store in the char buffer only digits? We don't have any contraints (but we have to rely on ASCII encoding scheme).
The strategy
Let's make sure that the lest 5 bytes of the char buffer contain the decimal representation of the input number. In this way, the PostProcess will convert those digits as expected. The value of those digits can be calculated as in % 100000
Being the maximum input value 2^24-1 = 16777215, we have to represent the range [0-167] with the first byte of the array
Since the PostProcess will subtract '0' from pu8Input[0], we make sure to compensate it when generating pu8Input[0]
The code
#include <stdio.h>
#include <string.h>
void PreProcess(unsigned int in, unsigned char out[])
{
if(in <= 16777215)
{
char aux[7];
unsigned int auxInt = in % 100000;
unsigned char firstchar;
firstchar = (in / 100000) + '0';
sprintf( aux, "%c%05u", firstchar, auxInt );
memcpy( out, aux, 6 );
}
}
Summarizing:
We calculate the remainder auxInt = in % 100000
We calculate the leading char as firstchar = (in / 100000) + '0'
We put them together with sprintf, using an auxiliary char buffer 7 bytes long (because we need room for the string terminator)
We memcpythe auxiliary char buffer to the output buffer

Related

C converting 20 digit string to number for IBAN validation

I am doing an IBAN validation in C. For this I have a char* which is something like '2012129431327715102998'.
Now I want to check the IBAN by taken the value modulo 97.
So I want to do 2012129431327715102998 % 97.
I have already tried to convert the char* with strtoull but this gives me an out-of-range error. So my question is: How can I convert this char* to a number where I can do a modulo calculation? Thanks in advance
You can write a custom function for this. Applying the modulo operator on partial sums, you can convert a number of arbitrary length:
#include <stdio.h>
int mod97(const char *s) {
int res = 0;
while (*s >= '0' && *s <= '9') {
res = (res * 10 + (*s++ - '0')) % 97;
}
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
printf("%s -> %d\n", argv[i], mod97(argv[i]));
}
return 0;
}
Output:
./mod97 2012129431327715102998
2012129431327715102998 -> 53
This method is simpler and more generic than the one described in the wiki article: computing the modulo 97 of a large number can be achieved by splitting the number in chunks of 9 digits and combining the modulo of these chunks. This splitting is specific to 97 and works because 1000000000 % 97 == 1. The above method works for any modulo value up to INT_MAX / 10.
A simple way without using additional library is to remember that mathematically: mod(a*b, c) == mod(b * mod(a, c), c). So you can process the number in chunks:
// suitable for a 32 bits system, can use 8 for a 64 bits one
#define NB 4
/*********************
* Initial is a string containin only digits representing an arbitrary large number
* div in a number < 10000 (because NB is 4)
* ******************/
int large_mod(char *initial, int div) {
char old[1 + (NB * 2)] = ""; // enough room for a remainder and next chunk
long val;
for (unsigned i=0; i<strlen(initial); i+= NB) {
strncat(old, initial + i, NB); // add the new chunk
val = atol(old) % div; // compute the remainder
sprintf(old, "%ld", val); // keep it for next chunk
// printf("%ld ", val); // uncomment for debugging
}
return (int) val;
}
For 2012129431327715102998 % 97, it gives as expected 53.

Why isn't my program that converts decimal to binary printing correctly?

I have an assignment that is asking me to convert a decimal number to its 16-bit 2's complement binary representation stored in a char array. I was provided started code that included a complete main method and an addOne method. I just needed to complete the flipBits and magnitudeToBinary methods.
I have completed the methods and they should work, but I am getting string output. An example is:
Enter integers and convert it to 2's complement binary.
Non-numeric input terminates program.
27
Integer: 27, 2's complement binary:
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void magnitudeToBinary(int n, char arr[], int numOfBits);
void flipBits(char arr[], int numOfBits);
void addOne(char arr[], int numOfBits);
int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
//Declare a char array with size 16 to simulate 16-bit binary
int numOfBits = 16;
char arr[numOfBits + 1];
arr[numOfBits] = '\0'; //set the terminating character
//Declare integer n to hold the decimal integer
int n = 0;
puts("Enter integers and convert it to 2's complement binary.");
puts("Non-numeric input terminates program.");
//Continually taking input and convert it to binary
while (scanf("%d", &n) == 1) {//if successfully read in ONE decimal integer
//Initialize the char array to all 0s (leave the terminating character unchanged)
for(int i = 0; i < numOfBits; i ++){
arr[i] = '0';
}
//Convert magnitude (absolute value) to binary
magnitudeToBinary(abs(n), arr, numOfBits);
//if the number is negative: flip all bits, then add 1.
if(n < 0){
//Flip all bits in char arr
flipBits(arr, numOfBits);
//Add 1
addOne(arr, numOfBits);
}
//Output binary:
printf("Integer: %d, 2's complement binary: %s\n", n, arr);
}
return EXIT_SUCCESS;
}
/* addOne: arithmatically add 1 to the binary simulated by character array
* INPUT: char arr[]: the character array holding the binary
* int numOfBits: the number of bits in the binary
* */
void addOne(char arr[], int numOfBits){
/* True table
* ******************************
* carry arr[i] | arr[i] carry
* 1 0 | 1 0
* 1 1 | 0 1
* 0 0 | 0 0
* 0 1 | 1 0
* *********************************/
char carry = '1';
for(int i = numOfBits - 1; i >= 0; i --){
if(carry != arr[i]){
arr[i] = '1';
carry = '0';
}
else if(carry == '1'){
arr[i] = '0';
}
else{
arr[i] = '0';
}
}
return;
}
/* flipBits: perform 1's complement on the binary, i.e., change 1 to 0, 0 to 1
* INPUT: char arr[]: the character array holding the binary
* int numOfBits: the number of bits in the binary *
* */
void flipBits(char arr[], int numOfBits){
//Implement your solution here
for(int i = 0; i < numOfBits; i++) {
if(arr[i] == '1') {
arr[i] = '0';
} else if(arr[i] == '0') {
arr[i] = '1';
}
}
return;
}
/* magnitudeToBinary: Convert a non-negative decimal integer to binary (stored in a char array)
* using division-remainder algorithm
* INPUT: int n: The decimal integer number to be converted
* char arr[]: the character array holding the binary
* int numOfBits: the number of bits in the binary *
* */
void magnitudeToBinary(int n, char arr[], int numOfBits){
//Implement the division-remainder algorithm here
int i = 0;
while (n > 0) {
arr[i] = n % 2;
n = n / 2;
i++;
}
return;
}
I would just like to see the correct binary output. Right now I am unsure if it is an error on my part, my professor's, or if Eclipse is acting up. Any help is appreciated, thanks!
Try changing the line in magnitudeToBinary() from :
arr[i] = n % 2;
to
arr[i] = n % 2 == 1 ? '1' : '0';
You want to write the ASCII value for '1' or '0' into the array - not the result of n % 2.

Converting a Numerical String to an Array of Bytes Represented in Binary

I’d like to convert a string containing only integers to an array of bytes, but to be stored efficiently (so no “digits[digitIndex] = string[digitIndex - ‘0’;”). I would like them to be stored like any type is stored: having 256 different possibilities per byte, not only 10 as in the previous, faulty example. It also needs to hold a lot of digits (I’m using an 8-bit parameter as the size, so at least 100 digits I believe). Edit: I also do not want to use any libraries whatsoever for personal reasons.
Here’s an example of what it would look like in a function:
int8_t *stringToBigInt(char *input) {
uint8_t digitsBase10 = strlen(input);
uint8_t bytes = ???; //However many bytes to store the result (max 255 bytes in this case)
int8_t *result = malloc(sizeof(void *) + bytes);
... //Code for setting result to input
return result;
}
And here’s an example of a possible input and output:
Edit: This is a short example that fits into 32-bits only for simplicity; an input could be much more than a 32-bit (and possibly 64-bit) integer
Input: “1234567890”
Output: {01001001, 10010110, 00000010, 11010010}
This is a base conversion from base-10 to base-256, so that’s what you should look for as far as algorithms go. For a simplistic implementation, first implement long division by powers of 2 working on strings. Then convert each of the remainders to a byte: these bytes form your output. You’ll want to repeatedly divide the input, and each string of 8 remainder bit remainders forms the base-256 bytes, starting at the least significant digit (one byte is one base-256 digit). Repeated division means that you feed the quotient of the preceding division to the succeeding one, as the dividend.
There are some cool algorithms that can divide base-10 numbers by powers of two, that operate much faster and are simpler than generalized long division. As a hint, let’s take an example: 510. We divide each digit by two, and feed the remainder*5 to the next digit. Let’s drop the fractional part smaller than 0.5: 510 becomes 2*100 + 5*10 + 5. Then 1*100 + 2*10 + 2 dot 5. Then 6*10 + 1. Then 3*10 dot 5, 2*10 + 5, then 1*10 + 2 dot 5, then 6, then 3, then 2 dot 5, then 1, then 0 dot 5.
For 255 we’d get 127.5, 63.5, 15.5, 7.5, 3.5, 1.5, 0.5.
Division by higher factors of two is possible, but requires repeated long additions. E.g. 33 div 4 = 0*10 + 7rem1 + 0 rem 0.75 (ha!). Divisions by two work better since we use the fact that 10=2*5, and base-n notation can be divided by factors of the base easily, without performing long additions: all operations are limited to two adjacent digits, so it’s a linear time process with cost N in number of digits. But for base conversion to base-256 you do repeated division, so the cost is ~0.5N^2. Easy to implement but costly in computations.
There are better algorithms than that, of course. But the above can be implemented concisely - even in the form of reasonably good quality library functions:
First, let's define an array-of-bytes type, and a way to dump it to human-readable hexadecimal output. For convenience, the object is referred to via the pointer to its data, and the implementation detail doesn't figure anywhere in the interface at all. The constructor new_Bytes zero-initializes the array. There is also a method that treats the array as if it was an array of bits, ordered lest-endian (LSB first), and sets (turns on) a given bit.
// https://github.com/KubaO/stackoverflown/tree/master/questions/decimal-to-binary-54422895
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Bytes Class Interface
typedef uint8_t *Bytes;
typedef const uint8_t *cBytes;
Bytes new_Bytes(size_t size);
size_t Bytes_size(cBytes bytes);
void Bytes_truncate(Bytes bytes, size_t new_size);
void free_Bytes(cBytes bytes);
char *Bytes_to_hex(cBytes bytes);
static inline void Bytes_set_bit(Bytes const bytes, size_t const bit_num) {
bytes[bit_num / 8] |= 1 << (bit_num % 8);
}
Then, the division-by-2 is performed in-place, and the flags provide additional information needed for base conversion - especially the remainder. The conversion from base 10 to base 256 uses the division and returns a new Bytes array.
// Division and Base Conversion Interface
typedef enum {
REMAINDER = 1, /* there is a non-zero remainder */
ZERO = 2, /* the quotient is zero or null */
NULL_DECIMAL = 4, /* the dividend is null or empty */
NON_DECIMALS = 8, /* division was terminated on non-decimal characters */
LEADING_ZERO_COUNT = 16, /* count of leading zeroes in the quotient */
LEADING_ZERO_COUNT_MASK = ~(LEADING_ZERO_COUNT - 1),
CLR_CARRY_MASK = ~REMAINDER,
CLR_ZERO_MASK = ~ZERO,
} DivFlags;
DivFlags divide_by_2(char *decimal);
Bytes base_10_to_256(const char *decimal);
The division operates on the decimal representation, in order from most-significant to least-significant digit. Each digit is merged with the remainder from the prior digit's division, and then is divided by 2. The remainder is carried between digit divisions. After division of the least significant digit, the remainder is output in the flags.
The flags are mostly self-explanatory, but LEADING_ZERO_COUNT isn't quite - and thus the access to it is implemented via accessor functions. LEADING_ZERO_COUNT is the unit of the count of leading zeroes. As the division steps though the decimal representation, it will count the leading zeroes, multiply them by this unit, and merge it with the flags. To extract the count, the flags are divided by the unit.
// Division and Base Conversion Implementation
static inline int leading_zero_count(DivFlags const flags) {
return (flags & LEADING_ZERO_COUNT_MASK) / LEADING_ZERO_COUNT;
}
static inline void saturated_inc_leading_zero_count(DivFlags *flags) {
if ((*flags & LEADING_ZERO_COUNT_MASK) != LEADING_ZERO_COUNT_MASK)
*flags += LEADING_ZERO_COUNT;
}
DivFlags divide_by_2(char *decimal) {
DivFlags flags = ZERO;
if (!decimal) return flags | NULL_DECIMAL;
char c;
while ((c = *decimal)) {
if (c < '0' || c > '9') return flags | NON_DECIMALS;
c = c - '0' + ((flags & REMAINDER) ? 10 : 0);
if (c & 1)
flags |= REMAINDER;
else
flags &= CLR_CARRY_MASK;
c >>= 1;
assert(c >= 0 && c <= 9);
if (c)
flags &= CLR_ZERO_MASK;
else if (flags & ZERO)
saturated_inc_leading_zero_count(&flags);
*decimal++ = c + '0';
}
return flags;
}
Then, the base conversion performs repeated division by 2, and shifts the remainder bits into the byte array, as follows:
First, the base conversion takes a copy of the decimal representation, and allocates the output byte array of the appropriate size.
static void base_10_to_256_impl(Bytes const bytes, char *decimal);
Bytes base_10_to_256(const char *const decimal) {
assert(decimal);
size_t const dec_len = strlen(decimal);
char *const dec_buf = malloc(dec_len + 1);
if (!dec_buf) return NULL;
memcpy(dec_buf, decimal, dec_len + 1);
size_t const BASE_RATIO_NUM = 416, /* ceil(log(10)/log(256)*1000) */
BASE_RATIO_DENOM = 1000;
assert(dec_len <= (SIZE_MAX / BASE_RATIO_NUM));
size_t const len = (size_t)(dec_len * BASE_RATIO_NUM / BASE_RATIO_DENOM) + 1;
Bytes const bytes = new_Bytes(len); // little-endian
if (bytes) base_10_to_256_impl(bytes, dec_buf);
free(dec_buf);
return bytes;
}
Then, in the "meat" of the implementation, the function iterates the output bits, repeatedly dividing the decimal representation by 2, and sets each bit with the value of the remainder bit.
static void base_10_to_256_impl(Bytes const bytes, char *decimal) {
size_t const len = Bytes_size(bytes);
for (size_t bit_num = 0;; bit_num++) {
DivFlags const flags = divide_by_2(decimal);
assert(!(flags & NULL_DECIMAL));
decimal += leading_zero_count(flags);
if (flags & ZERO && !(flags & REMAINDER)) {
size_t const new_len = ((bit_num + 7) / 8);
Bytes_truncate(bytes, new_len);
break;
}
// here, there are still non-zero bits - in the dec[imal] and/or in the carry
assert((bit_num / 8) < len);
if (flags & REMAINDER) Bytes_set_bit(bytes, bit_num);
}
}
We can now add some tests:
// Tests
void check_bytes(const char *const decimal, const char *const bytes_expected,
size_t const bytes_len, const char *const hex_expected) {
cBytes const bytes = base_10_to_256(decimal);
assert(bytes && Bytes_size(bytes) == bytes_len);
assert(memcmp(bytes, bytes_expected, bytes_len) == 0);
char *const hex = Bytes_to_hex(bytes);
assert(hex && strcmp(hex, hex_expected) == 0);
printf("%s\n", hex);
free(hex);
free_Bytes(bytes);
}
int main() {
check_bytes("4294967297" /* 2^32+1 */, "\1\0\0\0\1", 5, "01 00000001");
check_bytes("4294967296" /* 2^32 */, "\0\0\0\0\1", 5, "01 00000000");
check_bytes("4294967295" /* 2^32-1 */, "\xFF\xFF\xFF\xFF", 4, "FFFFFFFF");
check_bytes("16777217" /* 2^24+1 */, "\1\0\0\1", 4, "01000001");
check_bytes("16777216" /* 2^24 */, "\0\0\0\1", 4, "01000000");
check_bytes("16777215" /* 2^24-1 */, "\xFF\xFF\xFF", 3, "FFFFFF");
check_bytes("256", "\0\1", 2, "0100");
check_bytes("255", "\xFF", 1, "FF");
check_bytes("254", "\xFE", 1, "FE");
check_bytes("253", "\xFD", 1, "FD");
check_bytes("3", "\3", 1, "03");
check_bytes("2", "\2", 1, "02");
check_bytes("1", "\1", 1, "01");
check_bytes("0", "\0", 1, "00");
}
The implementation of the Bytes class concludes the example:
// Bytes Implementation
struct BytesImpl {
size_t size;
uint8_t data[1];
};
static const size_t Bytes_header_size = offsetof(struct BytesImpl, data);
_Static_assert(offsetof(struct BytesImpl, data) == sizeof(size_t),
"unexpected layout of struct BytesImpl");
Bytes new_Bytes(size_t size) {
assert(size <= SIZE_MAX - Bytes_header_size);
if (!size) size++;
struct BytesImpl *const impl = calloc(Bytes_header_size + size, 1);
if (!impl) return NULL;
impl->size = size;
return &impl->data[0];
}
static const struct BytesImpl *Bytes_get_const_impl_(cBytes const bytes) {
return (const struct BytesImpl *)(const void *)((const char *)bytes -
Bytes_header_size);
}
static struct BytesImpl *Bytes_get_impl_(Bytes const bytes) {
return (struct BytesImpl *)(void *)((char *)bytes - Bytes_header_size);
}
size_t Bytes_size(cBytes const bytes) { return Bytes_get_const_impl_(bytes)->size; }
void Bytes_truncate(Bytes const bytes, size_t new_size) {
size_t *const size = &Bytes_get_impl_(bytes)->size;
if (!new_size) {
new_size++; // we always leave one byte in the array
bytes[0] = 0;
}
assert(*size);
if (*size <= new_size) return;
*size = new_size;
}
void free_Bytes(cBytes const bytes) {
if (bytes) free((void *)(intptr_t)(const void *)Bytes_get_const_impl_(bytes));
}
char *Bytes_to_hex(cBytes const bytes) {
size_t n = Bytes_size(bytes);
size_t spaces = (n - 1) / 4;
char *const out = malloc(n * 2 + spaces + 1);
if (out)
for (char *o = out; n;) {
uint8_t const c = bytes[n - 1];
snprintf(o, 3, "%02" PRIX8, c);
o += 2;
n--;
if (n && n % 4 == 0) {
assert(spaces);
*o++ = ' ';
spaces--;
}
}
return out;
}

Getting multiple strings with repeated character [duplicate]

I am trying obtain 9 digit numbers that all have unique digits. My first approach seems a bit too complex and would be tedious to write.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int indx;
int num;
int d1, d2, d3, d4, d5, d6, d7, d8, d9;
for(indx = 123456789; indx <= 987654321; indx++)
{
num = indx;
d1 = num % 10;
d2 = ( num / 10 ) % 10;
d3 = ( num / 100 ) % 10;
d4 = ( num / 1000 ) % 10;
d5 = ( num / 10000 ) % 10;
d6 = ( num / 100000 ) % 10;
d7 = ( num / 1000000 ) % 10;
d8 = ( num / 10000000 ) % 10;
d9 = ( num / 100000000 ) % 10;
if( d1 != d2 && d1 != d3 && d1 != d3 && d1 != d4 && d1 != d5
&& d1 != d6 && d1 != d7 && d1 != d8 && d1 != d9 )
{
printf("%d\n", num);
}
}
}
That is just comparing the first number to the rest. I would have to do that many more to compare the other numbers. Is there a better way to do this?
This is a pretty typical example of a problem involving combinatorics.
There are exactly 9⋅8⋅7⋅6⋅5⋅4⋅3⋅2⋅1 = 9! = 362880 nine-digit decimal numbers, where each digit occurs exactly once, and zero is not used at all. This is because there are nine possibilities for the first digit, eight for the second, and so on, since each digit is used exactly once.
So, you can easily write a function, that takes in the seed, 0 ≤ seed < 362880, that returns one of the unique combinations, such that each combination corresponds to exactly one seed. For example,
unsigned int unique9(unsigned int seed)
{
unsigned char digit[9] = { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U };
unsigned int result = 0U;
unsigned int n = 9U;
while (n) {
const unsigned int i = seed % n;
seed = seed / n;
result = 10U * result + digit[i];
digit[i] = digit[--n];
}
return result;
}
The digit array is initialized to the set of nine thus far unused digits. i indicates the index to that array, so that digit[i] is the actual digit used. Since the digit is used, it is replaced by the last digit in the array, and the size of the array n is reduced by one.
Some example results:
unique9(0U) == 198765432U
unique9(1U) == 218765439U
unique9(10U) == 291765438U
unique9(1000U) == 287915436U
unique9(362878U) == 897654321U
unique9(362879U) == 987654321U
The odd order for the results is because the digits in the digit array switch places.
Edited 20150826: If you want the indexth combination (say, in lexicographic order), you can use the following approach:
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef unsigned long permutation_t;
int permutation(char *const buffer,
const char *const digits,
const size_t length,
permutation_t index)
{
permutation_t scale = 1;
size_t i, d;
if (!buffer || !digits || length < 1)
return errno = EINVAL;
for (i = 2; i <= length; i++) {
const permutation_t newscale = scale * (permutation_t)i;
if ((permutation_t)(newscale / (permutation_t)i) != scale)
return errno = EMSGSIZE;
scale = newscale;
}
if (index >= scale)
return errno = ENOENT;
memmove(buffer, digits, length);
buffer[length] = '\0';
for (i = 0; i < length - 1; i++) {
scale /= (permutation_t)(length - i);
d = index / scale;
index %= scale;
if (d > 0) {
const char c = buffer[i + d];
memmove(buffer + i + 1, buffer + i, d);
buffer[i] = c;
}
}
return 0;
}
If you specify digits in increasing order, and 0 <= index < length!, then buffer will be the permutation having indexth smallest value. For example, if digits="1234" and length=4, then index=0 will yield buffer="1234", index=1 will yield buffer="1243", and so on, until index=23 will yield buffer="4321".
The above implementation is definitely not optimized in any way. The initial loop is to calculate the factorial, with overflow detection. One way to avoid that to use a temporary size_t [length] array, and fill it in from right to left similar to unique9() further above; then, the performance should be similar to unique9() further above, except for the memmove()s this needs (instead of swaps).
This approach is generic. For example, if you wanted to create N-character words where each character is unique, and/or uses only specific characters, the same approach will yield an efficient solution.
First, split the task into steps.
Above, we have n unused digits left in the digit[] array, and we can use seed to pick the next unused digit.
i = seed % n; sets i to the remainder (modulus) if seed were to be divided by n. Thus, is an integer i between 0 and n-1 inclusive, 0 ≤ i < n.
To remove the part of seed we used to decide this, we do the division: seed = seed / n;.
Next, we add the digit to our result. Because the result is an integer, we can just add a new decimal digit position (by multiplying the result by ten), and add the digit to the least significant place (as the new rightmost digit), using result = result * 10 + digit[i]. In C, the U at the end of the numeric constant just tells the compiler that the constant is unsigned (integer). (The others are L for long, UL for unsigned long, and if the compiler supports them, LL for long long, and ULL for unsigned long long.)
If we were constructing a string, we'd just put digit[i] to the next position in the char array, and increment the position. (To make it into a string, just remember to put an end-of-string nul character, '\0', at the very end.)
Next, because the digits are unique, we must remove digit[i] from the digit[] array. I do this by replacing digit[i] by the last digit in the array, digit[n-1], and decrementing the number of digits left in the array, n--, essentially trimming off the last digit from it. All this is done by using digit[i] = digit[--n]; which is exactly equivalent to
digit[i] = digit[n - 1];
n = n - 1;
At this point, if n is still greater than zero, we can add another digit, simply by repeating the procedure.
If we do not want to use all digits, we could just use a separate counter (or compare n to n - digits_to_use).
For example, to construct a word using any of the 26 ASCII lowercase letters using each letter at most once, we could use
char *construct_word(char *const str, size_t len, size_t seed)
{
char letter[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
size_t n = 26;
if (str == NULL || len < 1)
return NULL;
while (len > 1 && n > 0) {
const size_t i = seed % n;
seed /= n; /* seed = seed / n; */
str[len++] = letter[i];
letter[i] = letter[--n];
}
str[len] = '\0';
return str;
}
Call the function with str pointing to a character array of at least len characters, with seed being the number that identifies the combination, and it'll fill str with a string of up to 26 or len-1 characters (whichever is less) where each lowercase letter occurs at most once.
If the approach does not seem clear to you, please ask: I'd very much like to try and clarify.
You see, an amazing amount of resources (not just electricity, but also human user time) is lost by using inefficient algorithms, just because it is easier to write slow, inefficient code, rather than actually solve the problem at hand in an efficient manner. We waste money and time that way. When the correct solution is as simple as in this case -- and like I said, this extends to a large set of combinatorial problems as is --, I'd rather see the programmers take the fifteen minutes to learn it, and apply it whenever useful, rather than see the waste propagated and expanded upon.
Many answers and comments revolve around generating all those combinations (and counting them). I personally don't see much use in that, because the set is well known already. In practice, you typically want to generate e.g. small subsets -- pairs, triplets, or larger sets -- or sets of subsets that fulfill some criteria; for example, you might wish to generate ten pairs of such numbers, with each nine-digit number used twice, but not in a single pair. My seed approach allows that easily; instead of decimal representation, you work with the consecutive seed values instead (0 to 362879, inclusive).
That said, it is straightforward to generate (and print) all permutations of a given string in C:
#include <stdlib.h>
#include <stdio.h>
unsigned long permutations(char str[], size_t len)
{
if (len-->1) {
const char o = str[len];
unsigned long n = 0U;
size_t i;
for (i = 0; i <= len; i++) {
const char c = str[i];
str[i] = o;
str[len] = c;
n += permutations(str, len);
str[i] = c;
str[len] = o;
}
return n;
} else {
/* Print and count this permutation. */
puts(str);
return 1U;
}
}
int main(void)
{
char s[10] = "123456789";
unsigned long result;
result = permutations(s, 9);
fflush(stdout);
fprintf(stderr, "%lu unique permutations\n", result);
fflush(stderr);
return EXIT_SUCCESS;
}
The permutation function is recursive, but its maximum recursion depth is the string length. The total number of calls to the function is a(N), where N is the length of the string, and a(n)=n⋅a(n-1)+1 (sequence A002627), 623530 calls in this particular case. In general, a(n)≤(1-e)n!, i.e. a(n)<1.7183n!, so the number of calls is O(N!), factorial with respect to number of items permuted. The loop body is iterated one less time compared to the calls, 623529 times here.
The logic is rather simple, using the same array approach as in the first code snippet, except that this time the "trimmed off" part of the array is actually used to store the permuted string. In other words, we swap each character still left with the next character to be trimemd off (or prepended to the final string), do the recursive call, and restore the two characters. Because each modification is undone after each recursive call, the string in the buffer is the same after the call as it was before. Just as if it was never modified in the first place.
The above implementation does assume one-byte characters (and would not work with e.g. multibyte UTF-8 sequences correctly). If Unicode characters, or characters in some other multibyte character set, are to be used, then wide characters should be used instead. Other than the type change, and changing the function to print the string, no other changes are needed.
Given an array of numbers, it is possible to generate the next permutation of those numbers with a fairly simple function (let's call that function nextPermutation). If the array starts with all the numbers in sorted order, then the nextPermutation function will generate all of the possible permutations in ascending order. For example, this code
int main( void )
{
int array[] = { 1, 2, 3 };
int length = sizeof(array) / sizeof(int);
printf( "%d\n", arrayToInt(array, length) ); // show the initial array
while ( nextPermutation(array, length) )
printf( "%d\n", arrayToInt(array, length) ); // show the permutations
}
will generate this output
123
132
213
231
312
321
and if you change the array to
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
then the code will generate and display all 362880 permutations of those nine numbers in ascending order.
The nextPermutation function has three steps
starting from the end of the array, find the first number (call it x) that is followed by a larger number
starting from the end of the array, find the first number (call it y) that is larger than x, and swap x and y
y is now where x was, and all of the numbers to the right of y are in descending order, swap them so that they are in ascending order
Let me illustrate with an example. Suppose the array has the numbers in this order
1 9 5 4 8 7 6 3 2
The first step would find the 4. Since 8 7 6 3 2 are in descending order, the 4 is the first number (starting from the end of the array) that is followed by a larger number.
The second step would find the 6, since the 6 is the first number (starting from the end of the array) that is larger than 4. After swapping 4 and 6 the array looks like this
1 9 5 6 8 7 4 3 2
Notice that all the numbers to the right of the 6 are in descending order. Swapping the 6 and the 4 didn't change the fact that the last five numbers in the array are in descending order.
The last step is to swap the numbers after the 6 so that they are all in ascending order. Since we know that the numbers are in descending order, all we need to do is swap the 8 with the 2, and the 7 with the 3. The resulting array is
1 9 5 6 2 3 4 7 8
So given any permutation of the numbers, the function will find the next permutation just by swapping a few numbers. The only exception is the last permutation which has all the numbers in reverse order, i.e. 9 8 7 6 5 4 3 2 1. In that case, step 1 fails, and the function returns 0 to indicate that there are no more permutations.
So here's the nextPermutation function
int nextPermutation( int array[], int length )
{
int i, j, temp;
// starting from the end of the array, find the first number (call it 'x')
// that is followed by a larger number
for ( i = length - 2; i >= 0; i-- )
if ( array[i] < array[i+1] )
break;
// if no such number was found (all the number are in reverse order)
// then there are no more permutations
if ( i < 0 )
return 0;
// starting from the end of the array, find the first number (call it 'y')
// that is larger than 'x', and swap 'x' and 'y'
for ( j = length - 1; j > i; j-- )
if ( array[j] > array[i] )
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
break;
}
// 'y' is now where 'x' was, and all of the numbers to the right of 'y'
// are in descending order, swap them so that they are in ascending order
for ( i++, j = length - 1; j > i; i++, j-- )
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return 1;
}
Note that the nextPermutation function works for any array of numbers (the numbers don't need to be sequential). So for example, if the starting array is
int array[] = { 2, 3, 7, 9 };
then the nextPermutation function will find all of the permutations of 2,3,7 and 9.
Just for completeness, here's the arrayToInt function that was used in the main function. This function is only for demonstration purposes. It assumes that the array only contains single digit numbers, and doesn't bother to check for overflows. It'll work for a 9 digit number provided that an int is at least 32-bits.
int arrayToInt( int array[], int length )
{
int result = 0;
for ( int i = 0; i < length; i++ )
result = result * 10 + array[i];
return result;
}
Since there seems to be some interest in the performance of this algorithm, here are some numbers:
length= 2 perms= 2 (swaps= 1 ratio=0.500) time= 0.000msec
length= 3 perms= 6 (swaps= 7 ratio=1.167) time= 0.000msec
length= 4 perms= 24 (swaps= 34 ratio=1.417) time= 0.000msec
length= 5 perms= 120 (swaps= 182 ratio=1.517) time= 0.001msec
length= 6 perms= 720 (swaps= 1107 ratio=1.538) time= 0.004msec
length= 7 perms= 5040 (swaps= 7773 ratio=1.542) time= 0.025msec
length= 8 perms= 40320 (swaps= 62212 ratio=1.543) time= 0.198msec
length= 9 perms= 362880 (swaps= 559948 ratio=1.543) time= 1.782msec
length=10 perms= 3628800 (swaps= 5599525 ratio=1.543) time= 16.031msec
length=11 perms= 39916800 (swaps= 61594835 ratio=1.543) time= 170.862msec
length=12 perms=479001600 (swaps=739138086 ratio=1.543) time=2036.578msec
The CPU for the test was a 2.5Ghz Intel i5 processor. The algorithm generates about 200 million permutations per second, and takes less than 2 milliseconds to generate all of the permutations of 9 numbers.
Also of interest is that, on average, the algorithm only requires about 1.5 swaps per permutation. Half the time, the algorithm just swaps the last two numbers in the array. In 11 of 24 cases, the algorithm does two swaps. So it's only in 1 of 24 cases that the algorithm needs more than two swaps.
Finally, I tried the algorithm with the following two arrays
int array[] = { 1, 2, 2, 3 }; // generates 12 permutations
int array[] = { 1, 2, 2, 3, 3, 3, 4 }; // generates 420 permutations
The number of permutations is as expected and the output appeared to be correct, so it seems that the algorithm also works if the numbers are not unique.
Recursion works nicely here.
#include <stdio.h>
void uniq_digits(int places, int prefix, int mask) {
if (!places) {
printf("%d\n", prefix);
return;
}
for (int i = 0; i < 10; i++) {
if (prefix==0 && i==0) continue;
if ((1<<i)&mask) continue;
uniq_digits(places-1, prefix*10+i, mask|(1<<i));
}
}
int main(int argc, char**argv) {
uniq_digits(9, 0, 0);
return 0;
}
Here is a simple program that will print all permutations of a set of characters. You can easily convert that to generate all the numbers you need:
#include <stdio.h>
static int step(const char *str, int n, const char *set) {
char buf[n + 2];
int i, j, count;
if (*set) {
/* insert the first character from `set` in all possible
* positions in string `str` and recurse for the next
* character.
*/
for (count = 0, i = n; i >= 0; i--) {
for (j = 0; j < i; j++)
buf[j] = str[j];
buf[j++] = *set;
for (; j <= n; j++)
buf[j] = str[j - 1];
buf[j] = '\0';
count += step(buf, n + 1, set + 1);
}
} else {
printf("%s\n", str);
count = 1;
}
return count;
}
int main(int argc, char **argv) {
int total = step("", 0, argc > 1 ? argv[1] : "123456789");
printf("%d combinations\n", total);
return 0;
}
It uses recursion but not bit masks and can be used for any set of characters. It also computes the number of permutations, so you can verify that it produces factorial(n) permutations for a set of n characters.
There are many long chunks of code here. Better to think more and code less.
We would like to generate each possibility exactly once with no wasted effort. It turns out this is possible with only a constant amount of effort per digit emitted.
How would you do this without code? Get 10 cards and write the digits 0 to 9 on them. Draw a row of 9 squares on your tabletop. Pick a card. Put it in the first square, another in the second, etc. When you've picked 9, you have your first number. Now remove the last card and replace it with each possible alternative. (There's only 1 in this case.) Each time all squares are filled, you have another number. When you've done all alternatives for the last square, do it for the last 2. Repeat with the last 3, etc., until you have considered all alternatives for all boxes.
Writing a succinct program to do this is about choosing simple data structures. Use an array of characters for the row of 9 square.
Use another array for the set of cards. To remove an element from the set of size N stored in an array A[0 .. N-1], we use an old trick. Say the element you want to remove is A[I]. Save the value of A[I] off to the side. Then copy the last element A[N-1] "down," overwriting A[I]. The new set is A[0 .. N-2]. This works fine because we don't care about order in a set.
The rest is to use recursive thinking to enumerate all possible alternatives. If I know how to find all selections from a character set of size M into a string of size N, then to get an algorithm, just select each possible character for the first string position, then recur to select the rest of the N-1 characters from the remaining set of size M-1. We get a nice 12-line function:
#include <stdio.h>
// Select each element from the given set into buf[pos], then recur
// to select the rest into pos+1... until the buffer is full, when
// we print it.
void select(char *buf, int pos, int len, char *set, int n_elts) {
if (pos >= len)
printf("%.*s\n", len, buf); // print the full buffer
else
for (int i = 0; i < n_elts; i++) {
buf[pos] = set[i]; // select set[i] into buf[pos]
set[i] = set[n_elts - 1]; // remove set[i] from the set
select(buf, pos + 1, len, set, n_elts - 1); // recur to pick the rest
set[n_elts - 1] = set[i]; // undo for next iteration
set[i] = buf[pos];
}
}
int main(void) {
char buf[9], set[] = "0123456789";
select(buf, 0, 9, set, 10); // select 9 characters from a set of 10
return 0;
}
You didn't mention whether it's okay to put a zero in the first position. Suppose it isn't. Since we understand the algorithm well, it's easy to avoid selecting zero into the first position. Just skip that possibility by observing that !pos in C has the value 1 if pos is 0 and 0. If you don't like this slightly obscure idiom, try (pos == 0 ? 1 : 0) as a more readable replacement:
#include <stdio.h>
void select(char *buf, int pos, int len, char *set, int n_elts) {
if (pos >= len)
printf("%.*s\n", len, buf);
else
for (int i = !pos; i < n_elts; i++) {
buf[pos] = set[i];
set[i] = set[n_elts - 1];
select(buf, pos + 1, len, set, n_elts - 1);
set[n_elts - 1] = set[i];
set[i] = buf[pos];
}
}
int main(void) {
char buf[9], set[] = "0123456789";
select(buf, 0, 9, set, 10);
return 0;
}
You can use a mask to set flags into, the flags being wether a digit has already been seen in the number or not. Like this:
int mask = 0x0, j;
for(j= 1; j<=9; j++){
if(mask & 1<<(input%10))
return 0;
else
mask |= 1<<(input%10);
input /= 10;
}
return !(mask & 1);
The complete program:
#include <stdio.h>
int check(int input)
{
int mask = 0x0, j;
for(j= 1; j<=9; j++){
if(mask & 1<<(input%10))
return 0;
else
mask |= 1<<(input%10);
input /= 10;
}
/* At this point all digits are unique
We're not interested in zero, though */
return !(mask & 1);
}
int main()
{
int indx;
for( indx = 123456789; indx <=987654321; indx++){
if( check(indx) )
printf("%d\n",indx);
}
}
Edited...
Or you could do the same with an array:
int check2(int input)
{
int j, arr[10] = {0,0,0,0,0,0,0,0,0,0};
for(j=1; j<=9; j++) {
if( (arr[input%10]++) || (input%10 == 0) )
return 0;
input /= 10;
}
return 1;
}
Here's one approach - start with an array of unique digits, then randomly shuffle them:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main( void )
{
char digits[] = "123456789";
srand( time( NULL ) );
size_t i = sizeof digits - 1;
while( i )
{
size_t j = rand() % i;
char tmp = digits[--i];
digits[i] = digits[j];
digits[j] = tmp;
}
printf( "number is %s\n", digits );
return 0;
}
Some sample output:
john#marvin:~/Development/snippets$ ./nine
number is 249316578
john#marvin:~/Development/snippets$ ./nine
number is 928751643
john#marvin:~/Development/snippets$ ./nine
number is 621754893
john#marvin:~/Development/snippets$ ./nine
number is 317529864
Note that these are character strings of unique decimal digits, not numeric values; if you want the corresponding integer value, you'd need to do a conversion like
long val = strtol( digits, NULL, 10 );
Rather than 10 variables, I would make a single variable with a bit set (and testable) for each of the 10 digits. Then you only need a loop setting (and testing) the bit corresponding to each digit. Something like this:
int ok = 1;
unsigned bits = 0;
int digit;
unsigned powers10 = 1;
for (digit = 0; digit < 10; ++digit) {
unsigned bit = 1 << ((num / powers10) % 10);
if ((bits & bit) != 0) {
ok = 0;
break;
}
bits |= bit;
powers10 *= 10;
}
if (ok) {
printf("%d\n", num);
}
Complete program (discarding unnecessary #include lines):
#include <stdio.h>
int main(void)
{
int indx;
int num;
for(indx = 123456789; indx <= 987654321; indx++)
{
num = indx;
int ok = 1;
unsigned bits = 0;
int digit;
unsigned powers10 = 1;
for (digit = 0; digit < 9; ++digit) {
unsigned bit = 1 << ((num / powers10) % 10);
if ((bit == 1) || ((bits & bit) != 0)) {
ok = 0;
break;
}
bits |= bit;
powers10 *= 10;
}
if (ok) {
printf("%d\n", num);
}
}
return 0;
}
OP clarified his question as I was leaving for work, and I had not focused on the lack of zeroes being requested. (response is updated now). This produces the expected 362880 combinations.
However - there was a comment about one answer being fastest, which prompts a followup. There were (counting this one) three comparable answers. In a quick check:
#Paul Hankin's answer (which counts zeros and gives 3265920 combinations):
real 0m0.951s
user 0m0.894s
sys 0m0.056s
this one:
real 0m49.108s
user 0m49.041s
sys 0m0.031s
#George André's answer (which also produced the expected number of combinations):
real 1m27.597s
user 1m27.476s
sys 0m0.051s
Check this code.
#include<stdio.h>
//it can be done by recursion
void func(int *flag, int *num, int n){ //take 'n' to count the number of digits
int i;
if(n==9){ //if n=9 then print the number
for(i=0;i<n;i++)
printf("%d",num[i]);
printf("\n");
}
for(i=1;i<=9;i++){
//put the digits into the array one by one and send if for next level
if(flag[i-1]==0){
num[n]=i;
flag[i-1]=1;
func(flag,num,n+1);
flag[i-1]=0;
}
}
}
//here is the MAIN function
main(){
int i,flag[9],num[9];
for(i=0;i<9;i++) //take a flag to avoid repetition of digits in a number
flag[i]=0; //initialize the flags with 0
func(flag,num,0); //call the function
return 0;
}
If you have any question feel free to ask.
I recommend Nominal Animal's answer, but if you are only generating this value so you can print it out you can eliminate some of the work and at the same time get a more generic routine using the same method:
char *shuffle( char *digit, int digits, int count, unsigned int seed )
{
//optional: do some validation on digit string
// ASSERT(digits == strlen(digit));
//optional: validate seed value is reasonable
// for(unsigned int badseed=1, x=digits, y=count; y > 0; x--, y--)
// badseed *= x;
// ASSERT(seed < badseed);
char *work = digit;
while(count--)
{
int i = seed % digits;
seed /= digits--;
unsigned char selectedDigit = work[i];
work[i] = work[0];
work[0] = selectedDigit;
work++;
}
work[0] = 0;
//seed should be zero here, else the seed contained extra information
return digit;
}
This method is destructive on the digits passed in, which don't actually have to be numeric, or unique for that matter.
On the off chance that you want the output values generated in sorted increasing order that's a little more work:
char *shuffle_ordered( char *digit, int digits, int count, unsigned int seed )
{
char *work = digit;
int doneDigits = 0;
while(doneDigits < count)
{
int i = seed % digits;
seed /= digits--;
unsigned char selectedDigit = work[i];
//move completed digits plus digits preceeding selectedDigit over one place
memmove(digit+1,digit,doneDigits+i);
digit[0] = selectedDigit;
work++;
}
work[0] = 0;
//seed should be zero here, else the seed contained extra information
return digit;
}
In either case it's called like this:
for(unsigned int seed = 0; seed < 16*15*14; ++seed)
{
char work[] = "0123456789ABCDEF";
printf("seed=%d -> %s\n",shuffle_ordered(work,16,3,seed));
}
This should print out an ordered list of three digit hex values with no duplicated digits:
seed 0 -> 012
seed 1 -> 013
...
seed 3358 -> FEC
seed 3359 -> FED
I don't know what you are actually doing with these carefully crafted sequences of digits. If some poor sustaining engineer is going to have to come along behind you to fix some bug, I recommend the ordered version, as it is way easier for a human to convert seed from/to sequence value.
Here is a bit ugly but very fast solution using nested for loops.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define NINE_FACTORIAL 362880
int main(void) {
//array where numbers would be saved
uint32_t* unique_numbers = malloc( NINE_FACTORIAL * sizeof(uint32_t) );
if( !unique_numbers ) {
printf("Could not allocate memory for the Unique Numbers array.\n");
exit(1);
}
uint32_t n = 0;
int a,b,c,d,e,f,g,h,i;
for(a = 1; a < 10; a++) {
for(b = 1; b < 10; b++) {
if (b == a) continue;
for(c = 1; c < 10; c++) {
if(c==a || c==b) continue;
for(d = 1; d < 10; d++) {
if(d==a || d==b || d==c) continue;
for(e = 1; e < 10; e++) {
if(e==a || e==b || e==c || e==d) continue;
for(f = 1; f < 10; f++) {
if (f==a || f==b || f==c || f==d || f==e)
continue;
for(g = 1; g < 10; g++) {
if(g==a || g==b || g==c || g==d || g==e
|| g==f) continue;
for(h = 1; h < 10; h++) {
if (h==a || h==b || h==c || h==d ||
h==e || h==f || h==g) continue;
for(i = 1; i < 10; i++) {
if (i==a || i==b || i==c || i==d ||
i==e || i==f || i==g || i==h) continue;
// print the number or
// store the number in the array
unique_numbers[n++] = a * 100000000
+ b * 10000000
+ c * 1000000
+ d * 100000
+ e * 10000
+ f * 1000
+ g * 100
+ h * 10
+ i;
}
}
}
}
}
}
}
}
}
// do stuff with unique_numbers array
// n contains the number of elements
free(unique_numbers);
return 0;
}
Same thing using some macros.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define l_(b,n,c,p,f) { int i; for(i = 1; i < 10; i++) { \
int j,r=0; for(j=0;j<p;j++){if(i == c[j]){r=1;break;}} \
if(r) continue; c[p] = i; f } }
#define l_8(b,n,c,p) { \
int i; for(i=1; i< 10; i++) {int j, r=0; \
for(j=0; j<p; j++) {if(i == c[j]) {r = 1; break;}} \
if(r)continue; b[n++] = c[0] * 100000000 + c[1] * 10000000 \
+ c[2] * 1000000 + c[3] * 100000 + c[4] * 10000 \
+ c[5] * 1000 + c[6] * 100 + c[7] * 10 + i; } }
#define l_7(b,n,c,p) l_(b,n,c,p, l_8(b,n,c,8))
#define l_6(b,n,c,p) l_(b,n,c,p, l_7(b,n,c,7))
#define l_5(b,n,c,p) l_(b,n,c,p, l_6(b,n,c,6))
#define l_4(b,n,c,p) l_(b,n,c,p, l_5(b,n,c,5))
#define l_3(b,n,c,p) l_(b,n,c,p, l_4(b,n,c,4))
#define l_2(b,n,c,p) l_(b,n,c,p, l_3(b,n,c,3))
#define l_1(b,n,c,p) l_(b,n,c,p, l_2(b,n,c,2))
#define get_unique_numbers(b,n,c) do {int i; for(i=1; i<10; i++) { \
c[0] = i; l_1(b,n,c,1) } } while(0)
#define NINE_FACTORIAL 362880
int main(void) {
//array where numbers would be saved
uint32_t* unique_numbers = malloc( NINE_FACTORIAL * sizeof(uint32_t) );
if( !unique_numbers ) {
printf("Could not allocate memory for the Unique Numbers array.\n");
exit(1);
}
int n = 0;
int current_number[8] = {0};
get_unique_numbers(unique_numbers, n, current_number);
// do stuff with unique_numbers array
// NINE_FACTORIAL is the number of elements
free(unique_numbers);
return 0;
}
I am sure there are better ways to write those macros, but that is what I could think of.
A simple way is to create an array with nine distinct values, shuffle it, and print the shuffled array. Repeat as many times as needed. For example, using the standard rand() function as a basis for shuffling ...
#include <stdlib.h> /* for srand() and rand */
#include <time.h> /* for time() */
#include <stdio.h>
#define SIZE 10 /* size of working array. There are 10 numeric digits, so .... */
#define LENGTH 9 /* number of digits we want to output. Must not exceed SIZE */
#define NUMBER 12 /* number of LENGTH digit values we want to output */
void shuffle(char *buffer, int size)
{
int i;
char temp;
for (i=size-1; i>0; --i)
{
/* not best way to get a random value of j in [0, size-1] but
sufficient for illustrative purposes
*/
int j = rand()%size;
/* swap buffer[i] and buffer[j] */
temp = buffer[i];
buffer[i] = buffer[j];
buffer[j] = temp;
}
}
void printout(char *buffer, int length)
{
/* this assumes SIZE <= 10 and length <= SIZE */
int i;
for (i = 0; i < length; ++i)
printf("%d", (int)buffer[i]);
printf("\n");
}
int main()
{
char buffer[SIZE];
int i;
srand((unsigned)time(NULL)); /* seed for rand(), once and only once */
for (i = 0; i < SIZE; ++i) buffer[i] = (char)i; /* initialise buffer */
for (i = 0; i < NUMBER; ++i)
{
/* keep shuffling until first value in buffer is non-zero */
do shuffle(buffer, SIZE); while (buffer[0] == 0);
printout(buffer, LENGTH);
}
return 0;
}
This prints a number of lines to stdout, each with 9 unique digits. Note that this does not prevent duplicates.
EDIT: After further analysis, more recursion unrolling and only iterating on set bits resulted in significant improvement, in my testing roughly FIVE times as fast. This was tested with OUTPUT UNSET to compare algorithm speed not console output, start point is uniq_digits9 :
int counter=0;
int reps=0;
void show(int x)
{
#ifdef OUTPUT
printf("%d\n", x);
#else
counter+=x;
++reps;
#endif
}
int bit_val(unsigned int v)
{
static const int MultiplyDeBruijnBitPosition2[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return MultiplyDeBruijnBitPosition2[(unsigned int)(v * 0x077CB531U) >> 27];
}
void uniq_digits1(int prefix, unsigned int used) {
show(prefix*10+bit_val(~used));
}
void uniq_digits2(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits1(base+bit_val(bit), used|bit);
}
}
void uniq_digits3(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits2(base+bit_val(bit), used|bit);
}
}
void uniq_digits4(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits3(base+bit_val(bit), used|bit);
}
}
void uniq_digits5(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits4(base+bit_val(bit), used|bit);
}
}
void uniq_digits6(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits5(base+bit_val(bit), used|bit);
}
}
void uniq_digits7(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits6(base+bit_val(bit), used|bit);
}
}
void uniq_digits8(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits7(base+bit_val(bit), used|bit);
}
}
void uniq_digits9() {
unsigned int used=~((1<<10)-1); // set all bits except 0-9
#ifndef INCLUDE_ZEROS
used |= 1;
#endif
for (int i = 1; i < 10; i++) {
unsigned int bit=1<<i;
uniq_digits8(i,used|bit);
}
}
Brief explanation:
There are 9 digits and the first cannot start with zero, so the first digit can be from 1 to 9, the rest can be 0 to 9
If we take a number, X and multiply it by 10, it shifts one place over. So, 5 becomes 50. Add a number, say 3 to make 53, and then multiply by 10 to get 520, and then add 2, and so on for all 9 digits.
Now some storage is needed to keep track of what digits were used so they aren't repeated. 10 true/false variables could be used: used_0_p, used_1_P , .... But, that is inefficient, so they can be placed in an array: used_p[10]. But then it would need to be copied every time before making a call the next place so it can reset it for the next digit, otherwise once all places are filled the first time the array would be all true and no other combinations could be calculated.
But, there is a better way. Use bits of an int as the array. X & 1 for the first, X & 2, X & 4, X & 8, etc. This sequence can be represented as (1<<X) or take the first bit and shift it over X times.
& is used to test bits, | is used to set them. In each loop we test if the bit was used (1<<i)&used and skip if it was. At the next place we shift the digits for each digit prefix*10+i and set that digit as used used|(1<<i)
Explanation of looping in the EDIT
The loop calculates Y & (Y-1) which zeroes the lowest set bit. By taking the original and subtracting the result the difference is the lowest bit. This will loop only as many times as there are bits: 3,265,920 times instead of 900,000,000 times. Switching from used to unused is just the ~ operator, and since setting is more efficient than unsetting, it made sense to flip
Going from power of two to its log2 was taken from: https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog . This site also details the loop mechanism: https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
Moving original to the bottom:
This is too long for a comment, but This answer can be make somewhat faster by removing the zero handling from the function: ( See edit for fastest answer )
void uniq_digits(int places, int prefix, int used) {
if (!places) {
printf("%d\n", prefix);
return;
}
--places;
int base=prefix*10;
for (int i = 0; i < 10; i++)
{
if ((1<<i)&used) continue;
uniq_digits(places, base+i, used|(1<<i));
}
}
int main(int argc, char**argv) {
const int num_digits=9;
// unroll top level to avoid if for every iteration
for (int i = 1; i < 10; i++)
{
uniq_digits(num_digits-1, i, 1 << i);
}
return 0;
}
A bit late to the party, but very fast (30 ms here) ...
#include <stdio.h>
#define COUNT 9
/* this buffer is global. intentionally.
** It occupies (part of) one cache slot,
** and any reference to it is a constant
*/
char ten[COUNT+1] ;
unsigned rec(unsigned pos, unsigned mask);
int main(void)
{
unsigned res;
ten[COUNT] = 0;
res = rec(0, (1u << COUNT)-1);
fprintf(stderr, "Res=%u\n", res);
return 0;
}
/* recursive function: consume the mask of available numbers
** until none is left.
** return value is the number of generated permutations.
*/
unsigned rec(unsigned pos, unsigned mask)
{
unsigned bit, res = 0;
if (!mask) { puts(ten); return 1; }
for (bit=0; bit < COUNT; bit++) {
if (! (mask & (1u <<bit)) ) continue;
ten[pos] = '1' + bit;
res += rec(pos+1, mask & ~(1u <<bit));
}
return res;
}
iterative version that uses bits extensively
note that array can be changed to any type, and set in any order
this will "count"the digits in given order
For more explaination look at my first answer (which is less flexible but much faster) https://stackoverflow.com/a/31928246/2963099
In order to make it iterative, arrays were needed to keep state at each level
This also went though quite a bit of optimization for places the optimizer couldn't figure out
int bit_val(unsigned int v) {
static const int MultiplyDeBruijnBitPosition2[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return MultiplyDeBruijnBitPosition2[(unsigned int)(v * 0x077CB531U) >> 27];
}
void uniq_digits(const int array[], const int length) {
unsigned int unused[length-1]; // unused prior
unsigned int combos[length-1]; // digits untried
int digit[length]; // printable digit
int mult[length]; // faster calcs
mult[length-1]=1; // start at 1
for (int i = length-2; i >= 0; --i)
mult[i]=mult[i+1]*10; // store multiplier
unused[0]=combos[0]=((1<<(length))-1); // set all bits 0-length
int depth=0; // start at top
digit[0]=0; // start at 0
while(1) {
if (combos[depth]) { // if bits left
unsigned int avail=combos[depth]; // save old
combos[depth]=avail & (avail-1); // remove lowest bit
unsigned int bit=avail-combos[depth]; // get lowest bit
digit[depth+1]=digit[depth]+mult[depth]*array[bit_val(bit)]; // get associated digit
unsigned int rest=unused[depth]&(~bit); // all remaining
depth++; // go to next digit
if (depth!=length-1) { // not at bottom
unused[depth]=combos[depth]=rest; // try remaining
} else {
show(digit[depth]+array[bit_val(rest)]); // print it
depth--; // stay on same level
}
} else {
depth--; // go back up a level
if (depth < 0)
break; // all done
}
}
}
Some timings using just 1 to 9 with 1000 reps:
15.00s Recursive (modified to count 1 to 9) from https://stackoverflow.com/a/31828305/2963099
3.53s swap recursion from https://stackoverflow.com/a/31830671/2963099
2.74s nextPermutation version (https://stackoverflow.com/a/31885811/2963099)
2.34s This Solution
1.66s unrolled recursive version in EDIT from https://stackoverflow.com/a/31928246/2963099
Make a list with 10 elements with values 0-9. Pull random elements out by rand() /w current length of list, until you have the number of digits you want.

Converting ascii hex string to byte array

I have a char array say char value []={'0','2','0','c','0','3'};
I want to convert this into a byte array like unsigned char val[]={'02','0c','03'}
This is in an embedded application so i can't use string.h functions. How can i do this?
Sicne you talk about an embedded application I assume that you want to save the numbers as values and not as strings/characters. So if you just want to store your character data as numbers (for example in an integer), you can use sscanf.
This means you could do something like this:
char source_val[] = {'0','A','0','3','B','7'} // Represents the numbers 0x0A, 0x03 and 0xB7
uint8 dest_val[3]; // We want to save 3 numbers
for(int i = 0; i<3; i++)
{
sscanf(&source_val[i*2],"%x%x",&dest_val[i]); // Everytime we read two chars --> %x%x
}
// Now dest_val contains 0x0A, 0x03 and 0xB7
However if you want to store it as a string (like in your example), you can't use unsigned char
since this type is also just 8-Bit long, which means it can only store one character. Displaying 'B3' in a single (unsigned) char does not work.
edit: Ok according to comments, the goal is to save the passed data as a numerical value. Unfortunately the compiler from the opener does not support sscanf which would be the easiest way to do so. Anyhow, since this is (in my opinion) the simplest approach, I will leave this part of the answer at it is and try to add a more custom approach in this edit.
Regarding the data type, it actually doesn't matter if you have uint8. Even though I would advise to use some kind of integer data type, you can also store your data into an unsigned char. The problem here is, that the data you get passed, is a character/letter, that you want to interpret as a numerical value. However, the internal storage of your character differs. You can check the ASCII Table, where you can check the internal values for every character.
For example:
char letter = 'A'; // Internally 0x41
char number = 0x61; // Internally 0x64 - represents the letter 'a'
As you can see there is also a differnce between upper an lower case.
If you do something like this:
int myVal = letter; //
myVal won't represent the value 0xA (decimal 10), it will have the value 0x41.
The fact you can't use sscanf means you need a custom function. So first of all we need a way to conver one letter into an integer:
int charToInt(char letter)
{
int myNumerical;
// First we want to check if its 0-9, A-F, or a-f) --> See ASCII Table
if(letter > 47 && letter < 58)
{
// 0-9
myNumerical = letter-48;
// The Letter "0" is in the ASCII table at position 48 -> meaning if we subtract 48 we get 0 and so on...
}
else if(letter > 64 && letter < 71)
{
// A-F
myNumerical = letter-55
// The Letter "A" (dec 10) is at Pos 65 --> 65-55 = 10 and so on..
}
else if(letter > 96 && letter < 103)
{
// a-f
myNumerical = letter-87
// The Letter "a" (dec 10) is at Pos 97--> 97-87 = 10 and so on...
}
else
{
// Not supported letter...
myNumerical = -1;
}
return myNumerical;
}
Now we have a way to convert every single character into a number. The other problem, is to always append two characters together, but this is rather easy:
int appendNumbers(int higherNibble, int lowerNibble)
{
int myNumber = higherNibble << 4;
myNumber |= lowerNibbler;
return myNumber;
// Example: higherNibble = 0x0A, lowerNibble = 0x03; -> myNumber 0 0xA3
// Of course you have to ensure that the parameters are not bigger than 0x0F
}
Now everything together would be something like this:
char source_val[] = {'0','A','0','3','B','7'} // Represents the numbers 0x0A, 0x03 and 0xB7
int dest_val[3]; // We want to save 3 numbers
int temp_low, temp_high;
for(int i = 0; i<3; i++)
{
temp_high = charToInt(source_val[i*2]);
temp_low = charToInt(source_val[i*2+1]);
dest_val[i] = appendNumbers(temp_high , temp_low);
}
I hope that I understood your problem right, and this helps..
If you have a "proper" array, like value as declared in the question, then you loop over the size of it to get each character. If you're on a system which uses the ASCII alphabet (which is most likely) then you can convert a hexadecimal digit in character form to a decimal value by subtracting '0' for digits (see the linked ASCII table to understand why), and subtracting 'A' or 'a' for letters (make sure no letters are higher than 'F' of course) and add ten.
When you have the value from the first hexadeximal digit, then convert the second hexadecimal digit the same way. Multiply the first value by 16 and add the second value. You now have single byte value corresponding to two hexadecimal digits in character form.
Time for some code examples:
/* Function which converts a hexadecimal digit character to its integer value */
int hex_to_val(const char ch)
{
if (ch >= '0' && ch <= '9')
return ch - '0'; /* Simple ASCII arithmetic */
else if (ch >= 'a' && ch <= 'f')
return 10 + ch - 'a'; /* Because hex-digit a is ten */
else if (ch >= 'A' && ch <= 'F')
return 10 + ch - 'A'; /* Because hex-digit A is ten */
else
return -1; /* Not a valid hexadecimal digit */
}
...
/* Source character array */
char value []={'0','2','0','c','0','3'};
/* Destination "byte" array */
char val[3];
/* `i < sizeof(value)` works because `sizeof(char)` is always 1 */
/* `i += 2` because there is two digits per value */
/* NOTE: This loop can only handle an array of even number of entries */
for (size_t i = 0, j = 0; i < sizeof(value); i += 2, ++j)
{
int digit1 = hex_to_val(value[i]); /* Get value of first digit */
int digit2 = hex_to_val(value[i + 1]); /* Get value of second digit */
if (digit1 == -1 || digit2 == -1)
continue; /* Not a valid hexadecimal digit */
/* The first digit is multiplied with the base */
/* Cast to the destination type */
val[j] = (char) (digit1 * 16 + digit2);
}
for (size_t i = 0; i < 3; ++i)
printf("Hex value %lu = %02x\n", i + 1, val[i]);
The output from the code above is
Hex value 1 = 02
Hex value 2 = 0c
Hex value 3 = 03
A note about the ASCII arithmetic: The ASCII value for the character '0' is 48, and the ASCII value for the character '1' is 49. Therefore '1' - '0' will result in 1.
It's easy with strtol():
#include <stdlib.h>
#include <assert.h>
void parse_bytes(unsigned char *dest, const char *src, size_t n)
{
/** size 3 is important to make sure tmp is \0-terminated and
the initialization guarantees that the array is filled with zeros */
char tmp[3] = "";
while (n--) {
tmp[0] = *src++;
tmp[1] = *src++;
*dest++ = strtol(tmp, NULL, 16);
}
}
int main(void)
{
unsigned char d[3];
parse_bytes(d, "0a1bca", 3);
assert(d[0] == 0x0a);
assert(d[1] == 0x1b);
assert(d[2] == 0xca);
return EXIT_SUCCESS;
}
If that is not available (even though it is NOT from string.h), you could do something like:
int ctohex(char c)
{
if (c >= '0' && c <= '9') {
return c - '0';
}
switch (c) {
case 'a':
case 'A':
return 0xa;
case 'b':
case 'B':
return 0xb;
/**
* and so on
*/
}
return -1;
}
void parse_bytes(unsigned char *dest, const char *src, size_t n)
{
while (n--) {
*dest = ctohex(*src++) * 16;
*dest++ += ctohex(*src++);
}
}
Assuming 8-bit bytes (not actually guaranteed by the C standard, but ubiquitous), the range of `unsigned char` is 0..255, and the range of `signed char` is -128..127. ASCII was developed as a 7-bit code using values in the range 0-127, so the same value can be represented by both `char` types.
For the now discovered task of converting a counted hex-string from ascii to unsigned bytes, here's my take:
unsigned int atob(char a){
register int b;
b = a - '0'; // subtract '0' so '0' goes to 0 .. '9' goes to 9
if (b > 9) b = b - ('A' - '0') + 10; // too high! try 'A'..'F'
if (b > 15) b = b - ('a' - 'A); // too high! try 'a'..'f'
return b;
}
void myfunc(const char *in, int n){
int i;
unsigned char *ba;
ba=malloc(n/2);
for (i=0; i < n; i+=2){
ba[i/2] = (atob(in[i]) << 4) | atob(in[i+1]);
}
// ... do something with ba
}

Resources