Finding consecutive bit string of 1 or 0 - c

How to find the length of the longest consecutive bit string(either 1 or 0)?
00000000 11110000 00000000 00000000 -> If it is 0 then length will be 20
11111111 11110000 11110111 11111111 -> If it is 1 then length will be 12

The following is based on the concept that if you AND a bit sequence with a shifted version of itself, you're effectively removing the trailing 1 from a row of consecutive 1's.
11101111 (x)
& 11011110 (x << 1)
----------
11001110 (x & (x << 1))
^ ^
| |
trailing 1 removed
Repeating this N times will reduce any sequence with N consecutive 1's to 0x00.
So, to count the number of consecutive 1's:
int count_consecutive_ones(int in) {
int count = 0;
while (in) {
in = (in & (in << 1));
count++;
}
return count;
}
To count the number of consecutive 0's, simply invert and the same routine.
int count_consecutive_zeros(int in) {
return count_consecutive_ones(~in);
}
Proof of concept: http://ideone.com/Z1l0D
int main(void) {
printf("%d has %d consecutive 1's\n", 0, count_consecutive_ones(0));
printf("%d has %d consecutive 0's\n", 0, count_consecutive_zeros(0));
/* 00000000 11110000 00000000 00000000 -> If it is 0 then length will be 20 */
printf("%x has %d consecutive 0's\n", 0x00F00000, count_consecutive_zeros(0x00F00000));
/* 11111111 11110000 11110111 11111111 -> If it is 1 then length will be 12 */
printf("%x has %d consecutive 1's\n", 0xFFF0F7FF, count_consecutive_ones(0xFFF0F7FF));
}
Output:
0 has 0 consecutive 1's
0 has 32 consecutive 0's
f00000 has 20 consecutive 0's
fff0f7ff has 12 consecutive 1's

One simple way would be to simply loop over the bits, and keep track of the number of bits in a row which have had the same value, and the maximum that this value has reached.
Here's a simple C function which does just this:
int num_conseq_matching_bits(int n) {
int i, max, cur, b, prevb;
prevb = n & 1; /* 0th bit */
cur = 1;
max = 1;
for(i=1; i<32; i++) {
b = (n >> i) & 1; /* get the i'th bit's value */
if(b == prevb) {
cur += 1;
if(cur > max)
max = cur;
}
else {
cur = 1; /* count self */
prevb = b;
}
}
return max;
}

You can form a look up table to do it quickly for you. The bigger the table, the faster the lookup. 2x256 entry tables can do 8 bits at a time with a little bit twiddling. Add a 1s version of the table and start adding entries. That's probably how I'd go about it.

To use the table idea, you need something like
static struct {
int lead; /* leading 0 bits */
int max; /* maximum 0 bits */
int trail; /* trailing 0 bits */
} table[256] = { ....data.... };
int mostConsecutiveBits(unsigned char *str, int length, bool count_ones) {
int max = 0; /* max seen so far */
int trail = 0; /* trailing 0s from previous bytes */
while (length-- > 0) {
int byte = *str++;
if (count_ones)
byte ^= 0xff;
if (table[byte].max > max)
max = table[byte].max;
if (trail + table[byte].lead > max)
max = trail + table[byte].lead;
if (byte)
trail = table[byte].trail;
else
trail += 8;
}
return max;
}
initializing the table is straight-forward, but depends on your bit- and byte-ordering (little endian or big endian).

Since you didn't wrote what is bit string (regular int, byte array or char string I've assumed that it's char array
int maxConsBits(char *pStr,char cChar)
{
char curChar;
int curMax = 0;
int max = 0;
while (pStr)
{
if (*pStr == cChar)
{
curMax++;
if (curMax > max)
{
max = curMax;
}
}
else
{
curMax = 0;
}
pStr++;
}
return max;
}

Posting from iPhone withbig fingers.
If ones, then invert.
Loop over the input using a leadz function. For each iteration, shift the input to the left. Continue until you reach the end of the input. Note that you need to compare the original input length with the cumulative leadz counts.
Also, as an optimization, you can early abort when the remaining input length is less than the largest leadz you have seen.
There are many fast leadz algorithms online.

I don't agree with the tables idea, because I was trying it and realized that even though "BA" in ASCII would contain 5 consecutive 0's for 'B' and 5 consecutive 0's for 'A', they will not add together for 10 consecutive 0's. As a matter of fact, there would be 5 consecutive 0's maximum. (This was in reference to a simple "counting bits in a table idea." Chris Dodd has since expounded on how a table could be used accurately.)
I would use an algorithm like this:
#include <iostream>
#include <algorithm>
using namespace std;
// Assumes Little Endian architecture
int mostConsecutiveBits(char str[], int length) {
int currentConsecutiveBits=0;
int maxConsecutiveBits=0;
char currentBit;
char lastBit=0;
char currentChar=str[0];
int charCtr,bitCtr;
for (charCtr=length-1; charCtr>=0; charCtr--) {
currentChar=str[charCtr];
for (bitCtr=0; bitCtr<8; bitCtr++) {
currentBit=currentChar & 1;
if (currentBit!=lastBit) {
maxConsecutiveBits=max(maxConsecutiveBits,currentConsecutiveBits);
currentConsecutiveBits=1;
lastBit=currentBit;
}
else {
currentConsecutiveBits++;
}
currentChar=currentChar>>1;
}
maxConsecutiveBits=max(maxConsecutiveBits,currentConsecutiveBits);
}
return maxConsecutiveBits;
}
int main (int argc, char * const argv[]) {
cout << mostConsecutiveBits("AB",2);
return 0;
}
In this algorithm, I assume the bitstream is represented as 8-bit characters. For each character, I look at the very last bit with a bitwise AND. If it's the same as the last bit, then I up the consecutive bit count, otherwise, I reset the count because the bits are no longer consecutive. I then use a bitwise shift operation to move the next bit in the character over for observation. Hope this helps!
My answer is effectively a duplicate of David Underhill's answer. :)

If you're just looking for a byte string of four bytes, you can pack these into an unsigned long and use an algorithm like this:
int CountConsecutiveOnes(unsigned long n)
{
unsigned long m = n;
int k = 0;
while (m)
{
++k;
n >>= 1;
m &= n;
}
return k;
}
For counting zeros, just taking the bitwise complement first.
If you need to count byte strings longer than four, you can just implement the operations x >>= 1 and x & y either directly on the byte strings or it may be more efficient to use strings of unsigned long so the carry checks on the implementation of x >>= 1 aren't too expensive.

It may help you....
First convert your binary number to String say bits.
It will give you max number of consecutive 1's (in java)
String[] split = bits.split("0");
Arrays.sort(split);
int maxLength = split[split.length - 1].length();

public static int maxConsecutiveOneInBinaryNumber(int number) {
int count = 0;
int max = 0;
while (number != 0) {
if ((number & 1) == 1) {
count++;
} else {
max = Math.max(count, max);
count = 0;
}
number = number >> 1;
}
return Math.max(count, max);
}
You can this code here:
https://github.com/VishalSKumar/DSFiddle/blob/master/src/main/java/com/vishalskumar/hackerrank/MaxConsecutiveOneInBinary.java

Related

Quick way to turn a binary array into a decimal string

I have a binary number, stored in an array of bytes (unsigned chars), and want to turn it into a decimal string.
The "obvious" approach that i found online was, to iterate over the array, add everything up while keeping track of the base and then converting it into a string but this doesn't work for me because the whole number doesn't fit into any common datatype and therefor cannot be added up in one go.
typedef unsigned char byte;
typedef struct Bin {
int size;
byte *ptrToVal;
} Bin;
void asDecString(Bin* this) {
signed int n = 0;
for(int i = 0; i < this->size; i++) {
n += this->ptrToVal[i] << (i * 8);
printf("%u\t%u\t%u\n", this->ptrToVal[i], n, i);
}
printf("%u\n", n);
}
The second, slow approach is to store the number in a string and multiply the digits in the string.
I'm looking for a quick way to implement this in c, but because I'm completely new to the language I don't know the features that well.
Out of curiosity and interest, here's my implementation of the algorithm found at:
https://my.eng.utah.edu/~nmcdonal/Tutorials/BCDTutorial/BCDConversion.html
It outputs intermediary values as each bit is processed. The verbose block can be moved out of the loop after testing.
Try it with one or two 'hex' bytes to begin with.
#include <stdio.h>
typedef unsigned char binByte;
void toBCD( binByte *p, int size ) {
const int decSize = 50; // Arbitrary limit of 10^49.
binByte decDgt[ decSize ]; // decimal digits as binary 'nibbles'.
int curPow10 = 0;
memset( decDgt, 0, sizeof(decDgt) );
for( int i = 0; i < size; i++ ) {
binByte oneByte = p[ i ]; // Initial one byte value
for( binByte bit = 0x80; bit > 0; bit >>= 1 ) {
for( int ii = 0; ii <= curPow10; ii++ )
if( decDgt[ ii ] >= 5 ) // Algorithm step
decDgt[ ii ] += 3;
for( ii = curPow10; ii >= 0; ii-- ) {
decDgt[ ii ] <<= 1;
if( decDgt[ ii ] & 0x10 ) { // Carry high bit?
decDgt[ ii + 1 ] |= 0x1;
if( ii == curPow10 ) // new power of 10?
curPow10++;
}
decDgt[ ii ] &= 0xF; // dealing in 'nibbles'
}
decDgt[ 0 ] |= ( (oneByte & bit) != 0 ); // truth value 0 or 1
printf( "Bottom: " );
for( ii = curPow10; ii >= 0; ii-- )
putchar( decDgt[ ii ] + '0' );
putchar( '\n' );
}
}
}
void main( void ) {
binByte x[] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF };
toBCD( x, sizeof(x) );
}
For large integers; you want to break them into "small enough integers", then convert the "small enough integers" into digits.
For example, lets say you have the number 1234567890. By doing next_piece = number / 100; number = number % 100; you could split it into pieces that fit in one byte, then print the smaller pieces 12, 34, 56, 78, 90 (with nothing between them and leading zeros to ensure the piece 03 doesn't get printed as 3) so that it looks like a single larger number.
In the same way you could split it into pieces that fit in a 32-bit unsigned integer; so that each piece is from 0 to 1000000000, by doing something like next_piece = number / 1000000000; number = number % 1000000000;. For example, the number 11223344556677889900112233445566778899 could be split into 11, 223344556, 677889900, 112233445, 566778899 and then printed (with leading zeros, etc).
Of course for big integers you'd need to implement a "divide by 1000000000" that works with your data structure, that returns a uint32_t (the remainder or the next piece) and the original value divided by 1000000000.
This is where things get messy. Using an array of bytes is slow, and signed numbers are painful. To fix that you'd want something more like:
#include <stdint.h>
typedef struct AlternativeBin {
int signFlag;
int size;
uint32_t *ptrToVal;
} AlternativeBin;
It wouldn't be hard to convert from your original format into this alternative format (if you can't just use this alternative format for everything).
The division loop would look something like (untested):
// WARNING: Destructive (the input value is used to return the quotient)
uint32_t getNextPiece(AlternativeBin * value) {
uint64_t temp = 0;
int i;
// Do the division
for(i = value->size - 1; i >= 0; i--) {
temp = (temp << 32) | value->ptrToVal[i];
value->ptrToVal[i] = temp / 1000000000ULL;
temp = temp % 1000000000ULL;
}
// Reduce the size of the array to improve performance next time
while( (value->size > 0) && (value->ptrToVal[value->size - 1] == 0) ) {
value->size--;
}
return temp;
}
..which means the "printing loop" (using recursion to reverse the order of pieces) might look like (untested):
#include <stdio.h>
#include <inttypes.h>
// WARNING: Recursive and destructive (the input value is destroyed)
void printPieces(AlternativeBin * value) {
uint32_t piece;
piece = getNextPiece(value);
if( !value_became_zero(value) ) {
printPieces(value);
printf("%09" PRIu32, piece); // Print it with leading zeros
} else {
printf("%" PRIu32, piece); // No leading zeros on first piece printed
}
}
The other minor inconvenience is that you'll want to print a '-' at the start if the value is negative (untested):
// WARNING: Destructive (the input value is destroyed)
void printValue(AlternativeBin * value) {
if(value->signFlag) {
printf("-");
}
printPieces(value);
}
If you wanted you could also create a copy of the original data here (get rid of the WARNING: Destructive comment by destroying a copy and leaving the original unmodified); and convert from your original structure (bytes) into the alternative structure (with uint32_t).
Note that it would be possible to do all of this with bytes (something like your original structure) using a divisor of 100 (instead of 1000000000). It'd just be a lot slower because the expensive getNextPiece() function will need to be called about 4.5 as many times.

Recursion function to check if bit is set or not (1\0)

I have this template and I need to fill the empty places, the function needs to return (count) the number of set (1) bits in a number (x)
In this question, an int is 2 bytes aka 16 bits
Template:
int dlukim(int x, int n, int count)
{
if (n > 16)
(1); // return count;
else
{
if ( (2) ) count++;
(3);// n++;
dlukim((4), n, count) // x
}
}
What's after the // is what I think should fill the empty space and I just don't know what to do on empty space number 2.
This is quite contrived, but something like this:
int count_ones(unsigned int x, int count)
{
/* Base case: zero has no further bits set. */
if (x == 0)
return count;
return count_ones(x >> 1, count + (x & 1));
}
int main(void)
{
const unsigned int x = 0xfeedf00du;
printf("%u has %d\n", x, count_ones(x, 0));
return 0;
}
Not sure about the n argument, could be used to track which bit to inspect but I optimized it out and always inspect bit 0, using right-shift between recursive steps to move all bits through that position.
I also switched x to unsigned int since that's more "clean" when caring about the bits in my opinion.
So first of all, int is 4 bytes which are 32 bits. But for 16 bits integer the code should look like the following:
if (n > 16)
return count;
else {
if (x % 2 == 1) count++;
n++;
set_bits(x/2, n, count);
}
Dividing a number by 2 means moving it to the right side by 1 bit. If x % 2 is 1 - the current bit is set, for example consider the decimal number 7 which is 111 in it's binary representation, 7 % 2 = 1 and 7 / 2 = 3 which is 11 in binary, and so on...

Count number of adjacent pairs in Binary

Let's say that I'm given an integer n, which is read from the user.
I would like to count the number of adjacent pairs of 1's that is has.
So for example, let's say I'm given the number 31.
The binary representation of 31 is 11111.
The number of pairs would be 11 11 1 => 2 pairs
How would you do this using bitwise operators?
Thanks!
You have to validate the integer with the ((n&3)==3) condition to find an adjacent pairs in bit position 0 and 1. If pair found we shift to right by 2 otherwise by 1 until we did not check all of the 32 bits.
unsigned int n = 31; /* input */
unsigned char number_of_pairs = 0; /* result */
unsigned char mask_position = 0;
do
{
if(((n >> mask_position) & 3) == 3)
{
number_of_pairs += 1;
mask_position += 2;
}
else
{
mask_position += 1;
}
} while(mask_position < 32);

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.

C: Decimal Value

Can any one help me sort out one problem, i have to reverse a number without using array(int/char) for storing them.
input1 = 123
output1 = 321
input2 = 2300
output2 = 0032
I am trying to find the solution but 0 got erased while printing so i thought of octal conversion but still no solution, so i went with the decimal places and i made the 23 to 0.0032. Now my problem is how can i extract the 0032 from that part.
Is there any possible way to achieve this without using array(int/char), with that it will be easy.
#include<stdio.h>
#include<math.h>
int main()
{
int number =3200;
int temp;
while (number >0)
{
temp= number%10;
printf("%d",temp);
number = number/10;
}
return 0;
}
you could use recursion to solve this problem, without using any array in fact u could also reverse a string without using any array using recursion. This code works for both numbers and strings and it has no arrays:
char reverse(int a)
{
char c,d;
if(a=='\n')
return 0;
c=getchar();
d=reverse(c);
putchar(a);
return (c);
}
int main()
{
char c;
scanf("%c",&c);
reverse(c);
}
for a start try this.
int n, l;
char nBuf[126];
n = 1230010;
l = sprintf(nBuf, "%d", n );
while( l >= 0 )
printf("%c", nBuf[l--] );
Though if you are taking input from stdin take it as string rathar than as int or long.
Edit - for not using array
int n = 123;
while(n) {
printf("%d", n%10);
n/=10;
}
I am assuming to get a value of this sort "output2 = 0032" it is better of being a string, else formatting complications turns up with input value length and format left space with zeros etc etc.
This becomes fairly easy if you know that you can represent numbers like so:
x = a_0 + a_1 * b^1 + a_2 * b^2 + ...
a_i are the digits
b is the base
To extract the lowest digit, you can use the remainder: x % b
Dividing by the base "removes" the last digit. That way you can get the digits in order lowest to highest.
If you reverse the digits then the lowest becomes the highest. Looking at below transformation it's easy to see how to incrementally build up a number when the digits come in order highest to lowest:
x = a_0 + b * (a_1 + b * (a_2 + ...
You start of with 0, and for each digit you multiply with the base and then add the digit.
In pseudo code:
output = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
end
If you want to store leading zeros, then you need to either store the digits in an array, or remember for how many steps of above loop the output remained zero:
output = 0
zeros = 0
while input != 0
digit = input % base
input = input / base ;; integer division
output = output * base + digit
if output == 0
zeros = zeros + 1
end
end
To print that you obviously need to print zeros zeros and then the number.
Live example here, relevant code:
unsigned reverse(
unsigned input,
unsigned const base,
unsigned * const zeros) {
unsigned output = 0;
unsigned still_zero = 0;
for (; input != 0; input/=base) {
output *= base;
output += input % base;
if (output == 0) {
++still_zero;
}
}
if (zeros != NULL) {
*zeros = still_zero;
}
return output;
}
void print_zeros(unsigned zeros) {
for (; zeros != 0; --zeros) {
printf("0");
}
}
Recursion allows for a simple solution. A small variation on #vishu rathore
void rev_dec(void) {
int ch = getchar();
if (isdigit(ch)) {
rev_dec();
}
if (ch >= 0) putchar(ch);
}
int main(void) {
rev_dec();
return 0;
}
input
0123456789012345678901234567890123456789
output
9876543210987654321098765432109876543210

Resources