How many 4digit numbers with hexadecimal characters can be generated without repetition? - combinations

for example we can have 1234, 1342, 1413,.... But not like 1223. And also 2 4digit numbers should not have all the exact same elements (for example : like 1234 and 3214)

Now it is a programming problem:
#include <stdio.h>
static int hasdups ( char * x ) {
return ((x[0] == x[1]) || (x[0] == x[2]) || (x[0] == x[3]) ||
(x[1] == x[2]) || (x[1] == x[3]) || (x[2] == x[3]));
}
int main ( void ) {
int bad[65536] = { 0 };
char hex[5];
int i;
int n = 0;
for (i = 0; i < 65536; ++i) {
if (bad[i]) continue;
sprintf(hex, "%04x", i);
if (hasdups(hex)) {
bad[i] = 1;
} else {
/* we could write code to enumerate the 24 permutations
of this number: abcd abdc acbd acdb ... dcba
and mark the other 23 off in bad OR we can just... */
}
}
for (i = 0; i < 65536; ++i) n += (bad[i] == 0);
printf("%d combinations meet the criteria\n", n/24); /* ... divide */
return 0;
}

Related

Print a matrix of alternating X's and O's given column and row constraints?

I'm trying to write an algorithm that prints a matrix of X's and O's, given the following params:
int numRows
int numCols
int charsPerCol
int charsPerRow
e.g. calling
printXOMatrix(int charsPerCol, int charsPerRow, int numCols, int numRows);
with the parameters
printXOMatrix(3,2,15,8);
will result in the following being printed to stdout:
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
Here's my code so far, it seems to print correctly if the number of columns / the number of chars per column is different, but fails for example in the case of:
printXOMatrix(2,2,8,8);
the following is printed to stdout:
XXOOXXOO
OOXXOOXX
OOXXOOXX
XXOOXXOO
XXOOXXOO
OOXXOOXX
OOXXOOXX
XXOOXXOO
How do I handle this edge case/clean up my code? Here's what I have so far:
#include <stdio.h>
void getXAndOGrid(int charsPerCol, int charsPerRow, int numCols, int numRows) {
char c = 'X';
for (int i=1; i<=(numCols*numRows); i++) {
// if current index is divisible by the columns (new row)
if (i % numCols == 0) {
// print character, then newline
printf("%c\n", c);
// if current index is divisible by number of columns times num of chars in column
if (i % (numCols * charsPerRow) == 0) {
if (c == 'O') {
c = 'X';
} else {
c = 'O';
}
}
// else if current index is divisible by num in row before it alternates
// and is not divisible by number of columns
} else if (i % charsPerCol == 0) {
printf("%c", c);
if (c == 'O') {
c = 'X';
} else {
c = 'O';
}
} else {
printf("%c", c);
}
}
}
int main() {
getXAndOGrid(3,2,15,8);
return 0;
}
Well, after figuring out the code had an inconsistancy as selbie said, it seems the problem is when you reach the end of the line you don't reset c back to what it was at the start of the line!
But the question should be: why are you writing so much code? The following does exactly the same (well, apart from handling the edge case correctly!):-
void PrintMatrix (int charsPerCol, int charsPerRow, int numCols, int numRows)
{
for (int y = 0 ; y < numRows ; ++y)
{
for (int x = 0 ; x < numCols ; ++x)
{
printf ((((x / charsPerCol) & 1) ^ ((y / charsPerRow) & 1)) != 0 ? "o" : "x");
}
printf ("\n");
}
}
The problem is that you missed one case. You handled the case that the table switch up, with the condition: if (i % (numCols * charsPerRow) == 0), but you haven't handled the case when it doesn't . So I add another condition:
if (i % (numCols * charsPerRow) == 0)
{
if ((numCols / charsPerCol)%2 == 1)
{
if (c == 'O')
{
c = 'X';
}
else
{
c = 'O';
}
}
}
else
{
if ((numCols / charsPerCol)%2 == 0)
{
if (c == 'O')
{
c = 'X';
}
else
{
c = 'O';
}
}
}
So, if the (numCols / charsPerCol) is odd, for instance XXOOXXOOXX, no switch from X <-> O needed, otherwise yes (for instance XXOOXXOO, now c need to be switched from O -> X).
The opposite holds for when the initial condition i % (numCols * charsPerRow) == 0 is reached.
Full code:
#include <iostream>
using namespace std;
void getXAndOGrid(int charsPerCol, int charsPerRow, int numCols, int numRows) {
char c = 'X';
for (int i=1; i<=(numCols*numRows); i++) {
// if current index is divisible by the columns (new row)
if (i % numCols == 0) {
// print character, then newline
printf("%c\n", c);
// if current index is divisible by number of columns times num of chars in column
if (i % (numCols * charsPerRow) == 0) {
if ((numCols / charsPerCol)%2 == 1)
{
if (c == 'O') {
c = 'X';
} else {
c = 'O';
}
}
}
else
{
//cerr << c << endl;
if ((numCols / charsPerCol)%2 == 0)
{
if (c == 'O') {
c = 'X';
} else {
c = 'O';
}
}
}
// else if current index is divisible by num in row before it alternates
// and is not divisible by number of columns
}
else if (i % charsPerCol == 0) {
printf("%c", c);
if (c == 'O') {
c = 'X';
} else {
c = 'O';
}
}
else {
printf("%c", c);
}
}
}
int main() {
getXAndOGrid(2,2,8,8);
return 0;
}
Output (your case):
XXOOXXOO
XXOOXXOO
OOXXOOXX
OOXXOOXX
XXOOXXOO
XXOOXXOO
OOXXOOXX
OOXXOOXX
Output (with getXAndOGrid(3,3,15,15);):
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
OOOXXXOOOXXXOOO
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
XXXOOOXXXOOOXXX
P.S : IMO, your code has quite a bit of duplicated code, wouldn't it be cleaner if a function is implemented?
void switchC(char &c)
{
if (c == 'O') { c = 'X';} else {c = 'O';}
}
void getXAndOGrid(int charsPerCol, int charsPerRow, int numCols, int numRows) {
char c = 'X';
for (int i=1; i<=(numCols*numRows); i++) {
if (i % numCols == 0) {
printf("%c\n", c);
if (i % (numCols * charsPerRow) == 0) {
if ((numCols / charsPerCol)%2 == 1) {switchC(c);}
}
else {
if ((numCols / charsPerCol)%2 == 0) {switchC(c);}
}
}
else if (i % charsPerCol == 0) { printf("%c", c); switchC(c);}
else { printf("%c", c);}
}
}
P.P.S : #Skizz and #selbie has compacted it even more.
There's a lot of complexity in your code because you are printing character by character, using for-loop index values initialized to 1 instead of 0, and trying to print the entire thing in a single loop.
Here's a cleaner approach. There are two unique lines to print. The one starting with X and the one starting with O. Have one for-loop to build each line type. Then another loop to print each line.
What do you think of this? The code below uses C++, but if you need pure C, replace the new/delete calls with malloc and free as seen in the comments:
void printXOMatrix(int numRows, int numCols, int charsPerCol, int charsPerRow)
{
char* primary = new char[numCols + 1]; // malloc(sizeof(char)*(numcols+1))
char* opposite = new char[numCols + 1]; // malloc(sizeof(char)*(numcols+1))
for (int col = 0; col < numCols; col++)
{
char ch = (col % (charsPerCol * 2) < charsPerCol) ? 'X' : 'O';
primary[col] = ch;
opposite[col] = (ch == 'X') ? 'O' : 'X';
}
primary[numCols] = '\0';
opposite[numCols] = '\0';
for (int row = 0; row < numRows; row++)
{
char* line = (row % (charsPerRow * 2) < charsPerRow) ? primary : opposite;
std::cout << line << std::endl; // printf("%s\n", line);
}
delete[] primary; // free(primary)
delete[] opposite; // free(opposite)
}

c++ Decimal to binary, then use operation, then back to decimal

I have an array with x numbers: sets[ ](long numbers) and a char array operations[ ] with x-1 numbers. For each number from sets[ ], its binary form(in 64bits) would be the same as a set of numbers( these numbers being from 0 to 63 ), 1's and 0's representing whether it is inside a subset or not ( 1 2 4 would be 1 1 0 1, since 3 is missing)
ex: decimal 5 --->000...00101 , meaning that this subset will only have those 2 last numbers inside it(#63 and #61)
now,using the chars i get in operations[], i should work with them and the binaries of these numbers as if they were operations on subsets(i hope subset is the right word), these operations being :
U = reunion ---> 101 U 010 = 111
A = intersection ---> 101 A 001 = 001
\ = A - B ---> 1110 - 0011 = 1100
/ = B-A ---> like the previous one
so basically I'd have to read numbers, make them binary, use them as if they were sets and use operations accordingly, then return the result of all these operations on them.
my code :
include <iostream>
using namespace std;
void makeBinaryVector(int vec[64], long xx)
{
// put xx in binary form in array "vec[]"
int k = 63;
long x = xx;
if(xx == 0)
for(int i=0;i<64;i++)
vec[i] = 0;
while(x != 0)
{
vec[k] = x % 2;
x = x / 2;
k--;
}
}
void OperationInA(int A[64], char op, int B[64])
{
int i;
if(op == 'U') //reunion
for(i=0;i<64;i++)
if(B[i] == 1)
A[i] = 1;
if(op == 'A') //intersection
for(i=0;i<64;i++)
{
if((B[i] == 1) && (A[i] == 1))
A[i] = 1;
else
A[i] = 0;
}
if(op == '\\') //A-B
for(i=0;i<64;i++)
{
if( (A[i] == 0 && B[i] == 0) || (A[i] == 0 && B[i] == 1) )
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 1))
A[i] = 0;
else
if((A[i] == 1) && (B[i] == 0))
A[i] = 1;
}
if(op == '/') //B-A
for(i=0;i<64;i++)
{
if(B[i] == 0)
A[i] = 0;
else
if((B[i] == 1) && (A[i] == 0))
A[i] = 1;
else
if((B[i] == 1) && (A[i] == 1))
A[i] = 0;
}
}
unsigned long setOperations(long sets[], char operations[], unsigned int x)
{
unsigned int i = 1; //not 0, since i'll be reading the 1st number separately
unsigned int j = 0;
unsigned int n = x;
int t;
long a = sets[0];
int A[64];
for(t=0;t<64;t++)
A[t] = 0;
makeBinaryVector(A, a); //hold in A the first number, binary, and the results of operations
long b;
int B[64];
for(t=0;t<64;t++) //Hold the next number in B[], in binary form
B[t] = 0;
char op;
while(i < x && j < (x-1) )
{
b = sets[i];
makeBinaryVector(B, b);
op = operations[j];
OperationInA(A, op, B);
i++; j++;
}
//make array A a decimal number
unsigned int base = 1;
long nr = 0;
for(t=63; t>=0; t--)
{
nr = nr + A[t] * base;
base = base * 2;
}
return nr;
}
long sets[100];
char operations[100];
long n,i;
int main()
{
cin>>n;
for(i=0;i<n;i++)
cin>>sets[i];
for(i=0;i<n-1;i++)
cin>>operations[i];
cout<<setOperations(sets,operations,n);
return 0;
}
So everything seems fine, except when im trying this :
sets = {5, 2, 1}
operations = {'U' , '\'}
5 U 2 is 7(111), and 7 \ 1 is 6 (111 - 001 = 110 --> 6)
the result should be 6, however when i Input them like that the result is 4 (??)
however, if i simply input {7,1} and { \ } the result is 6,as it should be. but if i input them like i first mentioned {5,2,1} and {U,} then its gonna output 4.
I can't seem to understand or see what im doing wrong...
You don't have to "convert to binary numbers".
There's no such thing as 'binary numbers'. You can just perform the operations on the variables.
For the reunion, you can use the bitwise OR operator '|', and for the intersection, you can use the bitwise AND operator '&'.
Something like this:
if (op == 'A')
result = a & b;
else if (op == 'U')
result = a | b;
else if (op == '\\')
result = a - b;
else if (op == '/')
result = b - a;
Use bitwise operators on integers as shown in #Hugal31's answer.
Note that integer size is usually 32bit, not 64bit. On a 64bit system you need long long for 64bit integer. Use sizeof operator to check. int is 4 bytes (32bit) and long long is 8 bytes (64bit).
For the purpose of homework etc., your conversion to vector cannot be right. You should test it to see if it outputs the correct result. Otherwise use this:
void makebinary(int vec[32], int x)
{
int bitmask = 1;
for (int i = 31; i >= 0; i--)
{
vec[i] = (x & bitmask) ? 1 : 0;
bitmask <<= 1;
}
}
Note the use of shift operators. To AND the numbers you can do something like the following:
int vx[32];
int vy[32];
makebinary(vx, x);
makebinary(vy, y);
int result = 0;
int j = 1;
for (int i = 31; i >= 0; i--)
{
int n = (vx[i] & vy[i]) ? 1 : 0;
result += n * j;
j <<= 1;
}
This is of course pointless because you can just say int result = X & Y;

Algorithm to calculate sum of LUCKY FACTOR in given range

Problem Statement :-
A number is given, N, which is given in binary notation, and it
contains atmost 1000000 bits. You have to calculate the sum of LUCKY
FACTOR in range from 1 to N (decimal notation).
Here, LUCKY FACTOR means, (after converting into binary representation) if
rightmost or leftmost 1's neighbour is either 0 or nothing(for
boundary bit).
EDITED :-
Means if rightmost one's left neighbour is 0, means it count as a
LUCKY FACTOR, simlarly in the left side also
Example,
5 == 101, LUCKY FACTOR = 2.
7 == 111, LUCKY FACTOR = 0.
13 == 1101, LUCKY FACTOR = 1.
16 == 1110, LUCKY FACTOR = 0.
0 == 0, LUCKY FACTOR = 0.
Answer must be in binary form
I am totally stuck, give me a hint.
My code
#include<stdio.h>
#include<string>
#include<string.h>
#include<vector>
//#include<iostream>
using namespace std;
vector<string> pp(10000001);
string add(string a, string b) {
if(b == "") return a;
string answer = "";
int c = 0;
int szeA = a.size() - 1;
int szeB = b.size() - 1;
while(szeA >= 0 || szeB >= 0) {
answer = (char)( ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) ^ ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) ^ (c) ) + 48 ) + answer;
c = ( ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) ) | ( ( (szeA >= 0) ? (a[szeA] - 48) : 0 ) & (c) ) | ( ( (szeB >= 0) ? (b[szeB] - 48) : 0 ) & (c) ) );
szeA--;
szeB--;
}
if(c) answer = '1' + answer;
return answer;
}
string subtract(string a, string b) {
int sze = a.size() - b.size();
while(sze--) b = '0' + b;
sze = a.size();
for(int i = 0; i < sze; i++) {
if(b[i] == '1') b[i] = '0';
else b[i] = '1';
}
if(b[sze-1] == '0') {
b[sze-1] = '1';
}
else {
int i = sze-1;
while(i >= 0 && b[i] == '1') {
b[i] = '0';
i--;
}
if(i >= 0) b[i] = '1';
else b = '1' + b;
}
b = add(a, b);
b.erase(b.begin() + 0);
//b[0] = '0';
while(b[0] == '0') b.erase(b.begin() + 0);
return b;
}
string power(int index) {
if(index < 0) return "";
string answer = "";
while(index--) {
answer = '0' + answer;
}
answer = '1' + answer;
return answer;
}
string convert(long long int val) {
int divisionStore=0;
int modStore=0;
string mainVector = "";
do {
modStore=val%2;
val=val/2;
mainVector = (char)(modStore+48) + mainVector;
}while(val!=0);
return mainVector;
}
string increment(string s) {
int sze = s.size()-1;
if(s[sze] == '0') {
s[sze] = '1';
return s;
}
while(sze >= 0 && s[sze] == '1') {
s[sze] = '0';
sze--;
}
if(sze >= 0) s[sze] = '1';
else s = '1' + s;
return s;
}
main() {
int T;
char s[1000001];
string answer;
scanf("%d", &T);
for(int t = 1; t <= T; t++) {
int num;
answer = "1";
int bitComeEver = 0;
int lastBit = 0;
scanf("%s", s);
int sze = strlen(s);
// I used below block because to avoid TLE.
if(sze > 3300) {
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", '1');
printf("\n");
//continue;
}
else {
if(pp[sze-1] != "") answer = pp[sze-1];
else {
pp[sze-1] = power(sze-1);
answer = pp[sze-1];
}
answer = subtract(answer, convert(sze-1));
////////////////////////////
//cout << answer << endl;
for(int i = 1; i < sze; i++) {
if(s[i] == '1') {
if(s[1] == '0') {
num = sze-i-1;
if(num > 0) {
if( pp[num-1] == "") {
pp[num-1] = power(num-1);
}
if(pp[num+1] == "") {
pp[num+1] = power(num+1);
}
answer = add(answer, subtract(pp[num+1], pp[num-1]));
if(lastBit) answer = add(answer, "1");
//else answer = increment(answer);
//cout << "\t\t" << answer << endl;
}
else{
int inc;
if(lastBit) inc = 2; //answer = add(answer, "10");
else inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 2;
else inc += 1;
if(inc == 2) answer = add(answer, "10");
else if(inc == 3) answer = add(answer, "11");
else answer = add(answer, "100");
}
}
else {
if(num > 0) {
if(pp[num-1] != "") pp[num-1] = power(num-1);
answer = add(answer, pp[num-1]);
}
else {
int inc = 0;
if(lastBit) inc = 1; //answer = increment(answer);
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
if(lastBit) inc += 1;
answer = add(answer, convert(inc));
}
}
if(s[i-1] == '0') lastBit = 1;
else lastBit = 0;
}
}
if(s[sze-1] == '0') {
if(lastBit) {
if(s[1] == '0') {
answer = add(answer, "10");
}
else answer = increment(answer);
}
else if(s[1] == '0'){
answer = increment(answer);
}
}
printf( "Case #%d\n", t);
for(int i = 0; i < sze; i++) printf("%c", answer[i]);
printf("\n");
}
}
return 0;
}
If a number has k bits, then calculate the number of such numbers having a LUCKY FACTOR of 2:
10.............01
Hence in this the 1st two and last two digits are fixed, the remaining k-4 digits can have any value. The number of such numbers = 2^(k-4).
So you can easily calculate the sum of lucky factors of such numbers = lucky_factor x 2^(k-4)
(ofcourse this is assuming k >= 4)
What's more, you do not need to calculate this number since it will be of the form 10000000.
If the number n is 11010010. Then 8 bit numbers less than n shall be of form:
10........ or 1100...... or 1101000_. If you see a pattern, then we have divided the calculation in terms of the number of 1s in the number n
.
I leave the rest for you.

How should I approach a credit card number validation algorithm?

I'm writing a program to validate credit card numbers and I have to use Luhn's Algorithm. Let me say beforehand, that I have just started to learn to program (we covered loops like last week), so there a lot of things I am unfamiliar with. I am having trouble with one of my functions that checks the arithmetic. Basically, it has to double every second digit from right to left and add everything together. But if you double a number, like 5, and you get 10, then you will have to add 1+0=1 to the total sum instead of 10. That's the part I'm stuck on. How can I put that in a program?
Sample code so far:
int
doubleEvenSum(string creditCardNumber) {
int evenSum;
int countPosition;
int doublePosition;
int length;
length = creditCardNumber.length ();
countPosition = creditCardNumber.at(length - 2);
evenSum = 0;
while(countPosition>0) {
if ((2 * countPosition) < 10) {
doublePosition = 2 * countPosition;
}
else if ((2 * countPosition) > 9) {
???
}
evenSum = evenSum + doublePosition;
}
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/*
return the Luhn (MOD10) checksum for a sequence of digits.
-1 is returned on error (a non-digit was in the sequence
*/
int mod10( char const* s)
{
int len = strlen(s);
int sum = 0;
int dbl = 0;
while (len) {
char digit;
int val;
--len;
digit = s[len];
if (!isdigit( (unsigned char) digit)) return -1; // non digit in the sequence
val = digit - '0'; // convert character to numeric value
if (dbl) {
// double the value
val *= 2;
// if the result is double-digits, add the digits together
if (val > 9) {
val = val - 10;
val = val + 1;
}
}
dbl = !dbl; // only double value every other time
sum += val;
}
return sum % 10;
}
Here is a different algorithm. I cut/pasted from a C# example; the second link discusses a number of optimization for Luhn.
Please study this example, and please run it through the debugger to study how the code behaves as it's executing. Understanding how code actually runs (as opposed to how you think it will run when you write it) is an essential skill. IMHO....
/*
* Validate credit card with Luhn Algorithm
*
* REFERENCES:
* - http://jlcoady.net/c-sharp/credit-card-validation-in-c-sharp
* - http://orb-of-knowledge.blogspot.com/2009/08/extremely-fast-luhn-function-for-c.html
*/
#include <stdio.h> // printf(), scanf(), etc
#include <string.h> // strlen (), etc
#include <ctype.h> // isdigit(), etc
#if !defined(FALSE)
#define FALSE 0
#define TRUE ~FALSE
#endif
/*
* type definitions (should go in separate header)
*/
enum CardType {
MASTERCARD=1, BANKCARD=2, VISA=3, AMEX=4, DISCOVER=5, DINERS=6, JCB=7
};
/*
* function prototypes (should also go in header)
*/
int luhn (int number[], int len);
bool validate (CardType cardType, char *cardNumber);
/*
* program main
*/
int
main (int argc, char *argv[])
{
char cc_number[80];
int cc_type;
for ( ;; ) {
printf ("Enter a credit card number and type (1, 2, 3, 4, 5. 6 or 7):\n");
printf (" MASTERCARD=1, BANKCARD=2, VISA=3, AMEX=4, DISCOVER=5, DINERS=6, JCB=7\n");
int iret = scanf ("%s %d", cc_number, &cc_type);
if (iret == 2)
break;
else
printf ("Incorrect input: please enter a valid CC# and CC type\n");
}
if (validate ((CardType)cc_type, cc_number))
printf ("Valid\n");
else
printf ("Invalid card type/number\n");
return 0;
}
/*
* validate card#
*/
bool
validate (CardType cardType, char *cardNumber)
{
// 16 or fewer digits?
int len = strlen(cardNumber);
if (strlen (cardNumber) > 16)
return false;
// number to validate
int number[16];
for(int i = 0; i < (int)strlen (cardNumber); i++) {
if(!isdigit(cardNumber[i]))
return FALSE;
number[i] = cardNumber[i] - '0';
}
// Validate based on card type, first if tests length, second tests prefix
switch(cardType) {
case MASTERCARD:
if(len != 16)
return FALSE;
if(number[0] != 5 || number[1] == 0 || number[1] > 5)
return FALSE;
break;
case BANKCARD:
if(len != 16)
return FALSE;
if(number[0] != 5 || number[1] != 6 || number[2] > 1)
return FALSE;
break;
case VISA:
if(len != 16 && len != 13)
return FALSE;
if(number[0] != 4)
return FALSE;
break;
case AMEX:
if(len != 15)
return FALSE;
if(number[0] != 3 || (number[1] != 4 && number[1] != 7))
return FALSE;
break;
case DISCOVER:
if(len != 16)
return FALSE;
if(number[0] != 6 || number[1] != 0 || number[2] != 1 || number[3] != 1)
return FALSE;
break;
case DINERS:
if(len != 14)
return FALSE;
if(number[0] != 3 || (number[1] != 0 && number[1] != 6 && number[1] != 8) || number[1] == 0 && number[2] > 5)
return FALSE;
break;
case JCB:
if(len != 16 && len != 15)
return FALSE;
if(number[0] != 3 || number[1] != 5)
return FALSE;
break;
default:
return FALSE;
}
int sum = luhn (number, len);
return (sum % 10 == 0);
}
// Use Luhn Algorithm to validate
int luhn (int number[], int len)
{
int sum = 0;
for(int i = len - 1; i >= 0; i--)
{
if(i % 2 == len % 2)
{
int n = number[i] * 2;
sum += (n / 10) + (n % 10);
}
else
sum += number[i];
}
return sum;
}
int luhnCardValidator(char cardNumbers[]) {
int sum = 0, nxtDigit, i;
for (i = 0; cardNumbers[i] != NULL_TERMINATOR ; i++) {
nxtDigit = cardNumbers[i] - START_OF_ASCII_NUMERIC;
if (i % 2 == 0)
nxtDigit = (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : nxtDigit * 2;
sum += nxtDigit;
}
return (sum % 10);
}
This:
... (nxtDigit > 4) ? (nxtDigit * 2 - 10) + 1 : ...
is the clever bit. If the digit is greater than 4, then the doubling will be 10 or more. In that case, you take the doubled number and subtract 10 which will give you the ones-digit then you add 1 (the tens-digit).
Just subtract 9 from the double of the number then you will equivalent of the sum of the digits.
For ex.
7= 7*2 = 14 = 1+4 = 5 OR 14-9 = 5
This is more efficient than writing code for adding both digits.

Compute Absolute values of N integer combinations Combinations

For a N number (a..N) I am finding set of all combinations in the following way:
void create_print_combinations(int *t, int x, int n) {
if(x == 0) {
char p [2 * r + 2];
memset (p, 0, 2 * r +2);
for (int j=c;j>0;j--)
if(j == c)
sprintf(p, "%d", t[j]);
else
sprintf(p, "%s,%d", p,t[j]);
print_combi(p);
} else {
for (int i= n; i < r; i++) {
t[x] = a[i];
create_print_combinations(t, x-1, i+1);
}
}
}
So a call to function like:
int main() {
unsigned long int start=0, end=0;
printf ("\nEnter the a positive integer N:");
scanf("%d", &r);
start=time(NULL);
a = new int[r];
for (int i = 0;i<r;i++)
a[i]=i+1;
for(int j=1;j<=r;j++) {
a1 = new int[j];
c=j;
create_print_combinations(a1, c, 0);
delete[] a1;
}
end=time(NULL);
printf("Total time taken = %llu\n" , end - start);
return 0;
}
Gives me combinations like for N=4:
Enter the a positive integer N:4
Combo : [1]
Combo : [2]
Combo : [3]
Combo : [4]
Combo : [1,2]
Combo : [1,3]
Combo : [1,4]
Combo : [2,3]
Combo : [2,4]
Combo : [3,4]
Combo : [1,2,3]
Combo : [1,2,4]
Combo : [1,3,4]
Combo : [2,3,4]
Combo : [1,2,3,4]
Now my tasks is to fond the absolute values of all combinations like:
For Combo [1,2,3,4] it should be:
1+2+3+4 = abs(1+2+3+4)
1+2+3-4 = abs(1+2+3-4)
1+2-3-4 = ..
1-2-3+4 = ...
Ans so on
I am trying the below logic:
while(pos > 0)
{
for(int a=0; a < i; a++)
{
if(a==0)
sprintf(p,"%d", t[a]);
else if(a == pos)
sprintf(p,"%s%c%d",p, minus, t[a]);
else
sprintf(p,"%s%c%d",p, plus, t[a]);
}
print(p);
memset (p , 0, 2 * r +2);
pos --;
}
But I beleiev I am doing something wrong as all sets are not getting printed. I am unable to frame the logic though I feel I am near to completion. Below is my whole program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
int *a;
int *a1;
int r;
int c;
unsigned long int no =1;
int stoi(char *var)
{
int n1 = 0;
int n2 = 0;
int n3 = 0;
char sign=0;
while(*var)
{
if(isspace(*var))
{
var++;
continue;
}
while(*var >= '0' && *var <= '9')
{
n1=(n1*10) + (*var - '0');
var++;
continue;
}
if(sign == '+')
{
n2=n2+n1;
n1=0;
}
else if(sign == '-')
{
n2=n2 - n1;
n1=0;
}
if(*var == '+' || *var == '-')
{
if(sign == 0)
{
n2=n1;
n1=0;
}
sign = *var;
}
var++;
}
if(sign == 0)
return abs(n1);
return abs(n2);
}
void print(char* var)
{
printf("[Combo %llu.] %s = %d\n" , no++, var, stoi(var));
}
void print_combi(char * a)
{
int t[c];
char *x = NULL;
char *y = a;
int i=0;
while((x=strchr(y, ',')) != NULL)
{
*x = '\0';
t[i++]=atoi(y);
y=x+1;
}
t[i++]=atoi(y);
int count =0;
int loop = 0;
char p [2 * r + 2];
memset (p , 0, 2 * r +2);
char plus = '+';
char minus = '-';
for(int k=0;k<2;k++)
{
if(k==1)
{
plus = '-';
minus = '+';
}
if(i>1)
{
for(int a=0; a < i; a++)
{
if(a==0)
sprintf(p,"%d", t[a]);
else
sprintf(p,"%s%c%d",p, plus, t[a]);
}
}
else if(i==1)
{
sprintf(p,"%d", t[i-1]);
print(p);
break;
}
print(p);
memset (p , 0, 2 * r +2);
if(i==2)
continue;
if(i==3 && k ==1)
break;
int pos = i-1;
while(pos > 0)
{
for(int a=0; a < i; a++)
{
if(a==0)
sprintf(p,"%d", t[a]);
else if(a == pos)
sprintf(p,"%s%c%d",p, minus, t[a]);
else
sprintf(p,"%s%c%d",p, plus, t[a]);
}
print(p);
memset (p , 0, 2 * r +2);
pos --;
}
}
}
void create_print_combinations(int *t, int x, int n)
{
if(x == 0)
{
char p [2 * r + 2];
memset (p, 0, 2 * r +2);
for (int j=c;j>0;j--)
if(j == c)
sprintf(p, "%d", t[j]);
else
sprintf(p, "%s,%d", p,t[j]);
print_combi(p);
}
else
for (int i= n; i < r; i++)
{
t[x] = a[i];
create_print_combinations(t, x-1, i+1);
}
}
int main()
{
unsigned long int start=0, end=0;
printf ("\nEnter the a positive integer N:");
scanf("%d", &r);
start=time(NULL);
a = new int[r];
for (int i = 0;i<r;i++)
a[i]=i+1;
for(int j=1;j<=r;j++)
{
a1 = new int[j];
c=j;
create_print_combinations(a1, c, 0);
delete[] a1;
}
end=time(NULL);
printf("Total time taken = %llu\n" , end - start);
return 0;
}
As per the program logic I am computing the combinations as strings and the generating the absolute values of the expression.
There is a simpler way to what you are doing. You want to add up a vector of N integers:
[ 1*k1, 2*k2, 3*k3 ... N*kN ]
where kx = -1, 0, +1.
There are 3^N combinations of kx for x=1..N.
Some code for #SteveC's solution:
#include <iostream>
#include <sstream>
using namespace std;
void print_sum(int N, int sum_so_far, string as_a_string) {
if(N) {
ostringstream oss; oss << N;
print_sum(N-1, sum_so_far+N, as_a_string + "+" + oss.str() + " ");
print_sum(N-1, sum_so_far-N, as_a_string + "-" + oss.str() + " ");
print_sum(N-1, sum_so_far, as_a_string);
} else {
if (sum_so_far < 0) sum_so_far *= -1;
cout << as_a_string << "\t= " << sum_so_far << endl; }
}
int main() {
print_sum(4, 0, "");
}
The output begins:
+4 +3 +2 +1 = 10
+4 +3 +2 -1 = 8
+4 +3 +2 = 9
+4 +3 -2 +1 = 6
+4 +3 -2 -1 = 4
+4 +3 -2 = 5
+4 +3 +1 = 8
+4 +3 -1 = 6
# .. and so on
What you are trying to do is very similar to enumerating all combinations from "N choose 1" to "N choose N". I would suggest you search in google under the terms "Enumerate Combinations"
Here is one of the link I have found:
http://www.codeproject.com/KB/recipes/CombC.aspx
Here is a logic on how to do it. Print all the binary digits of size n-1 where n is the size (number of elements) of the respective combo. For example to do what you want to do for the combo [1,2,3,4] create all the binary combinations of 3 (n-1 = 3, here n = 4 elements). i.e.
when n = 3, the possible combinations are:
000
001
010
011
100
101
110
111
Now run your combo in a for loop and inside it whenever you find a 0 do addition and whenever you find 1 do a subtraction. For example 000 would mean 1+2+3+4 and 101 would mean 1-2+3-4.