Why would this code give a segfault only for some cases? - c++

I am trying to code a Word-RAM version of the subset sum. (It is a basic dp algorithm, and the algo itself should not be important to determine the problem with the code). This is the minimum code needed to reproduce the error I think:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// get bit #bitno from num. 0 is most significant.
unsigned int getbit(unsigned int num, int bitno){
unsigned int w = sizeof(int)*8; //for regular word.
int shiftno = w-bitno-1;
unsigned int mask = 1<<shiftno;
unsigned int maskedn = num&mask;
unsigned int thebit = maskedn>>shiftno;
return thebit;
}
/* No boundary array right shift */
unsigned int* nbars(unsigned int orig[], unsigned int x){
int alength = sizeof(orig)/sizeof(orig[0]);
unsigned int b_s = sizeof(int)*8;
unsigned int * shifted;
shifted = new unsigned int[alength];
int i;
for(i=0;i<alength;i++){
shifted[i] = 0;
}
unsigned int aux1 = 0;
unsigned int aux2 = 0;
int bts = floor(x/b_s);
int split = x%b_s;
i = bts;
int j = 0;
while(i<alength){
aux1 = orig[j]>>split;
shifted[i] = aux1|aux2;
aux2 = orig[j]<<(b_s-split);
i++;j++;
}
return shifted;
}
/* Returns true if there is a subset of set[] with sum equal to t */
bool isSubsetSum(int set[],int n, int t){
unsigned int w = sizeof(int)*8; //for regular word.
unsigned int wordsneeded = ceil(double(t+1)/w);
unsigned int elements = n;
//Create table
unsigned int table[elements][wordsneeded];
int c,i;
//Initialize first row
for(i=0;i<wordsneeded;i++){
table[0][i] = 0;
}
table[0][0] = 1<<(w-1);
//Fill the table in bottom up manner
int es,ss,ai;
for(c=1;c<=elements; c++){
unsigned int *aux = nbars(table[c-1],set[c-1]);
for(i=0;i<wordsneeded;i++){
table[c][i] = table[c-1][i]|aux[i];
}
}
if((table[elements][wordsneeded-1]>>((w*wordsneeded)-t-1))&1 ==1){
return true;
}return false;
}
int main(){
int set[] = {81,80,43,40,30,26,12,11,9};
//int sum = 63;
int sum = 1000;
int n = sizeof(set)/sizeof(set[0]);
if (isSubsetSum(set,n,sum) == true)
printf("\nFound a subset with given sum\n");
else
printf("\nNo subset with given sum\n");
return 0;
}
Ok. so If I run the example with a target sum of 63, it works just fine. gives the right answer , True, and if I run code to print the subset it prints the right subset. however, if I change the sum to a larger one, say 1000 like in the code, I get the following error:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400af1 in isSubsetSum (set=0x0, n=0, t=0) at redss.cpp:63
63 unsigned int *aux = nbars(table[c-1],set[c-1]);
from gdb. I really don't understand why it would fail only for larger sums, since the process should be the same... am I missing something obvious? Any help would be great!!!

Related

Find the number of ways the N balls could be placed in the M boxes

You have N different balls numbered from 1 to N, and M different boxes numbered from 1 to M.
Input:
First line of input contains the number of test cases T. After that, next T lines contain the value of N and M.
Output:
For each test case, print the answer. As it can be very large, you should print it modulo 10^9 + 7.
I tried the below code, but it gives an error:
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
int main()
{
unsigned short int T;
unsigned long int N,M;
cin>>T;
for (int i = 0; i < T; i++)
{
cin>>N>>M;
long int res;
res= pow(M,N);
int c=0;
c=pow(10,9);
res=res%(c + 7);
cout<<res<<endl;
}
return 0;
}
You must be facing integer overflow problem, that's why you must have been getting wrong answer.
Do the following steps to fix this problem.
change the unsigned long to long long or unsigned long long. (Why? Think).
Use the logarithmic user-defined function to calculate the value of the res = pow(M,N) along with the modulo consideration side-by-side. This will boost up your program.
See my code snippet to check what changes to be made:
#include<iostream>
#define MOD 1000000007
int main() {
unsigned short int T;
unsigned long long N , M , result;
unsigned long long power(unsigned long long, unsigned long long); /*prototype of power*/
std::cin>>T;
for (int i = 0; i < T; i++) {
std::cin >> N >> M;
result = power(M , N);
std::cout << result << std::endl;
}
return 0;
}
unsigned long long power(unsigned long long M, unsigned long long N) {
if(N == 0) {
return 1;
}
unsigned long long result = power(M , N/2);
result = (result * result) % MOD;
if(N%2 == 1) {
result = (result * M) % MOD;
}
return result;
}

Printing (Factorial of 2^n)/(2^n -1)mod m in C++

How can we store and print factorial(2^n) / (2^n -1))mod1000000009 in C++.Here n can be as large as 20. When I try to print this using the following code, it shows segmentation fault for n=20
#include
#include
using namespace std;
long int factorial(int n)
{
if(n<=1){return 1;}
else
return (n%1000000009)*(factorial(n-1))%1000000009;
}
int main()
{
int K;
long long int numofmatches=0;
long long int denominator=0;
long long int factor=0;
long long int times=0;
long long int players=0;
cin>>K;
if(K==1)
{
cout<<2<<endl<<2<<endl;
return 0;
}
else
{
denominator=pow(2,K);
cout<<"Denominator="<<denominator<<endl;
numofmatches=factorial(denominator)%1000000009;
denominator-=1;
cout<<"numberofmatches="<<numofmatches<<endl;
cout<<"Denominator="<<denominator<<endl;
factor=numofmatches/denominator;
cout<<"Factor="<<factor<<endl;
while(times<=denominator)
{
cout<<(times*factor)<<endl;
++times;
}
}
return 0;
}
First of all, note that (2^n)! / (2^n-1) is equal to (2^n-2)! x 2^n.
Now, (2^20-2)! by itself is already an extremely large number to calculate.
What you can do instead, is to modulo the intermediate result with 1000000009 after every multiplication:
#define MAX ((1<<20)-2)
unsigned long long res = 1;
for (unsigned int i=1; i<=MAX; i++)
res = (res*i)%1000000009;
res = (res*(MAX+2))%1000000009;
If you want to iterate all values of n between 1 and 20, then you can use:
#define MAX_N 20
unsigned int arr[MAX_N+1] = {0};
void Func()
{
unsigned int i = 1;
unsigned long long res = 1;
for (int n=1; n<=MAX_N; n++)
{
unsigned int max = (1<<n)-2;
for (; i<=max; i++)
res = (res*i)%1000000009;
arr[n] = (unsigned int)((res*(max+2))%1000000009);
}
}
BTW, for any n larger than 29 the result will simply be 0, as (2^30-2) is larger than 1000000009.
So (2^30-2)! is divisible by 1000000009, and therefore, (2^30-2)! mod 1000000009 equals 0.

Converting an array of 2 digit numbers into an integer (C++)

Is it possible to take an array filled with 2 digit numbers e.g.
[10,11,12,13,...]
and multiply each element in the list by 100^(position in the array) and sum the result so that:
mysteryFunction[10,11,12] //The function performs 10*100^0 + 11*100^1 + 12*100^3
= 121110
and also
mysteryFunction[10,11,12,13]
= 13121110
when I do not know the number of elements in the array?
(yes, the reverse of order is intended but not 100% necessary, and just in case you missed it the first time the numbers will always be 2 digits)
Just for a bit of background to the problem: this is to try to improve my attempt at an RSA encryption program, at the moment I am multiplying each member of the array by 100^(the position of the number) written out each time which means that each word which I use to encrypt must be a certain length.
For example to encrypt "ab" I have converted it to an array [10,11] but need to convert it to 1110 before I can put it through the RSA algorithm. I would need to adjust my code for if I then wanted to use a three letter word, again for a four letter word etc. which I'm sure you will agree is not ideal. My code is nothing like industry standard but I am happy to upload it should anyone want to see it (I have also already managed this in Haskell if anyone would like to see that). I thought that the background information was necessary just so that I don't get hundreds of downvotes from people thinking that I'm trying to trick them into doing homework for me. Thank you very much for any help, I really do appreciate it!
EDIT: Thank you for all of the answers! They perfectly answer the question that I asked but I am having problems incorporating them into my current program, if I post my code so far would you be able to help? When I tried to include the answer provided I got an error message (I can't vote up because I don't have enough reputation, sorry that I haven't accepted any answers yet).
#include <iostream>
#include <string>
#include <math.h>
int returnVal (char x)
{
return (int) x;
}
unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
unsigned long long remainder;
int x = 1;
while (e != 0)
{
remainder = e % 2;
e= e/2;
if (remainder == 1)
x = (x * b) % m;
b= (b * b) % m;
}
return x;
}
int main()
{
unsigned long long p = 80001;
unsigned long long q = 70021;
int e = 7;
unsigned long long n = p * q;
std::string foo = "ab";
for (int i = 0; i < foo.length(); i++);
{
std::cout << modExp (returnVal((foo[0]) - 87) + returnVal (foo[1] -87) * 100, e, n);
}
}
If you want to use plain C-style arrays, you will have to separately know the number of entries. With this approach, your mysterious function might be defined like this:
unsigned mysteryFunction(unsigned numbers[], size_t n)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < n; ++i)
{
result += factor * numbers[i];
factor *= 100;
}
return result;
}
You can test this code with the following:
#include <iostream>
int main()
{
unsigned ar[] = {10, 11, 12, 13};
std::cout << mysteryFunction(ar, 4) << "\n";
return 0;
}
On the other hand, if you want to utilize the STL's vector class, you won't separately need the size. The code itself won't need too many changes.
Also note that the built-in integer types cannot handle very large numbers, so you might want to look into an arbitrary precision number library, like GMP.
EDIT: Here's a version of the function which accepts a std::string and uses the characters' ASCII values minus 87 as the numbers:
unsigned mysteryFunction(const std::string& input)
{
unsigned result = 0;
unsigned factor = 1;
for (size_t i = 0; i < input.size(); ++i)
{
result += factor * (input[i] - 87);
factor *= 100;
}
return result;
}
The test code becomes:
#include <iostream>
#include <string>
int main()
{
std::string myString = "abcde";
std::cout << mysteryFunction(myString) << "\n";
return 0;
}
The program prints: 1413121110
As benedek mentioned, here's an implementation using dynamic arrays via std::vector.
unsigned mystery(std::vector<unsigned> vect)
{
unsigned result = 0;
unsigned factor = 1;
for (auto& item : vect)
{
result += factor * item;
factor *= 100;
}
return result;
}
void main(void)
{
std::vector<unsigned> ar;
ar.push_back(10);
ar.push_back(11);
ar.push_back(12);
ar.push_back(13);
std::cout << mystery(ar);
}
I would like to suggest the following solutions.
You could use standard algorithm std::accumulate declared in header <numeric>
For example
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s =
std::accumulate( std::begin( a ), std::end( a ), 0ull,
[&]( unsigned long long acc, unsigned int x )
{
return ( acc += x * i, i *= 100, acc );
} );
std::cout << "s = " << s << std::endl;
return 0;
}
The output is
s = 13121110
The same can be done with using the range based for statement
#include <iostream>
#include <numeric>
int main()
{
unsigned int a[] = { 10, 11, 12, 13 };
unsigned long long i = 1;
unsigned long long s = 0;
for ( unsigned int x : a )
{
s += x * i; i *= 100;
}
std::cout << "s = " << s << std::endl;
return 0;
}
You could also write a separate function
unsigned long long mysteryFunction( const unsigned int a[], size_t n )
{
unsigned long long s = 0;
unsigned long long i = 1;
for ( size_t k = 0; k < n; k++ )
{
s += a[k] * i; i *= 100;
}
return s;
}
Also think about using std::string instead of integral numbers to keep an encrypted result.

Image maximum value with SSE instruction

I'm trying to cede a function that return the maximum value of an image with the use of SSE instruction. I have a strange result of the maximum value set to be -356426400 (the value should be 254).
this is my code :
void max_sse(unsigned int *src, long h, long w, unsigned int *val)
{
unsigned int tab[16];
for(int i=0; i<h*w;i+=16)
{
__m128i PG=_mm_load_si128((__m128i*)(&src[i]));
__m128i max=_mm_max_epi8(max,PG);
_mm_store_si128((__m128i*)&tab, max);
}
*val=tab[0];
for (int i=0;i<16;i++)
{
if (tab[i]>*val)
{
*val=tab[i];
}
}
}
1) I don't see any code dealing with alignment
2) There's a mismatch between unsigned integers and _mm_max_epi8 which comapares 8-bit signed integers (http://msdn.microsoft.com/en-us/library/bb514045(v=vs.90).aspx)
3) I'm assuming you have a h*w matrix with rows multiple of 4 (or dealing with that with some padding for instance)
On Windows you could do something like:
#include "windows.h"
#include <malloc.h>
#include <smmintrin.h>
#include <iostream>
using namespace std;
void max_sse(unsigned int *src, long h, long w, unsigned int *val)
{
_STATIC_ASSERT(sizeof(unsigned int) == sizeof(BYTE)*4);
if( w % 4 != 0)
return; // ERROR Can't do it, need 4-multiple rows or do some alignment!
unsigned int *aligned_src = (unsigned int*)_aligned_malloc(h*w*sizeof(unsigned int), 16); // _mm_load_si128 needs 16-bytes aligned memory
memcpy(aligned_src, src, sizeof(unsigned int)*h*w);
__declspec(align(16)) __m128i max = {0,0,0,0};
// Iterates the matrix
for(int i=0; i<h*w; i+=4)
{
__m128i *pg = (__m128i*)(aligned_src+i);
__m128i PG = _mm_load_si128(pg);
__m128i newmax = _mm_max_epu32(max, PG);
_mm_store_si128(&max, newmax);
}
unsigned int abs_max = 0;
unsigned int *max_val = (unsigned int*)&max;
for (int i=0;i<4;i++)
{
if (abs_max < *(max_val+i))
{
abs_max = *(max_val+i);
}
}
_aligned_free(aligned_src);
cout << "The max is: " << abs_max << endl;
}
int main()
{
unsigned int src[] = {0,1,2,4, 5,6,7,8, 224,225,226,129};
unsigned int val;
max_sse(src, 3,4, &val);
return 0;
}
I'm assuming the memcpy a necessary evil in your code since there isn't any other information on memory alignment. If you have something to deal with that, do it yourself and it will be a lot better.

Curious behaviour of inverse modulo

I wrote the following code to calculate n!modulo p...Given that n and p are close...but its running in a rather funny way, cant figure out the bug..There is some overflow somewhere..The constraints are 1 < P <= 2*10^9
1 <= N <= 2*10^9
though it runs fine for few cases...what could be the error.I have used
(a/b)mod p = ((a mod p)*(b^(p-2))mod p)mod p
as p is prime....and wilsons theorem that (p-1)! mod p = p-1
#include<bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
unsigned int pow(unsigned int a, unsigned n,unsigned int p) {
unsigned int ret = 1;
while(n) {
if((n&1)== 1) ret=(ret*a)%p;
a=a%p;
a=(a*a)%p;
n=n>>1;
}
return ret;
}
int main(){_
int t;
cin>>t;
while(t--){
unsigned int n,p;
long long int r;
cin>>n>>p;
r=p-1;
if(n>=p){
cout<<"0\n";
}
else{
for(unsigned int i=p-1;i>n;i--){
r=((long long)r*pow(i,p-2,p))%p;
}
cout<<r<<"\n";
}
}
return 0;
}
21! is 51090942171709440000, while 2^64 is only 1844674407370955161: so if unsigned long long is a 64-bit quantity (as is likely), it doesn't fit.