Dynamic programming algorithm - c++
Hi I have a question on an existing algo problem.
Existing problem description: Generate 10-digit number using a phone keypad
1 2 3
4 5 6
7 8 9
0
Though this question has a tag of C++, consider this pseudo-code to express the algorithm (which conveniently happens to be written in ruby.)
# Where the knight can jump to
$m = {
0 => [4,6], 1 => [6,8], 2 => [7,9], 3 => [4,8], 4 => [0,3,9],
5 => [], 6 => [0,1,7], 7 => [2,6], 8 => [1,3], 9 => [2,4]
}
$cache = Hash.new
# return count
def nseq( k, n, e=0 )
e += 1 if k.even?
return 0 if 3 < e
return 1 if n == 1
key = "#{k}:#{n}:#{e}" # for the memoization
return $cache[key] if $cache.has_key? key
# Sum nseq(j,n-1,e) for j in $m[k]
return $cache[key] = $m[k].inject(0) { |sum,j| sum + nseq( j, n-1, e ) }
end
0.upto(9) do |k|
2.upto(8) do |n|
count = nseq(k,n)
puts "k=#{k},n=#{n}: #{count}"
break if count.zero?
end
end
This outputs
k=0,n=2: 2
k=0,n=3: 6
k=0,n=4: 8
k=0,n=5: 16
k=0,n=6: 0
k=1,n=2: 2
k=1,n=3: 5
k=1,n=4: 10
k=1,n=5: 24
k=1,n=6: 32
k=1,n=7: 64
k=1,n=8: 0
k=2,n=2: 2
k=2,n=3: 4
k=2,n=4: 10
k=2,n=5: 16
k=2,n=6: 32
k=2,n=7: 0
k=3,n=2: 2
k=3,n=3: 5
k=3,n=4: 10
k=3,n=5: 24
k=3,n=6: 32
k=3,n=7: 64
k=3,n=8: 0
k=4,n=2: 3
k=4,n=3: 6
k=4,n=4: 14
k=4,n=5: 16
k=4,n=6: 32
k=4,n=7: 0
k=5,n=2: 0
k=6,n=2: 3
k=6,n=3: 6
k=6,n=4: 14
k=6,n=5: 16
k=6,n=6: 32
k=6,n=7: 0
k=7,n=2: 2
k=7,n=3: 5
k=7,n=4: 10
k=7,n=5: 24
k=7,n=6: 32
k=7,n=7: 64
k=7,n=8: 0
k=8,n=2: 2
k=8,n=3: 4
k=8,n=4: 10
k=8,n=5: 16
k=8,n=6: 32
k=8,n=7: 0
k=9,n=2: 2
k=9,n=3: 5
k=9,n=4: 10
k=9,n=5: 24
k=9,n=6: 32
k=9,n=7: 64
k=9,n=8: 0
The result is the number of all n-length sequences starting on key k, which have no more than 3 even digits in them. For example, the last entry is k=9,n=8: 0. This means that all sequences of length 8 starting on key 9 include more than 3 even digits.
EDIT: Here it is translated into C++. It produces identical output as above.
#include<iostream>
#include<map>
using namespace std;
const int MAX_EVENS = 3; // Assume < 8
// Where the knight can jump to
const int jumpto[][3] = { {4,6}, // 0
{6,8}, {7,9}, {4,8}, // 1 2 3
{0,3,9}, {}, {0,1,7}, // 4 5 6
{2,6}, {1,3}, {2,4} }; // 7 8 9
const int jumpto_size[] = { 2, // 0
2, 2, 2, // 1 2 3
3, 0, 3, // 4 5 6
2, 2, 2 }; // 7 8 9
typedef map<unsigned,int> cachetype;
cachetype cache;
int nseq( int k, int n, int e=0 )
{
e += k&1^1; // increment e if k is even.
if( MAX_EVENS < e ) return 0;
if( n <= 1 ) return 1;
unsigned key = (n << 4 | k) << 3 | e; // n is left with 32-7=25 bits
cachetype::const_iterator it = cache.find(key);
if( it != cache.end() ) return it->second;
int sum = 0;
for( int i=0 ; i<jumpto_size[k] ; ++i ) sum += nseq( jumpto[k][i], n-1, e );
return cache[key] = sum;
}
int main()
{
for( int k=0 ; k<=9 ; ++k )
for( int n=2 ; n<=8 ; ++n )
{
int count = nseq(k,n);
cout << "k="<<k<<",n="<<n<<": "<<count<<endl;
if( count == 0 ) break;
}
return 0;
}
Related
Failing for specific case
This is for finding the top view of a binary tree. My logic has been line by line traversal of the tree. I have used two maps here, m2 for storing node and horizontal distance, the other(m1) with horizontal distance and node data. It seems to fail for a specific case(I cannot copy the test case here because the test case is too large and is not shown completely) in GFG : Link to question Here is the partial test case I can get : 1 338 5 4 L 5 4 R 4 8 L 4 -1 N 4 2 L 4 2 R 8 8 L 8 -1 N 2 4 L 2 7 R 2 5 L 2 -1 N 8 9 L 8 3 R 4 9 L 4 -1 N 7 5 L 7 3 R 5 8 L 5 -1 N 9 1 L 9 8 R 3 1 L 3 -1 N 9 10 L 9 10 R 5 5 L 5 -1 N 3 7 L 3 6 R 8 9 L 8 -1 N 1 3 L 1 10 R 8 6 L 8 -1 N 1 7 L 1 10 R 10 4 L 10 -1 N 10 7 L 10 10 R 5 8 L 5 -1 N 7 1 L 7 9 R 6 10 L 6 -1 N 9 3 L 9 10 R 3 10 L 3 -1 N 10 2 L 10 4 R 6 2 L 6 -1 N 7 7 L 7 7 R 10 3 L 10 -1 N 4 5 L 4 3 R 7 1 L 7 -1 N 10 3 L 10 2 R 8 10 L 8 -1 N 1 2 L 1 1 R 9 10 L 9 -1 N 10 1 L 10 4 R 3 8 L 3 -1 N 10 8 L 10 7 R 10 9 L 10 -1 N 2 4 L 2 7 R 4 2 L 4 -1 N 2 6 L 2 1 R 7 10 L 7 -1 N 7 6 L 7 10 R 3 3 L 3 -1 N 5 8 L 5 5 R 3 9 L 3 -1 N 1 9 L 1 4 R 3 6 L 3 -1 N 2 3 L 2 3 R 10 7 L 10 -1 N 2 4 L 2 7 R 1 7 L 1 -1 N 10 6 L 10 6 R 1 8 L 1 -1 N 4 6 L 4 8 R 8 7 L 8 -1 N 8 9 L 8 1 R 7 4 L 7 -1 N 9 10 L 9 2 R 4 6 L 4 -1 N 7 1 L 7 1 R 2 9 L 2 -1 N 6 4 L 6 2 R 1 6 L 1 -1 N 10 9 L 10 4 R 6 9 L 6 -1 N 10 2 L 10 6 R 3 1 L 3 -1 N 8 2 L 8 8 R 5 1 L 5 -1 N 9 3 L 9 6 R 9 7 L 9 -1 N 4 3 L 4 2 R 6 2 L 6 -1 N 3 10 L 3 ................. Expected Output : 5 3 10 9 10 3 1 9 8 8 4 5 4 2 6 8 3 My Output: 5 3 10 9 10 3 1 9 8 8 4 5 4 2 My Code : // { Driver Code Starts #include <bits/stdc++.h> using namespace std; struct Node { int data; struct Node *left; struct Node *right; Node(int x){ data = x; left = NULL; right = NULL; } }; void topView(struct Node *root); int main() { int t;cin>>t; while(t--) { int n,i,k; cin>>n; i=n; Node* root=NULL; queue <Node*> q; while(i>0) { int a,b; char c; cin>> a >> b >> c; if(!root){ root = new Node(a); q.push(root); } Node* pick = q.front(); q.pop(); if(c == 'L'){ pick->left = new Node(b); q.push( pick->left ); } cin>> a >> b >> c; if(c == 'R'){ pick->right = new Node(b); q.push( pick->right ); } i-=2; } // inorder(root); // cout<<endl; topView(root); cout << endl; } return 0; } // } Driver Code Ends //Structure of binary tree /*struct Node struct Node { int data; struct Node* left; struct Node* right; Node(int x){ data = x; left = right = NULL; } };*/ // function should print the topView of the binary tree void topView(struct Node *root) { if(root==NULL) return; queue<Node *> q; map<Node *,int> m2; map<int,int> m1; m1[0]=root->data; m2[root]=0; q.push(root); while(!q.empty()) { if(q.front()->left) { q.push(root->left); if(m1.find(m2[root]-1)==m1.end()) { m2[root->left]=m2[root]-1; m1[m2[root]-1]=root->left->data; } } if(q.front()->right) { q.push(root->right); if(m1.find(m2[root]+1)==m1.end()) { m2[root->right]=m2[root]+1; m1[m2[root]+1]=root->right->data; } } q.pop(); root=q.front(); } for(auto i:m1) cout<<i.second<<" "; }
The problem is that you add new members to m2 when the root is seen from the top of the tree: if(m1.find(m2[root]+1)==m1.end()) { m2[root->right]=m2[root]+1; This will not work for a test case like this 1 10 1 2 L 1 5 R 2 -1 N 2 3 R 5 -1 N 5 -1 N 3 -1 N 3 4 R 4 -1 N 4 6 R which has the following tree: 1 / \ 2 5 \ 3 \ 4 \ 6 The expected output would be 2 1 5 6 but your code will result in 2 1 5 Here, when the root is node 2, node 3 will be added to m2. But when the root node 3, it will not add node 4 to m2 as node 3 cannot be seen from the top and thus not initialize it correctly to position 1. Afterwards when root is set to node 4 it will look for it in m2. But as that key doesn't exist yet, it will create a new value with the standard constructor of int (0). Because of that your code suggests that node 6 is at position 1 which is overshadowed by node 5 already. The fix is simple though. Just move the assignments of m2 out of the if-clauses: m2[root->left]=m2[root]-1; if(m1.find(m2[root]-1)==m1.end()) { m1[m2[root]-1]=root->left->data; } Same for the right case.
Is it possible to efficiently compute A % B without having to compute A / B?
I'm writing a multi-precision library in C++, using a base of 2^64, and currently I'm working on the mod operation. I'm using Algorithm D described in Donald E. Knuth's 1998 edition of "The Art Of Computer Programming" Vol. 2, Section 4.3.1, for division, which yields a quotient and a remainder. For the mod operation, I'm performing a division, throwing away the quotient in the end. Although Knuth's Algorithm D is very fast if implemented in C++ with some ASM enhancements for the partial division and the concurrent multi-precision multiplication/subtraction in each step, I'm not sure if there is a better way, since throwing away a painstakingly computed result doesn't seem efficient to me. Unfortunately, it's not possible to get rid of the partial division in Algorithm D, because the partial quotient is required to compute the remainder, by subtracting the product of the partial quotient and the divisor from the dividend iteratively. I've searched the Internet for alternative solutions, and found the influential papers written by Paul Barrett and Peter L. Montgomery. However, the fancy tricks they use seem to pay off only if lots of mod operations are performed in a row with the same modulus, since they involve heavy precomputations. This is the case in complex operations like modular exponentiation, where the mod of several squares and products is required for a single modulus. Barrett starts with the basic definition of the remainder, r = a - b * (a / b), and changes the division to a multiplication with the reciprocal of b. Then he presents an efficient way to compute this multiplication, which pays off if the reciprocal is computed once for several similar computations. Montgomery transforms the operands into a completely different residue system, where modular arithmetic is cheap, but for the price of transformations to and fro. Additionally, Both algorithms introduce some restrictions, which need to be met for correct operation. Montgomery, for instance, usually requires the operands to be odd, which is the case in RSA calculations with primes, but which cannot be assumed in the general case. Outside these restrictions, even more overhead for normalizations is required. So what I need, is an efficient one-shot mod function without overhead and special restrictions. Hence my question is: Is it possible to compute a remainder without computing the quotient in the first place, in a way that is more efficient than division?
One suggestion would be to write a simple function that would calculate A%B=C and store the A, B and C values into an array, then store all the results into a vector. Then print them out to see the relationships of all of the inputs and output values. There is one thing that can be done to simplify some of this work and that is to know some of the properties of the mod function. These two statements will help you out with the function. 0 mod N = 0 N mod 0 = undefined Since 0 mod N = 0 we can put a test case for A and if it is 0 we can just use that to populate our array. Likewise if B = 0 we can populate our array's C value with -1 just to represent undefined because you can not perform A mod 0 as the compilation will fail due to division by 0. I wrote this function to do just that; then I run it through a loop for both A & B from [0,15]. #include <array> #include <vector> #include <iostream> std::array<int, 3> calculateMod(int A, int B) { std::array<int, 3 > res; if (A == 0) { res = std::array<int, 3>{ 0, B, 0 }; } else if (B == 0) { res = std::array<int, 3>{ A, 0, -1 }; } else { res = std::array<int, 3>{ A, B, A%B }; } return res; } int main() { std::vector<std::array<int, 3>> results; int N = 15; for (int A = 0; A <= N; A++) { for (int B = 0; B <= N; B++) { results.push_back(calculateMod(A, B)); } } // Now print out the results in a table form: int i = 0; // Index for formatting output for (auto& res : results) { std::cout << res[0] << " % " << res[1] << " = " << res[2] << '\n'; // just for formatting output data to make it easier to read. i++; if ( i > N ) { std::cout << '\n'; i = 0; } } return 0; } Here is it's output: 0 % 0 = 0 0 % 1 = 0 0 % 2 = 0 0 % 3 = 0 0 % 4 = 0 0 % 5 = 0 0 % 6 = 0 0 % 7 = 0 0 % 8 = 0 0 % 9 = 0 0 % 10 = 0 0 % 11 = 0 0 % 12 = 0 0 % 13 = 0 0 % 14 = 0 0 % 15 = 0 1 % 0 = -1 1 % 1 = 0 1 % 2 = 1 1 % 3 = 1 1 % 4 = 1 1 % 5 = 1 1 % 6 = 1 1 % 7 = 1 1 % 8 = 1 1 % 9 = 1 1 % 10 = 1 1 % 11 = 1 1 % 12 = 1 1 % 13 = 1 1 % 14 = 1 1 % 15 = 1 2 % 0 = -1 2 % 1 = 0 2 % 2 = 0 2 % 3 = 2 2 % 4 = 2 2 % 5 = 2 2 % 6 = 2 2 % 7 = 2 2 % 8 = 2 2 % 9 = 2 2 % 10 = 2 2 % 11 = 2 2 % 12 = 2 2 % 13 = 2 2 % 14 = 2 2 % 15 = 2 3 % 0 = -1 3 % 1 = 0 3 % 2 = 1 3 % 3 = 0 3 % 4 = 3 3 % 5 = 3 3 % 6 = 3 3 % 7 = 3 3 % 8 = 3 3 % 9 = 3 3 % 10 = 3 3 % 11 = 3 3 % 12 = 3 3 % 13 = 3 3 % 14 = 3 3 % 15 = 3 4 % 0 = -1 4 % 1 = 0 4 % 2 = 0 4 % 3 = 1 4 % 4 = 0 4 % 5 = 4 4 % 6 = 4 4 % 7 = 4 4 % 8 = 4 4 % 9 = 4 4 % 10 = 4 4 % 11 = 4 4 % 12 = 4 4 % 13 = 4 4 % 14 = 4 4 % 15 = 4 5 % 0 = -1 5 % 1 = 0 5 % 2 = 1 5 % 3 = 2 5 % 4 = 1 5 % 5 = 0 5 % 6 = 5 5 % 7 = 5 5 % 8 = 5 5 % 9 = 5 5 % 10 = 5 5 % 11 = 5 5 % 12 = 5 5 % 13 = 5 5 % 14 = 5 5 % 15 = 5 6 % 0 = -1 6 % 1 = 0 6 % 2 = 0 6 % 3 = 0 6 % 4 = 2 6 % 5 = 1 6 % 6 = 0 6 % 7 = 6 6 % 8 = 6 6 % 9 = 6 6 % 10 = 6 6 % 11 = 6 6 % 12 = 6 6 % 13 = 6 6 % 14 = 6 6 % 15 = 6 7 % 0 = -1 7 % 1 = 0 7 % 2 = 1 7 % 3 = 1 7 % 4 = 3 7 % 5 = 2 7 % 6 = 1 7 % 7 = 0 7 % 8 = 7 7 % 9 = 7 7 % 10 = 7 7 % 11 = 7 7 % 12 = 7 7 % 13 = 7 7 % 14 = 7 7 % 15 = 7 8 % 0 = -1 8 % 1 = 0 8 % 2 = 0 8 % 3 = 2 8 % 4 = 0 8 % 5 = 3 8 % 6 = 2 8 % 7 = 1 8 % 8 = 0 8 % 9 = 8 8 % 10 = 8 8 % 11 = 8 8 % 12 = 8 8 % 13 = 8 8 % 14 = 8 8 % 15 = 8 9 % 0 = -1 9 % 1 = 0 9 % 2 = 1 9 % 3 = 0 9 % 4 = 1 9 % 5 = 4 9 % 6 = 3 9 % 7 = 2 9 % 8 = 1 9 % 9 = 0 9 % 10 = 9 9 % 11 = 9 9 % 12 = 9 9 % 13 = 9 9 % 14 = 9 9 % 15 = 9 10 % 0 = -1 10 % 1 = 0 10 % 2 = 0 10 % 3 = 1 10 % 4 = 2 10 % 5 = 0 10 % 6 = 4 10 % 7 = 3 10 % 8 = 2 10 % 9 = 1 10 % 10 = 0 10 % 11 = 10 10 % 12 = 10 10 % 13 = 10 10 % 14 = 10 10 % 15 = 10 11 % 0 = -1 11 % 1 = 0 11 % 2 = 1 11 % 3 = 2 11 % 4 = 3 11 % 5 = 1 11 % 6 = 5 11 % 7 = 4 11 % 8 = 3 11 % 9 = 2 11 % 10 = 1 11 % 11 = 0 11 % 12 = 11 11 % 13 = 11 11 % 14 = 11 11 % 15 = 11 12 % 0 = -1 12 % 1 = 0 12 % 2 = 0 12 % 3 = 0 12 % 4 = 0 12 % 5 = 2 12 % 6 = 0 12 % 7 = 5 12 % 8 = 4 12 % 9 = 3 12 % 10 = 2 12 % 11 = 1 12 % 12 = 0 12 % 13 = 12 12 % 14 = 12 12 % 15 = 12 13 % 0 = -1 13 % 1 = 0 13 % 2 = 1 13 % 3 = 1 13 % 4 = 1 13 % 5 = 3 13 % 6 = 1 13 % 7 = 6 13 % 8 = 5 13 % 9 = 4 13 % 10 = 3 13 % 11 = 2 13 % 12 = 1 13 % 13 = 0 13 % 14 = 13 13 % 15 = 13 14 % 0 = -1 14 % 1 = 0 14 % 2 = 0 14 % 3 = 2 14 % 4 = 2 14 % 5 = 4 14 % 6 = 2 14 % 7 = 0 14 % 8 = 6 14 % 9 = 5 14 % 10 = 4 14 % 11 = 3 14 % 12 = 2 14 % 13 = 1 14 % 14 = 0 14 % 15 = 14 15 % 0 = -1 15 % 1 = 0 15 % 2 = 1 15 % 3 = 0 15 % 4 = 3 15 % 5 = 0 15 % 6 = 3 15 % 7 = 1 15 % 8 = 7 15 % 9 = 6 15 % 10 = 5 15 % 11 = 4 15 % 12 = 3 15 % 13 = 2 15 % 14 = 1 15 % 15 = 0 From the data above we can see that if A == B the result will be 0. We can also see that if B > A then B == A. Finally we can see that there are patterns between odd and even values of A while B < A. If you can understand these patterns then most of it becomes algebraic manipulation. From here the next step would be to create an algorithm that would take all of this data and convert it to its binary equivalence. I chose the value of N above as 15 for a reason. This is due to the binary representation of all the possible combinations of binary digits before they repeat again. We know that a single byte of data is 8 bits; we know that the values from [0,15] will fit into half of that; for example: binary byte: hex decimal 0000 0000 0x00 0 ... 0000 1111 0xFF 15 After these 15 different sequences of 0s and 1s these patterns will repeat. So by taking the table above you can convert these into binary representations. Now once you examine the representations of A & B inputs with their C outputs in binary and understand the 3 properties of the results that I had mentioned above; you should be able to design an algorithm to quickly compute the modulo of any A B combination quite easily. One trick to remember is that there are 3 other things to take into consideration. The first is what user eerokia had stated: "In particular, modulo with a power of 2 can be replaced by a bitwise operations." The next beyond that is are the values even or odd as the even and odd cases do present different patters of A mod B when B < A. I have give you some tools of information to start out on, but the rest I'll leave up to you including the task of converting the A, B, and C values into their binary representations. Once you know the binary patterns of both the A and B inputs according to their C outputs and you understand the truth tables of the logical gates - operators such as And - &, Or - |, Nand - (!&), Nor - (!|), Xor - ^ Xnor - (!^) and Not - ! as well as the compliment (~). You should be able to design your algorithm with efficiency.
Inaccurate C++ factorial program
I wrote an implementation of the following tutorial: LINK Basically, since C/C++ does not have BIG Integer we are storing the factorial decimal values in an array. This is equivalent to writing a multiplication that performs the multiplication kids are taught at schools. Problem: It works fine for values up to 17! after that (18!, 19!,... ) it does not output correct values. #include <iostream> using namespace std; int main(){ int fact[1000]={1}; int n; scanf("%d", &n); //n are the number of factorials we will calculate while(n--){ int number; scanf("%d", &number); //scan the number if(number == 0) printf("%d", 1); int flag = number; int index = 0, length = 0; //following lines we find the length of the entered number while(flag!=0){ fact[index] = flag%10; flag /= 10; index++; length++; } //following lines are the multiplication code while(number>1){ index = 0; int temp = 0; number--; for(index = 0; index<length; index++){ int x = (fact[index] * number) + temp; fact[index] = x%10; temp = x/10; } //here we append the carry over left from multiplication while(temp){ fact[index] = temp%10; temp /= 10; length++; } } //print the array from most to least significant digit for(int i = length-1; i>=0; i--){ printf("%d", fact[i]); } printf("\n"); } return 0; }
For a start, you need to be very careful with: long long int x = (fact[index] * number) + temp; Since fact[], number and temp are all int types, the calculation will be done as an int and only widened to a long long when placing the value into x. You would be better off with: long long x = fact[index]; x *= number; x += temp; That way, it becomes a long long early enough that the calculations will be done with that type. However, that doesn't actually fix your problem, so let's modify your code a little to see where the problem lies: #include <iostream> using namespace std; int main(){ int fact[1000]={1}; int n = 18, numberx = 0; while(n-- > 0){ int number = ++numberx; if(number == 0) { printf("%d", 1); continue; } int flag = number; int index = 0, length = 0; //following lines we find the length of the entered number while(flag!=0){ fact[index] = flag%10; flag /= 10; index++; length++; } //following lines are the multiplication code while(number>1){ index = 0; int temp = 0; number--; for(index = 0; index<length; index++){ long long int x = fact[index]; x *= number; x += temp; fact[index] = x%10; temp = x/10; } //here we append the carry over left from multiplication while(temp){ fact[index] = temp%10; temp /= 10; length++; } } //print the array from most to least significant digit printf("%d! = ", number); for(int i = length-1; i>=0; i--){ printf("%d ", fact[i]); } printf("\n"); } return 0; } Running this gives you: 1! = 1 2! = 2 3! = 6 4! = 2 4 5! = 1 2 0 6! = 7 2 0 7! = 5 0 4 0 8! = 4 0 3 2 0 9! = 3 6 2 8 8 0 10! = 3 6 2 8 8 0 0 11! = 3 9 9 1 6 8 0 0 12! = 4 7 9 0 0 1 6 0 0 13! = 6 2 2 7 0 2 0 8 0 0 14! = 8 7 1 7 8 2 9 1 2 0 0 15! = 1 3 0 7 6 7 4 3 6 8 0 0 0 16! = 2 0 9 2 2 7 8 9 8 8 8 0 0 0 17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0 18! = 1 9 9 1 0 4 7 1 7 3 8 5 7 2 8 0 0 0 which is, as you state okay up until 18!, where if fails. And, in fact, you can see the ratio between 17! and 18! is about 500 rather than 18 so that's where we should look. Let's first strip out the extraneous stuff by starting at 17!. That can be done simply by changing a couple of starting values: int n = 2, numberx = 16; and that gives: 17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0 18! = 1 9 9 1 0 4 7 1 7 3 8 5 7 2 8 0 0 0 Then we can add debug code to see what's happening, outputting temporary results along the way. The main loop can become: while(number>1){ index = 0; int temp = 0; number--; if (numberx > 17) printf("\n"); for(index = 0; index<length; index++){ if (numberx > 17) printf("index %d fact[] %d number %d temp %d", index, fact[index], number, temp); long long int x = fact[index]; x *= number; x += temp; fact[index] = x%10; temp = x/10; if (numberx > 17) printf(" -> fact[] %d temp %d\n", fact[index], temp); } //here we append the carry over left from multiplication while(temp){ fact[index] = temp%10; temp /= 10; length++; } if (numberx > 17) { printf("temp: "); for(int i = length-1; i>=0; i--){ printf("%d ", fact[i]); } printf("\n"); } } This shows you *exactly where things start to go wrong (// bits are added by me): 17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0 index 0 fact[] 8 number 17 temp 0 -> fact[] 6 temp 13 index 1 fact[] 1 number 17 temp 13 -> fact[] 0 temp 3 temp: 3 0 6 // okay: 18 * 17 = 306 index 0 fact[] 6 number 16 temp 0 -> fact[] 6 temp 9 index 1 fact[] 0 number 16 temp 9 -> fact[] 9 temp 0 index 2 fact[] 3 number 16 temp 0 -> fact[] 8 temp 4 temp: 4 8 9 6 // okay 306 * 16 = 4896 index 0 fact[] 6 number 15 temp 0 -> fact[] 0 temp 9 index 1 fact[] 9 number 15 temp 9 -> fact[] 4 temp 14 index 2 fact[] 8 number 15 temp 14 -> fact[] 4 temp 13 index 3 fact[] 4 number 15 temp 13 -> fact[] 3 temp 7 temp: 7 3 4 4 0 // okay 4896 * 15 = 73440 index 0 fact[] 0 number 14 temp 0 -> fact[] 0 temp 0 index 1 fact[] 4 number 14 temp 0 -> fact[] 6 temp 5 index 2 fact[] 4 number 14 temp 5 -> fact[] 1 temp 6 index 3 fact[] 3 number 14 temp 6 -> fact[] 8 temp 4 index 4 fact[] 7 number 14 temp 4 -> fact[] 2 temp 10 temp: 8 1 2 8 1 6 0 // no good: 73440 * 14 = 10128160 !!! 1 0 2 8 1 6 0 // is what it should be With a bit of thought, it appears to be the point where the final "carry" from the multiplication is greater than nine, meaning it's almost certainly in the code for handling that: while(temp){ fact[index] = temp%10; temp /= 10; length++; } Thinking about that (and comparing it to other code that changes index and length together), it becomes obvious - even though you increase the length of the array, you're not increasing the index. That means, for a final carry of ten or more, the subsequent carry will not populate the correct index, it will simply overwrite the same index each time. This can be seen here: temp: 8 1 2 8 1 6 0 // no good: 73440 * 14 = 10128160 !!! 1 0 2 8 1 6 0 // is what it should be where it will have placed the zero (10 % 10) at that second location (increasing the length) but then placed the one (10 / 10) at the same index, leaving the 8 at whatever value it had before. So, if we increment index as well, what do we see (going back to the less verbose code)? 1! = 1 2! = 2 3! = 6 4! = 2 4 5! = 1 2 0 6! = 7 2 0 7! = 5 0 4 0 8! = 4 0 3 2 0 9! = 3 6 2 8 8 0 10! = 3 6 2 8 8 0 0 11! = 3 9 9 1 6 8 0 0 12! = 4 7 9 0 0 1 6 0 0 13! = 6 2 2 7 0 2 0 8 0 0 14! = 8 7 1 7 8 2 9 1 2 0 0 15! = 1 3 0 7 6 7 4 3 6 8 0 0 0 16! = 2 0 9 2 2 7 8 9 8 8 8 0 0 0 17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0 18! = 6 4 0 2 3 7 3 7 0 5 7 2 8 0 0 0 19! = 1 2 1 6 4 5 1 0 0 4 0 8 8 3 2 0 0 0 20! = 2 4 3 2 9 0 2 0 0 8 1 7 6 6 4 0 0 0 0 That solves your specific problem and hopefully provides some education on debugging as well :-)
abnormality in the output of my code
I'm trying to read an array in c++, filled with values from 0 to 5, For an unimportant reason, I need to count how many numbers 1, numbers 2, numbers 3, numbers 4 and numbers 5 do stand on the 'iii*DAYS'th position, so when iii = 0 and DAYS is 5, I need to know how many numbers 1, numbers 2, numbers 3, numbers 4 and numbers 5 are located on the 0th, 4th, 9th, 14th position. The code I posted does this quite well, but sometimes, gives a very big unlogical value, -36589245 or 99653256, can somebody tell me why this happens ( it does happen +- one in a hunderd times ) DAYS = 28 NURSES = 33 SHIFTS =5 int calculate_penalty_coverage_offspring(int offspring[NURSES*DAYS]) { int temporary[DAYS]; int count[DAYS][SHIFTS]; penalty_score_offspring_coverage =0; for (int ii = 0; ii<DAYS; ii++) { int een = 0; int twee = 0; int drie = 0; int vier = 0; int vijf = 0; for (int iii = 0; iii<NURSES; iii++) { temporary[iii] = offspring[(ii+(iii*DAYS))]; } for(int a = 0 ; a<DAYS ; a++) { if(temporary[a]== 1) { een++; count[ii][0] = een; } else if(temporary[a] == 2) { twee++; count[ii][1] = twee; } else if(temporary[a]== 3) { drie++; count[ii][2] = drie; } else if(temporary[a]== 4) { vier++; count[ii][3] = vier; } else if(temporary[a] == 5) { vijf++; count[ii][4] = vijf; } } } for(int ii = 0; ii<DAYS ; ii++) { for (int iii =0 ; iii<SHIFTS ; iii++) { cout << count[ii][iii] << '\t'; } cout << '\n'; } this is the exeptional output where I talked about, as you can see, there is an onlogical value in the output of -31427696 ... I can't see why the function is working good, except for this one time. 1 2 2 4 4 5 2 2 9 5 9 6 3 5 2 8 3 4 3 8 9 3 3 4 6 5 5 6 8 1 6 8 2 2 5 3 5 8 -31427696 7 5 5 2 5 8 5 7 8 2 3 2 7 1 2 10 5 6 3 5 5 4 4 4 6 7 7 4 6 4 6 6 5 6 4 3 5 3 7 4 6 5 5 6 1 7 5 5 1 6 2 4 6 6 4 5 3 3 4 5 9 6 6 5 4 4 5 5 4 4 5 8 4 4 5 3 5 5 4 7 5 4 8 6 3 3 9 1 5 7 3 3 7 5 2 5 2 6 5 7 5
First you say int temporary[DAYS]; Where DAYS = 28 Then you do: for (int iii = 0; iii<NURSES; iii++) { temporary[iii] = offspring[(ii+(iii*DAYS))]; } Where NURSES = 33 You're trying to access indices that are out of bounds in temporary. EDIT: Following our discussion in the comments, You're additionally not initializing your arrays, specifically count: int count[DAYS][SHIFTS]; Which you then conditionally fill in (partially) later: if(temporary[a]== 1) { een++; count[ii][0] = een; } // ... Accesses to count afterwards to indices that were not assigned to will result in the garbage numbers you're seeing. You should probably just default the matrix to all zeros like so: int count[DAYS][SHIFTS] = {0};
bit vector intersect in handling parquet file format
I am handling parquet file format. For example: a group of data: 1 2 null 3 4 5 6 null 7 8 null null 9 10 11 12 13 14 I got a bit vector to indicate null element: 1 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 and only store the non-null element: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 I want to evaluate a predicate: big then 5 I compared non-null element to 5 and got a bit vector: 0 0 0 0 0 1 1 1 1 1 1 1 1 1 I want to got a bit vector for all elements: 0 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 1 the 0 in bold is null elements, should be false. void IntersectBitVec(vector<int64_t>& bit_vec, vector<int64_t>& sub_bit_vec) { int data_idx = 0, int bit_idx = 63; for (int i = 0; i < bit_vec.size(); ++i) { for (int j = 63; j >=0; --j) { if (bit_vec[i] & 0x01 << j) { if (!(sub_bit_vec[data_idx] & 0x01 << bit_idx)) { bit_vec[i] &= ~(0x01 << j); } if (--bit_idx < 0) { --data_idx; bit_idx = 63; } } } }} My code is quite ugly, is there anyway to make it fast? Great thanks!