Finding sum of all binary expansions of numbers from 1 to n - c++

Recently, I came across a question posted as a challenge at a competitive site. There it was asked to find the sum of all the decimal interpretation of binary representations of numbers from 1 to n. Suppose when n = 4, so, sum will be 1 + 10 + 11 + 100 = 122. Since this number could be very large so answer should be modulo 1000000007.
I came across the following solutions but was not able to optimize it.
#include<iostream>
#include<queue>
using namespace std;
int Mod(string s, int a)
{
int res = 0, i, l = s.size();
for( i = 0 ; i < l ; i++ )
{
res = ( res * 10 + s[i] - '0' ) % a;
}
return res;
}
int main()
{
int t;
cin >> t;
while(t--)
{
long long n;
cin >> n;
int Sum = 0, mod = 1000000007;
queue<string> q;
q.push("1");
while( n > 0 )
{
n--;
string s1 = q.front();
q.pop();
Sum = ( Sum + Mod(s1, mod) ) % mod;
string s2 = s1;
q.push(s1.append("0"));
q.push(s2.append("1"));
}
cout << Sum << endl;
}
return 0;
}
Constraints:
1 <= t <= 10^5, 1 <= n <= 10^18, Allowed Time = 1 sec. Any optimization help would be admirable. Thanks in advance.

After doing some calculative math finally I have come up with the solution. Thanks, to #largest_prime_is_463035818 for providing such hints. Here is my code:
#include<iostream>
#include<cmath>
#define mod 1000000007
using namespace std;
long long power(long long x, long long y)
{
long long res = 1LL;
while(y)
{
if( y & 1LL )
{
res = ( res * x ) % mod;
}
y >>= 1LL;
x = ( x * x ) % mod;
}
return res;
}
int main()
{
long long t;
cin >> t;
while(t--)
{
long long n, i, l, m, s = 0;
cin >> n;
if( n && (!( n & ( n - 1LL ) )) )
{
l = ceil(log2(n)) + 1LL;
}
else
{
l = ceil(log2(n));
}
for( i = 0LL ; i < l ; i++ )
{
if( n & ( 1LL << i ) )
{
m = ( ( ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) ) + 1LL ) + ( ( n % ( 1LL << ( i + 1LL ) ) ) % ( 1LL << i ) ) );
}
else
{
m = ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) );
}
s = ( s + ( ( ( m % mod ) * power(10, i) ) % mod ) ) % mod;
}
cout << s << endl;
}
return 0;
}

Related

How to 'define' a datatype in C++?

I was solving a CodeChef problem which asked to calculate the factorial of input. The range of input is 100. Here's the problem's link.
https://www.codechef.com/problems/FCTRL2
So, there is one method to solve the factorial of 100 by using arrays because I used the 'Insertion sort' method but there's a time limit exceeded error. So
I came up with another method by using unsigned long long int datatype. I defined int unsigned long long int but it's not working. I'll be if you help fix it.
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long;
int main() {
int t,n;
cin>>t;
if(1<=t<=100){
while (t--) {
cin>>n;
if(1<=n<=100){
int fact=1;
for(int i=1;i<=n;i++){
fact*=i;
}
cout<<fact<<endl;
}
}
}
return 0;
}
Factorial of 100 is way too large for 64 bits, it will overflow regardless. The point is that you should implement your own big-number class, or use an existing implementation like the one in Boost.
Factorial of 100 has 158 digits!
100! is way too big for a 64 bit integer. It has 158 digits. You have to implement the BigInteger library. Hopefully, #LightOj Judge creator #Jane Alom Jan has a nice implementation that you can check. I am sharing his implementation, you can modify and test this for this problem.
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
struct Bigint {
// representations and structures
string a; // to store the digits
int sign; // sign = -1 for negative numbers, sign = 1 otherwise
// constructors
Bigint() {} // default constructor
Bigint( string b ) { (*this) = b; } // constructor for string
// some helpful methods
int size() { // returns number of digits
return a.size();
}
Bigint inverseSign() { // changes the sign
sign *= -1;
return (*this);
}
Bigint normalize( int newSign ) { // removes leading 0, fixes sign
for( int i = a.size() - 1; i > 0 && a[i] == '0'; i-- )
a.erase(a.begin() + i);
sign = ( a.size() == 1 && a[0] == '0' ) ? 1 : newSign;
return (*this);
}
// assignment operator
void operator = ( string b ) { // assigns a string to Bigint
a = b[0] == '-' ? b.substr(1) : b;
reverse( a.begin(), a.end() );
this->normalize( b[0] == '-' ? -1 : 1 );
}
// conditional operators
bool operator < ( const Bigint &b ) const { // less than operator
if( sign != b.sign ) return sign < b.sign;
if( a.size() != b.a.size() )
return sign == 1 ? a.size() < b.a.size() : a.size() > b.a.size();
for( int i = a.size() - 1; i >= 0; i-- ) if( a[i] != b.a[i] )
return sign == 1 ? a[i] < b.a[i] : a[i] > b.a[i];
return false;
}
bool operator == ( const Bigint &b ) const { // operator for equality
return a == b.a && sign == b.sign;
}
// mathematical operators
Bigint operator + ( Bigint b ) { // addition operator overloading
if( sign != b.sign ) return (*this) - b.inverseSign();
Bigint c;
for(int i = 0, carry = 0; i<a.size() || i<b.size() || carry; i++ ) {
carry+=(i<a.size() ? a[i]-48 : 0)+(i<b.a.size() ? b.a[i]-48 : 0);
c.a += (carry % 10 + 48);
carry /= 10;
}
return c.normalize(sign);
}
Bigint operator - ( Bigint b ) { // subtraction operator overloading
if( sign != b.sign ) return (*this) + b.inverseSign();
int s = sign; sign = b.sign = 1;
if( (*this) < b ) return ((b - (*this)).inverseSign()).normalize(-s);
Bigint c;
for( int i = 0, borrow = 0; i < a.size(); i++ ) {
borrow = a[i] - borrow - (i < b.size() ? b.a[i] : 48);
c.a += borrow >= 0 ? borrow + 48 : borrow + 58;
borrow = borrow >= 0 ? 0 : 1;
}
return c.normalize(s);
}
Bigint operator * ( Bigint b ) { // multiplication operator overloading
Bigint c("0");
for( int i = 0, k = a[i] - 48; i < a.size(); i++, k = a[i] - 48 ) {
while(k--) c = c + b; // ith digit is k, so, we add k times
b.a.insert(b.a.begin(), '0'); // multiplied by 10
}
return c.normalize(sign * b.sign);
}
Bigint operator / ( Bigint b ) { // division operator overloading
if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 );
Bigint c("0"), d;
for( int j = 0; j < a.size(); j++ ) d.a += "0";
int dSign = sign * b.sign; b.sign = 1;
for( int i = a.size() - 1; i >= 0; i-- ) {
c.a.insert( c.a.begin(), '0');
c = c + a.substr( i, 1 );
while( !( c < b ) ) c = c - b, d.a[i]++;
}
return d.normalize(dSign);
}
Bigint operator % ( Bigint b ) { // modulo operator overloading
if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 );
Bigint c("0");
b.sign = 1;
for( int i = a.size() - 1; i >= 0; i-- ) {
c.a.insert( c.a.begin(), '0');
c = c + a.substr( i, 1 );
while( !( c < b ) ) c = c - b;
}
return c.normalize(sign);
}
// output method
void print() {
if( sign == -1 ) putchar('-');
for( int i = a.size() - 1; i >= 0; i-- ) putchar(a[i]);
}
};
int main() {
Bigint a, b, c; // declared some Bigint variables
/////////////////////////
// taking Bigint input //
/////////////////////////
string input; // string to take input
cin >> input; // take the Big integer as string
a = input; // assign the string to Bigint a
cin >> input; // take the Big integer as string
b = input; // assign the string to Bigint b
//////////////////////////////////
// Using mathematical operators //
//////////////////////////////////
c = a + b; // adding a and b
c.print(); // printing the Bigint
puts(""); // newline
c = a - b; // subtracting b from a
c.print(); // printing the Bigint
puts(""); // newline
c = a * b; // multiplying a and b
c.print(); // printing the Bigint
puts(""); // newline
c = a / b; // dividing a by b
c.print(); // printing the Bigint
puts(""); // newline
c = a % b; // a modulo b
c.print(); // printing the Bigint
puts(""); // newline
/////////////////////////////////
// Using conditional operators //
/////////////////////////////////
if( a == b ) puts("equal"); // checking equality
else puts("not equal");
if( a < b ) puts("a is smaller than b"); // checking less than operator
return 0;
}
As the problem has a source limit of 2000 bytes so adding the hole BigInteger library will cross the source limit.
So only string multiplication can be done here.
A clean approach of multiplication is given below using C++
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
vector<int> arr;
int n;
cin >> n;
arr.push_back(1);
int carry = 0;
for(int i = 2; i <= n; i++){
vector<int> t;
for(int j = arr.size() - 1; j >= 0; j--){
int r = arr[j] * i + carry;
carry = r / 10;
t.push_back(r % 10);
}
while(carry){
t.push_back(carry % 10);
carry /= 10;
}
reverse(t.begin(), t.end());
arr = t;
}
for(auto el : arr){
cout << el;
}
cout << endl;
}
return 0;
}
Input
2
10
100
Output
3628800
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Also adding an easy python implementation
test = int(input())
for i in range(0, test):
n = int(input())
res = 1
for j in range(2, n + 1):
res = res * j
print(res)
Already 3 days old question, but anyway.
The solution is a rather simple task. We can do it like we would do it on a piece of paper. We use a std::vector of digits to hold the number. Because the result will be already too big for an unsigned long long for 22!.
The answer will be exact. Also the code is short and compact.
With such an approach the calculation is simple. I do not even know what to explain further.
Please be careful with the runtime. It will be extremely long for big numbers. If speed is an issue, then use the original BigInt header only lib.
Please see the code:
#include <iostream>
#include <vector>
int main()
{
std::cout << "Calculate n! Enter n (max 10000): ";
if (unsigned int input{}; (std::cin >> input) && (input <= 10000)) {
// Here we store the resulting number as single digits
std::vector<unsigned int> result(3000, 0); // Magic number. Is big enough for 100000!
result.back() = 1; // Start calculation with 1 (from right to left)
// Multiply up to the given input value
for (unsigned int count = 2; count <= input; count++)
{
unsigned int sum{}, remainder{};
unsigned int i = result.size() - 1; // Calculate from right to left
while (i > 0)
{
// Simple multiplication like on a piece of paper
sum = result[i] * count + remainder;
result[i--] = sum % 10;
remainder = sum / 10;
}
}
// Show output. Supporess leading zeroes
bool showZeros{ false };
for (const unsigned int i : result) {
if ((i != 0) || showZeros) {
std::cout << i;
showZeros = true;
}
}
}
else std::cerr << "\nError: Wrong input.";
}
Developed and tested with Microsoft Visual Studio Community 2019, Version 16.8.2.
Additionally compiled and tested with clang11.0 and gcc10.2
Language: C++17

Runtime error in c++ when analysing time [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to check how much time passes with each 3 solutions for a problem, but sometimes I get a runtime error and can't see the passed time for 3rd solution, but sometimes it works. I think the solutions.h file is correct but i put it here anyway.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "solutions.h"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
int* output1= new int[1000];
double duration;
clock_t startTime1 = clock();
solution1(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 1 with 10000 inputs took " << duration << " milliseconds." << endl;
startTime1 = clock();
solution2(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 2 with 10000 inputs took " << duration<< " milliseconds." << endl;
startTime1 = clock();
solution3(input1,10000,1000,output1);
duration = 1000 * double( clock() - startTime1 ) / CLOCKS_PER_SEC;
cout << "Solution 3 with 10000 inputs took " << duration << " milliseconds." << endl<<endl<<endl;
return 0;
}
And the solutions.h is
#ifndef SOLUTIONS_H_INCLUDED
#define SOLUTIONS_H_INCLUDED
#include <cmath>
void solution1( int input[], const int n, const int k, int output[] );
void solution2( int input[], const int n, const int k, int output[] );
void solution3( int input[], const int n, const int k, int output[] );
void swap( int &n1, int &n2 ) {
int temp = n1;
n1 = n2;
n2 = temp;
}
void solution1( int input[], const int n, const int k, int output[] ) {
int maxIndex, maxValue;
for( int i = 0; i < k; i++ ) {
maxIndex = i;
maxValue = input[i];
for( int j = i+1; j < n; j++ ) {
if( input[j] >= maxValue ) {
maxIndex = j;
maxValue = input[ j ];
}
}
swap( input[i], input[maxIndex] );
output[i] = input[i];
}
}
int partition( int input[], int p, int r ) {
int x = input[ r ], i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[i+1], input[r] );
return i + 1;
}
void quickSort( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition( input, p, r );
quickSort( input, p, q - 1 );
quickSort( input, q + 1, r );
}
}
void solution2( int input[], const int n, const int k, int output[] ) {
quickSort( input, 0, n - 1 );
for( int i = 0; i < k; i++ ) {
output[i] = input[i];
}
}
int partition2( int input[], int a, int p, int r ) {
int x = a, i = p - 1;
for( int j = p; j < r; j++ ) {
if( input[ j ] == x ) {
swap( input[ j ], input[ r ] );
}
if( input[ j ] >= x ) {
i = i + 1;
swap( input[i], input[j] );
}
}
swap( input[ i + 1 ], input[ r ] );
return i + 1;
}
void quickSort2( int input[], int p, int r ) {
int q;
if( p < r ) {
q = partition2( input, input[ r ], p, r );
quickSort2( input, p, q - 1 );
quickSort2( input, q + 1, r );
}
}
int findMin( int n1, int n2 ) {
if( n1 <= n2 )
return n1;
else
return n2;
}
int select( int input[], int n, int k, int start, int end, int flag ) {
if( n <= 5 ) {
quickSort2( input, start, end );
return input[ start + k - 1 ];
}
int i = start, numGroups = (int) ceil( ( double ) n / 5 ), numElements, j = 0;
int *medians = new int[numGroups];
while( i <= end ) {
numElements = findMin( 5, end - i + 1 );
medians[( i - start ) / 5] = select( input, numElements, (int) ceil( ( double ) numElements / 2 ), i, i + numElements - 1, 1 );
i = i + 5;
}
int M = select( medians, numGroups, (int) ceil( ( double ) numGroups / 2 ), 0, numGroups - 1, 1 );
delete[] medians;
if( flag == 1 )
return M;
int q = partition2( input, M, start, end );
int m = q - start + 1;
if( k == m )
return M;
else if( k < m )
return select( input, m - 1, k, start, q - 1, 0 );
else
return select( input, end - q, k - m, q + 1, end, 0 );
}
void solution3( int input[], const int n, const int k, int output[] ) {
select( input, n, k, 0, n - 1, 0 );
for( int i = 0; i < k; i++ )
output[i] = input[i];
}
#endif // SOLUTIONS_H_INCLUDED
Building your program with address sanitizer (clang++ clock.cxx -std=c++11 -O1 -g -fsanitize=address -fno-omit-frame-pointer) reveals the problem:
$ ./a.out
Hello world!
=================================================================
==8175==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62e00000a040 at pc 0x000104dbd912 bp 0x7fff5ae43970 sp 0x7fff5ae43968
WRITE of size 4 at 0x62e00000a040 thread T0
#0 0x104dbd911 in main clock.cxx:18
#1 0x7fff88cd85fc in start (libdyld.dylib+0x35fc)
#2 0x0 (<unknown module>)
0x62e00000a040 is located 0 bytes to the right of 40000-byte region [0x62e000000400,0x62e00000a040)
And there is your code:
int* input1 = new int[10000];
int* input2 = new int[20000];
int* input3 = new int[40000];
int* input4 = new int[80000];
int* input5 = new int[100000];
for(int i = 0; i<100000; i++)
{
input1[i]= rand();
input2[i]= rand();
input3[i]= rand();
input4[i]= rand();
input5[i]= rand();
}
As you can see, size of input1, input2, ..., input4 is 10K, 20K, 40K, 80K elements, but in the loop we are accessing to elements out of this array so this can lead to the heap corruption.
Process returned -1073741819 (0xC0000005)
This means "memory access violation" or SEGFAULT.
Hope this will help.

Converting a piece of C++ to Python

I'm trying to convert this C++ to Python. I practice Python only and haven't touched C/C++ yet.
int phi(const int n)
{
// Base case
if ( n < 2 )
return 0;
// Lehmer's conjecture
if ( isprime(n) )
return n-1;
// Even number?
if ( n & 1 == 0 ) {
int m = n >> 1;
return !(m & 1) ? phi(m)<<1 : phi(m);
}
// For all primes ...
for ( std::vector<int>::iterator p = primes.begin();
p != primes.end() && *p <= n;
++p )
{
int m = *p;
if ( n % m ) continue;
// phi is multiplicative
int o = n/m;
int d = binary_gcd(m, o);
return d==1? phi(m)*phi(o) : phi(m)*phi(o)*d/phi(d);
}
}
Most of it is straightforward to convert, it just requires looking up C++ operators. However, this bit:
for ( std::vector<int>::iterator p = primes.begin();
p != primes.end() && *p <= n;
++p )
What does it mean in Python?
for p in primes:
if p > n:
break
...
or
for p in (x for x in primes if x <= n):
...
Although the former will end quicker.

Sieve of Atkin malfunctioning for very high limits

I am attempting to solve Project Euler problem 10 where the user is asked to calculate the sum of all the primes less than two million. I've written the following by studying the pseudocode on Wikipedia but the answer it generates seems to be incorrect, at least according to the website whenever I try to enter it:
int main()
{
int limit = 2000000;
int answer = 5;
std::vector<bool> isPrime;
for( int i = 0; i < limit; ++i ){
isPrime.push_back( false );
}
int n = 0;
for( int x = 1; x <= ceil( sqrt( limit ) ); ++x ){
for( int y = 1; y <= ceil( sqrt( limit ) ); ++y ){
n = 4*x*x + y*y;
if( (n <= limit) && ( n%12 == 1 || n%12 == 5 ) ){
isPrime.at(n) = ! isPrime.at(n);
}
n = 3*x*x + y*y;
if( (n <= limit) && ( n%12 == 7 ) ){
isPrime.at(n) = ! isPrime.at(n);
}
n = 3*x*x - y*y;
if( (x > y) && (n <= limit) && (n%12 == 11) ){
isPrime.at(n) = ! isPrime.at(n);
}
}
}
for( n = 6; n <= ceil( sqrt( limit ) ); n += 2 ){
if( isPrime.at(n) ){
for( int m = n*n; m < limit; m += n*n ){
isPrime.at(m) = false;
}
}
}
for( int i = 5; i < limit; i += 2 ){
if( isPrime.at(i) ){
answer += i;
}
}
std::cout << "The sum of the primes below " << limit << " is " << answer << std::endl;
return 0;
}
The following output is generated:
The sum of all the primes below 2000000 is 1179908154
I've tested it with smaller limits that I'm able to verify by hand and the code is indeed functioning correctly for those numbers. I've found other peoples implementation which indicate that the answer should be 142913828922, but I can't figure out where their code differs from mine.
Can anyone see what it is I'm doing wrong here?
You only have a signed 32-bit integer for the answer. The actual answer is much higher than can fit in 32 bits, so you have to go over to using 64 bit integers. Try using unsigned long long instead.
You can create your own class to store big numbers.Or u can use an array of integer to store your answer and storing each digit at each index. (Even if unsigned long long not working) :)

C++: compute a number's complement and its number of possible mismatches

I got a bit stuck with my algorithm and I need some help to solve my problem. I think an example would explain better my problem.
Assuming:
d = 4 (maximum number of allowed bits in a number, 2^4-1=15).
m_max = 1 (maximum number of allowed bits mismatches).
kappa = (maximum number of elements to find for a given d and m, where m in m_max)
The main idea is for a given number, x, to compute its complement number (in binary base) and all the possible combinations for up to m_max mismatches from x complement's number.
Now the program start to scan from i = 0 till 15.
for i = 0 and m = 0, kappa = \binom{d}{0} = 1 (this called a perfect match)
possible combinations in bits, is only 1111 (for 0: 0000).
for i = 0 and m = 1, kappa = \binom{d}{1} = 4 (one mismatch)
possible combinations in bits are: 1000, 0100, 0010 and 0001
My problem was to generalize it to general d and m. I wrote the following code:
#include <stdlib.h>
#include <iomanip>
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <stdint.h>
#include <vector>
namespace vec {
typedef std::vector<unsigned int> uint_1d_vec_t;
}
int main( int argc, char* argv[] ) {
int counter, d, m;
unsigned num_combination, bits_mask, bit_mask, max_num_mismatch;
uint_1d_vec_t kappa;
d = 4;
m = 2;
bits_mask = 2^num_bits - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
for ( unsigned m = 0 ; m < max_num_mismatch ; m++ ) {
// maximum number of allowed combinations
num_combination = boost::math::binomial_coefficient<double>( static_cast<unsigned>( d ), static_cast<unsigned>(m) );
kappa.push_back( num_combination );
for ( unsigned j = 0 ; j < kappa.at(m) ; j++ ) {
if ( m == 0 )
v[i][counter++] = i^bits_mask; // M_0
else {
bit_mask = 1 << ( num_bits - j );
v[i][counter++] = v[i][0] ^ bits_mask
}
}
}
}
return 0;
}
I got stuck in the line v[i][counter++] = v[i][0] ^ bits_mask since I was unable to generalize my algorithm to m_max>1, since I needed for m_max mismatches m_max loops and in my original problem, m is unknown until runtime.
i wrote a code that do what i want, but since i am newbie, it is a bit ugly.
i fixed m and d although this code would work fine for genral m and d.
the main idea is simple, assuming we would like to compute the complement of 0 up to two failure (d= 4,m=2), we will see that max number of possibilities is given by \sum_{i = 0)^2\binom{4}{i} = 11.
The complement to 0 (at 4 bits) is 15
With 1 bit possible mismatch (from 15): 7 11 13 14
with 2 bits possible mismatches (from 15): 3 5 6 9 10 12
i wanted that the output of this program will be a vector with the numbers 15 7 11 13 14 3 5 6 9 10 12 inside it.
i hope that this time i am more clear with presenting my question (although i also supplied the solution). I would appreachiate if someone could point out, in my code, ways to improve it and make it faster.
regards
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <vector>
#define USE_VECTOR
namespace vec {
#if defined(USE_VECTOR) || !defined(USE_DEQUE)
typedef std::vector<unsigned int> uint_1d_vec_t;
typedef std::vector<uint_1d_vec_t> uint_2d_vec_t;
#else
typedef std::deque<unsigned int> uint_1d_vec_t;
typedef std::deque<uint_1d_vec_t> uint_2d_vec_t;
#endif
}
using namespace std;
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits );
double get_kappa( int m , int d );
int main( ) {
unsigned int num_elements , m , num_bits;
num_elements = 16;
num_bits = 4; // 2^4 = 16
m = 2;
double kappa = 0;
for ( unsigned int i = 0 ; i <= m ; i++ )
kappa += get_kappa( num_bits , i );
vec::uint_2d_vec_t Pointer( num_elements , vec::uint_1d_vec_t (kappa ,0 ) );
get_pointers_vec( Pointer , num_elements , m , num_bits );
for ( unsigned int i = 0 ; i < num_elements ; i++ ) {
std::cout << setw(2) << i << ":";
for ( unsigned int j = 0 ; j < kappa ; j++ )
std::cout << setw(3) << Pointer[i][j];
std::cout << std::endl;
}
return EXIT_SUCCESS;
}
double get_kappa( int n , int k ) {
double kappa = boost::math::binomial_coefficient<double>( static_cast<unsigned>( n ), static_cast<unsigned>(k) );
return kappa;
}
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits ) {
int counter;
unsigned num_combination, ref_index, bits_mask, bit_mask;
vec::uint_1d_vec_t kappa;
bits_mask = pow( 2 , num_bits ) - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
kappa.clear();
ref_index = 0;
for ( unsigned m = 0 ; m <= max_num_unmatch ; m++ ) {
num_combination = get_kappa( num_bits , m ); // maximum number of allowed combinations
kappa.push_back( num_combination );
if ( m == 0 ) {
v[i][counter++] = i^bits_mask; // M_0
}
else if ( num_bits == kappa.at(m) ) {
for ( unsigned k = m ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
}
else {
// Find first element's index
ref_index += kappa.at( m - 2 );
for( unsigned j = 0 ; j < ( kappa.at(m - 1) - 1 ) ; j++ ) {
for ( unsigned k = m + j ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
ref_index++;
}
}
}
}
}