Coordinates of cell in Excel - c

I'm trying to get coordinates from Excel cell-numbers like A5, AC8, AAA8, and DADFAF145.
I read input from the user like this:
while( ( c = getchar() ) != EOF )
In the cycle I have a condition
if( c >= 48 && c <= 57 )
{
ungetc( c, stdin );
scanf( "%d\n", &column ); }
It check if c is a number 0-9, returns c to the buffer and read the number. The number is the y coordinate.
My problem is that I don't know how to get the X coordinate from the characters. I can't figure out an algorithm.
Index of A = 0, Z = 25, total 26 chars. If there is one char, it's ok. I dont' know how to solve if there are more chars.
Some examples:
A5
=> [5,0]
Z8
=> [8,25]
AAA2345
=> [2345,702] (26+26*26)
PA12
=> [12,416] (26+15*26)
AC23
=> [23,28]
NBFA349
=> [349,247572]

These letter combinations are actually base-26, however the digits are not from 0 to 25, but 1 to 26 instead (and are represented by letters from A to Z). So you can move from the end of the string to the beginning, multiply the digit (str[i]-'A'+1 where str[i] is the i-th character of the string str, i runs from strlen(str) to 0) to the corresponding power of 26. Like that:
int c = 1, s = 0;
for(int i = strlen(str)-1; i>=0; i--) {
s += (str[i]-'A'+1)*c; c*=26;
}
You must move from right to left, because, for example, number 28 is written as AB (and not BA)

The following might help. It defines a function which returns the column number of a string like "ADX". It coincides with what you will see if you enter the function =Column() in a cell in that column in an Excel spreadsheet:
#include <stdio.h>
#include <string.h>
long col_num(char* col);
int main(void){
char test1[] = "Z";
char test2[] = "AA";
char test3[] = "BZA";
printf("Column %s is column number %ld\n",test1,col_num(test1));
printf("Column %s is column number %ld\n",test2,col_num(test2));
printf("Column %s is column number %ld\n",test3,col_num(test3));
return 0;
}
long col_num(char* col){
long sum, i, n, p, val;
char letter;
n = strlen(col);
sum = 0;
p = 1;
for(i = n-1; i >= 0; i--){
letter = col[i];
val = letter - 'A' + 1;
sum += p*val;
p *= 26;
}
return sum;
}
I almost forgot. Output:
Column Z is column number 26
Column AA is column number 27
Column BZA is column number 2029

//"A" => 1, "Z" -> 26, "AAA" => 703, "NBFA" => 247573
int colToNum (const char *s){
int n = 0;
for(int i = 0; s[i] ; ++i)
n = n * 26 + (s[i] - 'A' + 1);
return n;//To zero origin : return n-1;
}

Related

Brute force function for decrypting string in C (Caesar cipher )

I found this problem interesting, as it is given that you need to use the alphabet as an array in C. Task is to brute force every possible K value, in basic Caesar's cipher manner.
However, code I come up with compile non-true values after K = 1. For example, a letter C is turned to Z instead of A etc. Can anyone spot what I did wrong?
#include <stdio.h>
#include <string.h>
void bruteforce (char*);
int main() {
char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
bruteforce(cyphertext);
return 0;
}
void bruteforce (char *cyphertext) {
char alphabet[26] = "abcdefghijklmnopqrstuvwxyz";
long int size = strlen(cyphertext);
for (int k = 0; k < 26; k++){
for (long int i = 0; i < size; i++){
for (int j = 0; j < 26; j++){
if (alphabet[j] == cyphertext[i]){
cyphertext[i] = alphabet[j - k];
if (k > j){
cyphertext[i] = alphabet[26 + j - k];
}
break;
}
}
}
printf("%s\n ", cyphertext);
}
}
For Caesar Cypher shifting, you don't need to use the alphabet string. You can just shift the character in ASCII code. ASCII codes of 'a' - 'z' are 97 - 122. Thus if decode with + 1. If the characters are a - z, you can just add one to each character. If after adding the shift value to the character value and the character value become larger than 122 then take the character value and subtract it to 122 then add 96 to that.
For shifting negative, if character value become smaller than 97. Take 97 subtract to character's value. Then subtract 123 to the previous equation value. Nonetheless, I built the code so that negative shift will be convert to positive shift. If the shift is negative we take 26 and add to that. Example is, shifting -1 will make a become z. So that is similar to shifting 26 + -1 = 25.
Shift value can be larger than +25 or smaller than -25. Nonetheless, if it is, it will be modulus to 26.
If you want to bruteforce all the possible combinations for a string. Just use the function below and run it in a loop from 1 to 25. But your function modify the original string. Thus, when doing bruteforce, you would have to copy the string of your function to a temporary string and let the function work on that. The examples are below.
#include <stdio.h>
#include <string.h>
void bruteforce (char *cyphertext, int shiftBy);
int main() {
char cyphertext[] = "kyvtrmrcipnzccrkkrtbwifdkyvefikynvjkrkeffe";
char cyphertext2[] = "yvccf wifd bvmze";
bruteforce(cyphertext, -17);
puts("");
bruteforce(cyphertext2, 9);
/* Bruteforce example */
puts("");
puts("Bruteforce section:");
// +9
char cyphertext3[] = "kyzjkvokzjkfsvtirtb nyrk tre kyzj sv zj zk yvccf nficu";
char temp[50];
for (int i = 1; i < 26; i++){
printf("Trying to crack by shifting %d \n", i );
strcpy(temp, cyphertext3);
bruteforce(temp, i);
puts("");
}
/* End Bruteforce example */
return 0;
}
// If there is no shift i.e 0, 26, 52, -26
// It won't print
void bruteforce (char *cyphertext, int shiftBy){
size_t size = strlen(cyphertext);
if ( shiftBy > 25){
shiftBy = shiftBy % 26;
} else if ( shiftBy < 0 ) {
shiftBy = 26 + (shiftBy % 26);
// If shiftBy is 26
// there is no need to shift.
if ( shiftBy == 26 ) return;
}
// If there is no shift return.
if ( shiftBy == 0 ) return;
for ( size_t i = 0; i < size; i++){
// 97 - 122 is a - z
// if char is a - z
if ( cyphertext[i] > 96 && cyphertext[i] < 123 ){
// add shift by
cyphertext[i] += shiftBy;
// if char > z
// then take char - z then add to the ascii code that just before 'a'.
// Since shiftBy is converted fomr negative to positive.,
// There will not be a negative shiftBy.
if ( (unsigned char)cyphertext[i] > 122 )
cyphertext[i] = ((unsigned char) cyphertext[i]) - 122 + 96;
}
// If want to do A - Z
// ASCII code are 65 - 90.
}
printf("%s\n", cyphertext);
}

No output shown on problem 8 of project euler

This is problem 8 of project euler.
I don't understand why no output is shown. Please don't write direct solution, I just wan't to know where my logic is wrong.
#include <stdio.h>
int main() {
//code
char a[1001]='7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450';
int p,i=0,m;
for(p=1;i<13;i++)p=p*((int)a[i]-48);m=p;printf("%d %d\n",m,p);
for(;i<1001&&a[i]!='\0';i++)
{
p=p/((int)(a[i-13]-48));
p=p*((int)(a[i]-48));
if(m<p)m=p;
}
printf("%d\n",m);
return 0;
}
There are some errors in the posted code, both syntactic and logical.
As already noted, you should use double quotes for the string literal. You could also write it splitted in different lines, the compiler will concatenate all the chuncks and add the \0 terminator.
const char *digits = "73167176531330624919225119674426574742355349194934"
// ...
"71636269561882670428252483600823257530420752963450";
The type int may be too small to represent the value of the product. The Standard only guarantees it to be capable of representing numbers up to 32767 and even a 32-bit (common this days) int can't store 913. I'd suggest using a long long and more meaningful names, e.g.:
#define MAX_ADJACENT_DIGITS 13
// ...
long long product = 0, max_product = 0;
int n_digits = 0;
The error in your algorithm is that it doesn't consider what happens when a digit is zero. An integer division by zero could lead to a runtime error, and besides that, all the products of the nearby digits are equal to zero.
Consider this modified version:
For every character in the string, from the first up to the one which is equal to '\0'
If it's equal to '0' (note the single quotes and the use of the actual char, not a "magic" number)
reset product and n_digits.
Skip the rest of the loop body (continue;).
If it's the first digit of a group of adjacent digits (n_digits == 0)
than product is equal to that digit and we can increase n_digits.
Continue with the next digit.
Here we can update the product (product *= digits[i] - '0';) and increase n_digits.
If we have exceeded the maximum number of adjacent digits
remove the oldest one (product /= digits[i - MAX_ADJACENT_DIGITS] - '0';) from the product and reset n_digits to the maximum.
Update the maximum value of the products, if the current product is bigger.
Following those steps, your program should find the sub-sequence of digits "5576689664895" and output their product.
You have wrong quotes in the initializer of char a[1001] - single quotes are for a character constant, use double quotes for a string literal. And get a better compilation environment - one which warns about such mistakes.
Then, the idea of removing the thirteenth-to-last factor from the current product seems clever at first sight, but it breaks if the digit is zero and you try to divide by it.
you have to change char a[1001] = '123'; to char a[] = "123"; then run it.here is the code
#include <stdio.h>
int main() {
//code
//' ' is used for single character, " " is for string.
char a[]="7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int p, i=0, m;
for(p=1;i<13;i++)
{
p = p * ( (int)a[i] - 48);
m = p;
printf("%d %d\n", m, p);
}
for( ; i < (1001 && a[i]!='\0'); i++)
{
p= p / ((int)(a[i-13] - 48));
p= p * ((int)(a[i] - 48));
if(m < p)
m = p;
}
printf("%d\n",m);
return 0;
}
output -:
7 7
21 21
126 126
882 882
882 882
6174 6174
37044 37044
185220 185220
555660 555660
555660 555660
5000940 5000940
5000940
This is my approach to the solution of euler #8. It first uses the strok(3) function to separate the complete string into pieces separated by 0 chars. Then it slides a window of length n over the separated strings (strings of length less than n cannot get enough digits to form a product without involving a 0 so they are discarded.
We then construct the first product by multiplying the first set of n digits. Once it is set, the window is sliced, by multiplying the product by the next digit and dividing the product by the last digit in a queue, pointed by p and q. Products are compared with the maximum and in case they are larger, the position of the match and the new value of the product are stored.
At the end, the substring is printed, starting at the stored position, the index is printed and the product.
The program accepts the options -n and -v:
-n number allows to specify a different number (defaults to 13, as euler #8 indicates)
-v produces more output, indicating at each step the string to be tested, and the products involved.
To compile the program, just:
cc -o 8 8.c
and to run it, just execute 8 at the command line.
If you don't want to see at the solution, don't continue reading.
8.c
#include <getopt.h>
#include <stdio.h>
#include <string.h>
#define FLAG_VERBOSE (1 << 0)
int flags = 0;
int n = 13;
char N[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
int main(int argc, char **argv)
{
int opt;
while ((opt = getopt(argc, argv, "n:v")) != EOF) {
switch (opt) {
case 'n':
if (sscanf(optarg, "%d", &n) != 1) {
fprintf(stderr,
"invalid number: %s\n",
optarg);
}
break;
case 'v':
flags |= FLAG_VERBOSE;
break;
} /* switch */
} /* while */
if (flags & FLAG_VERBOSE) {
printf( "n = %d;\n"
"N = \"%s\"\n",
n, N);
}
char *p, *res = NULL;
unsigned long long res_prod = 0;
for (p = strtok(N, "0"); p; p = strtok(NULL, "0")) {
if (strlen(p) < n) continue;
char *q = p;
unsigned long long prod = 1LL;
int i;
for (i = 0; i < n; i++) { /* initial product */
prod *= *p++ - '0';
}
for(;;) {
int larger = prod > res_prod;
if (flags & FLAG_VERBOSE)
printf("Trying %.*s ==> %llu%s\n",
n, q, prod,
larger ? " !" : "");
if (larger) {
res = q; res_prod = prod;
}
if (!*p) break;
prod /= *q++ - '0';
prod *= *p++ - '0';
}
}
if (res) {
int pos = res - N;
printf("Largest product at position %d (%s%.*s%s): %llu\n",
pos,
pos ? "..." : "", n, res,
pos < sizeof N - 1 - n ? "..." : "",
res_prod);
} else {
printf("No solution found\n");
}
}
You can solve this with a sliding window approach. First grow the window to size 13 and reset the window every time you hit a '0'.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(){
const char a[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
uint64_t prod = 1;
uint64_t m = 0;
size_t count = 0;
for (size_t i = 0; i < sizeof(a) - 1; ++i) {
prod *= a[i] - '0';
if (prod == 0) {
prod = 1;
count = 0;
} else {
if (count++ >= 13) {
prod /= a[i - 13] - '0';
}
if ((count >= 13) && (prod > m)) m = prod;
}
}
printf("max = %"PRIu64"\n", m);
}

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.

I need to add string characters in C. A + B must = C. Literally

I am writing a program that is due tonight at midnight, and I am utterly stuck. The program is written in C, and takes input from the user in the form SOS where S = a string of characters, O = an operator (I.E. '+', '-', '*', '/'). The example input and output in the book is the following:
Input> abc+aab
Output: abc + aab => bce
And that's literally, not variable. Like, a + a must = b.
What is the code to do this operation? I will post the code I have so far, however all it does is take the input and divide it between each part.
#include <stdio.h>
#include <string.h>
int main() {
system("clear");
char in[20], s1[10], s2[10], o[2], ans[15];
while(1) {
printf("\nInput> ");
scanf("%s", in);
if (in[0] == 'q' && in[1] == 'u' && in[2] == 'i' && in[3] == 't') {
system("clear");
return 0;
}
int i, hold, breakNum;
for (i = 0; i < 20; i++) {
if (in[i] == '+' || in[i] == '-' || in[i] == '/' || in[i] == '*') {
hold = i;
}
if (in[i] == '\0') {
breakNum = i;
}
}
int j;
for (j = 0; j < hold; j++) {
s1[j] = in[j];
}
s1[hold] = '\0';
o[0] = in[hold];
o[1] = '\0';
int k;
int l = 0;
for (k = (hold + 1); k < breakNum; k++) {
s2[l] = in[k];
l++;
}
s2[breakNum] = '\0';
printf("%s %s %s =>\n", s1, o, s2);
}
}
Since this is homework, let's focus on how to solve this, rather than providing a bunch of code which I suspect your instructor would frown upon.
First, don't do everything from within the main() function. Break it up into smaller functions each of which do part of the task.
Second, break the task into its component pieces and write out the pseudocode:
while ( 1 )
{
// read input "abc + def"
// convert input into tokens "abc", "+", "def"
// evaluate tokens 1 and 3 as operands ("abc" -> 123, "def" -> 456)
// perform the operation indicated by token 2
// format the result as a series of characters (579 -> "egi")
}
Finally, write each of the functions. Of course, if you stumble upon roadblocks along the way, be sure to come back to ask your specific questions.
Based on your examples, it appears “a” acts like 1, “b” acts like 2, and so on. Given this, you can perform the arithmetic on individual characters like this:
// Map character from first string to an integer.
int c1 = s1[j] - 'a' + 1;
// Map character from second string to an integer.
int c2 = s2[j] - 'a' + 1;
// Perform operation.
int result = c1 + c2;
// Map result to a character.
char c = result - 1 + 'a';
There are some things you have to add to this:
You have to put this in a loop, to do it for each character in the strings.
You have to vary the operation according to the operator specified in the input.
You have to do something with each result, likely printing it.
You have to do something about results that extended beyond the alphabet, like “y+y”, “a-b”, or “a/b”.
If we assume, from your example answer, that a is going to be the representation of 1, then you can find the representation values of all the other values and subtract the value representation of a from it.
for (i = 0; i < str_len; i++) {
int s1Int = (int)s1[i];
int s2Int = (int)s1[i];
int addAmount = 1 + abs((int)'a' - s2Int);
output[i] = (char)(s1Int + addAmount)
}
Steps
1) For the length of the s1 or s2
2) Retrieve the decimal value of the first char
3) Retrieve the decimal value of the second char
4) Find the difference between the letter a (97) and the second char + 1 <-- assuming a is the representation of 1
5) Add the difference to the s1 char and convert the decimal representation back to a character.
Example 1:
if S1 char is a, S2 char is b:
s1Int = 97
s2Int = 98
addAmount = abs((int)'a' - s2Int)) = 1 + abs(97 - 98) = 2
output = s1Int + addAmount = 97 + 2 = 99 = c
Example 2:
if S1 char is c, S2 char is a:
s1Int = 99
s2Int = 97
addAmount = abs((int)'a' - s2Int)) = 1 + abs(97 - 97) = 1
output = s1Int + addAmount = 99 + 1 = 100 = d

Data types conversion (unsigned long long to char)

Can anyone tell me what is wrong with the following code?
__inline__
char* ut_byte_to_long (ulint nb) {
char* a = malloc(sizeof(nb));
int i = 0;
for (i=0;i<sizeof(nb);i++) {
a[i] = (nb>>(i*8)) & 0xFF;
}
return a;
}
This string is then concatenated as part of a larger one using strcat. The string prints fine but for the integers which are represented as character symbols. I'm using %s and fprintf to check the result.
Thanks a lot.
EDIT
I took one of the comments below (I was adding the terminating \0 separately, before calling fprintf, but after strcat. Modifying my initial function...
__inline__
char* ut_byte_to_long (ulint nb) {
char* a = malloc(sizeof(nb) + 1);
int i = 0;
for (i=0;i<sizeof(nb);i++) {
a[i] = (nb>>(i*8)) & 0xFF;
}
a[nb] = '\0' ;
return a;
}
This sample code still isn't printing out a number...
char* tmp;
tmp = ut_byte_to_long(start->id);
fprintf(stderr, "Value of node is %s \n ", tmp);
strcat is expecting a null byte terminating the string.
Change your malloc size to sizeof(nb) + 1 and append '\0' to the end.
You have two problems.
The first is that the character array a contains numbers, such as 2, instead of ASCII codes representing those numbers, such as '2' (=50 on ASCII, might be different in other systems). Try modifying your code to
a[i] = (nb>>(i*8)) & 0xFF + '0';
The second problem is that the result of the above computation can be anything between 0 and 255, or in other words, a number which requires more than one digit to print.
If you want to print hexadecimal numbers (0-9, A-F), two digits per such computation will be enough, and you can write something like
a[2*i + 0] = int2hex( (nb>>(i*8)) & 0x0F ); //right hexa digit
a[2*i + 1] = int2hex( (nb>>(i*8+4)) & 0x0F ); //left hexa digit
where
char int2hex(int n) {
if (n <= 9 && n >= 0)
return n + '0';
else
return (n-10) + 'A';
}
if you dont want to use sprintf(target_string,"%lu",source_int) or the non standard itoa(), here is a version of the function that transform a long to a string :
__inline__
char* ut_byte_to_long (ulint nb) {
char* a = (char*) malloc(22*sizeof(char));
int i=21;
int j;
do
{
i--;
a[i] = nb % 10 + '0';
nb = nb/10;
}while (nb > 0);
// the number is stored from a[i] to a[21]
//shifting the string to a[0] : a[21-i]
for(j = 0 ; j < 21 && i < 21 ; j++ , i++)
{
a[j] = a[i];
}
a[j] = '\0';
return a;
}
I assumed that an unsigned long contain less than 21 digits. (biggest number is 18,446,744,073,709,551,615 which equals 2^64 − 1 : 20 digits)

Resources