segmentation fault while using pthread library - c

I am a newbie to threading and i am trying to change the sequential program of travelling salesman problem (dynamic programming) to parallel program using threading in c.
#include <stdio.h>
#include <limits.h>
#define size 10 //maximum 10 cities
#define min(a,b) (a > b ? b : a)
#define sizePOW 1024 // 2^10
//Space complexity: O(n * 2^n)
//Time complexity: O(n^2 * 2^n)
int n; npow;
int g[size][sizePOW];
int p[size][sizePOW];
int adj[size][size];
int compute(int start, int set) {
int masked, mask, temp, i;
int result = INT_MAX; //result stores the minimum
if (g[start][set] != -1) //memoization DP top-down,check for repeated subproblem
return g[start][set];
for (i = 0; i < n; i++) { //npow-1 because we always exclude "home" vertex from our set
mask = (npow - 1) - (1 << i); //remove ith vertex from this set
masked = set & mask;
if (masked != set) { //in case same set is generated(because ith vertex was not present in the set hence we get the same set on removal) eg 12&13=12
temp = adj[start][i] + compute(i, masked); //compute the removed set
if (temp < result)
result = temp,
p[start][set] = i; //removing ith vertex gave us minimum
}
}
return g[start][set] = result; //return minimum
}
void getpath(int start, int set) {
if (p[start][set] == -1)
return; //reached null set
int x = p[start][set];
int mask = (npow - 1) - (1 << x);
int masked = set & mask; //remove p from set
printf("%d ", x);
getpath(x, masked);
}
void TSP() {
int i, j;
//g(i,S) is length of shortest path starting at i visiting all vertices in S and ending at 1
for (i = 0; i < n; i++)
for (j = 0; j < npow; j++)
g[i][j] = p[i][j] = -1;
for (i = 0; i < n; i++)
g[i][0] = adj[i][0]; //g(i,nullset)= direct edge between (i,1)
int result = compute(0, npow - 2);//npow-2 to exclude our "home" vertex
printf("Tour cost:%d\n", result);
printf("Tour path:\n0 ");
getpath(0, npow - 2);
printf("0\n");
}
int main(void) {
int i, j;
printf("Enter number of cities\n");
scanf("%d",&n);
npow=(int)pow(2, n);//bit number required to represent all possible sets
printf("Enter the adjacency matrix\n");
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
scanf("%d", &adj[i][j]);
TSP();
return 0;
}
This is the sequential program from ideone code.
Here is my parallel code for this
#include <stdio.h>
#include <math.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include<limits.h>
#define size 10 //maximum 10 cities
#define min(a,b) a > b ? b:a
#define sizePOW 1024 // 2^10
struct threadargs {
int a, b;
int *c;
};
//Space complexity: O(n * 2^n)
//Time complexity: O(n^2 * 2^n)
int n, npow;
int g[size][sizePOW];
int p[size][sizePOW];
int adj[size][size];
void printMatrix() {
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 16; j++) {
printf("%d ",g[i][j]);
printf("\n");
}
printf("\n\n");
}
void *compute(void *args) {
int masked, mask, i, start, set;
int result = INT_MAX; //result stores the minimum
struct threadargs *recvargs = (struct threadargs *) args;
start = recvargs->a;
set = recvargs->b;
int *retval = recvargs->c;
if (g[start][set] != -1) { //memoization DP top-down,check for repeated subproblem
*retval += g[start][set];
return;
}
printMatrix();
//sleep(1);
int temp[n];
for (i = 0; i < n; i++)
temp[i] = INT_MAX;
pthread_t threads[n];
struct threadargs arguments[n];
int running_thread_count = 0;
for (i = 0; i < n; i++)
threads[i] == -1;
for (i = 0; i < n; i++) { //npow-1 because we always exclude "home" vertex from our set
mask= (npow - 1) - (1 << i); //remove ith vertex from this set
masked = set & mask;
//printf("hello world");
if (masked != set)//in case same set is generated(because ith vertex was not present in the set hence we get the same set on removal) eg 12&13=12
{
temp[i] = adj[start][i];
arguments[i].a = i;
arguments[i].b = masked;
arguments[i].c = &temp[i];
pthread_create(&threads[i], NULL, compute, (void *)&arguments[i] );
running_thread_count++;
}
}
for (i = 0; i < n; i++) {
if (pthread_kill(threads[i], 0) != ESRCH)
pthread_join(threads[i], NULL);
}
int ith = 0;
result = temp[0];
for (i = 1; i < n; i++) {
if(temp[i] < result) {
result = temp[i];
ith = i;
}
}
p[start][set] = ith;
if (result != INT_MAX)
g[start][set] = result; //return minimum
*retval += g[start][set];
}
void getpath(int start,int set)
{
if (p[start][set] == -1)
return; //reached null set
int x = p[start][set];
int mask= (npow - 1) - (1 << x);
int masked = set & mask;//remove p from set
printf("%d ",x);
getpath(x, masked);
}
void TSP()
{ int i, j;
//g(i,S) is length of shortest path starting at i visiting all vertices in S and ending at 1
for(i=0; i < n; i++)
for( j = 0; j < npow; j++)
g[i][j] = p[i][j] = -1;
for (i = 0; i < n; i++)
g[i][0] = adj[i][0]; //g(i,nullset)= direct edge between (i,1)
int result;
struct threadargs arguments;
arguments.a = 0;
arguments.b = npow-2;
arguments.c = &result;
compute((void *) &arguments);//npow-2 to exclude our "home" vertex
printf("Tour cost:%d\n",result);
printf("Tour path:\n0 ");
getpath(0,npow-2);
printf("0\n");
}
int main(void) {
int i, j;
printf("Enter number of cities\n");
scanf("%d", &n);
npow=(int)pow(2, n);//bit number required to represent all possible sets
printf("Enter the adjacency matrix\n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &adj[i][j]);
TSP();
return 0;
}
But I am getting segmentation fault while trying to execute this code. Following is the output of the gdb
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78bf63e in pthread_join (threadid=4196128,
thread_return=0x0) at pthread_join.c:85
85 pthread_join.c: No such file or directory.
(gdb) backtrace
#0 0x00007ffff78bf63e in pthread_join (threadid=4196128,
thread_return=0x0) at pthread_join.c:85
#1 0x0000000000400b36 in compute (args=0x7fffffffde90) at tsp3.c:69
#2 0x0000000000400db2 in TSP () at tsp3.c:107
#3 0x0000000000400ec8 in main () at tsp3.c:120
(gdb)
I know this will not give any noticeable performance gain but I want to try this. Thanks in advance.
**edit : **
I have rectified the errors but now I am facing new errors.I am getting correct answer when program runs but if I delete the line `printMatrix()
, I get segmentation fault. The gdb log is as follows
(gdb) backtrace
#0 __pthread_kill (threadid=0, signo=0)
at ../nptl/sysdeps/unix/sysv/linux/pthread_kill.c:42
#1 0x0000000000400c85 in compute (args=0x7ffff74eede0) at tsp3.c:79
#2 0x00007ffff78be182 in start_thread (arg=0x7ffff64ed700)
at pthread_create.c:312
#3 0x00007ffff75eaefd in clone ()
at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)
why is this happening. Please explain. Thanks in advance.

You are creating threads in compare function, and you pass compare as thread function, that's chaos. You maybe exceed available number of threads.

Related

C segmentation fault threads

This is a program made in C that compiles fine using gcc filename.c -o file -pthread. However when I go to run the program is tells me there is a segmentation fault and I am not sure how to fix it. This program is meant to make random integers in an array then compare how long it takes to find the 10 largest and 10 lowest numbers using a different amount of threads for reach iteration of the program.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#define arraySize 10000
#define lval 0
#define hval 50000
#define maxthread 100
int num[arraySize];
int maxs[maxthread];
int mins[maxthread];
int threadsize;
int threadnum = 0;
void fill(){
int i;
int tmp[hval];
for(i = lval;i < hval;i++)tmp[i] = i;
for(i = 0;i < arraySize;i++){
int t= i + rand()%(hval - 1);
int temp = tmp[i];
tmp[i] = tmp[t];
tmp[t] = temp;
num[i] = tmp[i];
}
}
void print(){
int i;
printf("First 10 Numbers are: \n");
for(i = 0;i < 10;i++)printf("\t%d\n",num[i]);
printf("\n\nLast 10 Numbers: \n");
for(i = (arraySize - 10);i < arraySize;i++)printf("\t%d\n",num[i]);
}
void *getminmax(void *arg){
int i,n = threadnum++;
int max = lval,min = hval;
for(i = n*(arraySize / threadsize);i < (n + 1)*(arraySize / threadsize);i++){
if (num[i] > max)max = num[i];
if (num[i] < min)min = num[i];
}
maxs[n] = max;
mins[n] = min;
printf("Threads:%d Min: %d Max%d Thread Num: %d\n",threadsize,min,max,n);
}
void search(){
int max = lval, min = hval;
int i;
int start = clock();
pthread_t threads[threadsize];
for(i = 0;i < threadsize;i++)
pthread_create(&threads[i],NULL,getminmax,(void*)NULL);
for(i = 0;i < threadsize;i++)
pthread_join(threads[i],NULL);
for(i = 0;i < threadsize;i++){
if(maxs[i] > max)max = maxs[i];
if(mins[i] < min)min = mins[i];
}
int end = clock();
int d = end - start;
printf("Threads %d Min: %d Time Taken: %d \n\n",threadsize,min,max,d);
}
int main(){
fill();
print();
threadsize = 2;
threadnum = 0;
search();
threadsize = 10;
threadnum = 0;
search();
threadsize = 100;
threadnum = 0;
search();
return 0;
}
There are few obvious bugs in your program.
As yano pointed out, t = i + rand()%(hval - 1); will produce a t in the range between 0 and arraySize + hval - 2. That later value is well outside the valid range for accessing tmp[t] and is likely the cause of the segmentation fault.
You probably meant this instead: t = (i + rand()) % (hval - 1);
The construct below is a data race. You are not at all guaranteeing distinct ns for different threads.
int n = threadnum++;
The usual fix for problem 2 is to pass the thread number as the arg (which you didn't use).

Count how many 1 in integer's binary

Sample Input
2
2
5
Sample Output
0 1 1
0 1 1 2 1 2
I already knew how to transfer an integer to its binary and count how many 1 in its binary.
But my code only can input one integer each time. I want it to input many numbers, like the sample input and sample output. To make question more easy to understand, so I drew a picture. Thank you!!
Thanks all of you!! But I need some time to understand those code and my English is pretty basic, so I couldn't reply you guys soon. But I will understand and reply you as soon as possible!!thank you :D
#include <stdio.h>
int main()
{
int n,cnt=0,m;
scanf("%d",&n);
while(n>0){
m=n%2;
if(m==1){
cnt++;
}
n/=2;
}
printf("%d",cnt);
return 0;
}
In practice, the process can be simplified and accelerated by noticing that if we know the result for i < 2^p, then, for all values in [2^p, 2^(p+1)-1], we have
count(j) = 1 + count(j-2^p)
This method is useful here as we have to provide the result for all values less or equal to n.
Moreover, in order to avoid performing the same calculation at different times, we first calculate the maximum n value, and perform the calculation for this maximum value.
#include <stdio.h>
int main() {
int t;
int check = scanf("%d", &t);
if (check != 1) return 1;
int nn[t];
for (int i = 0; i < t; ++i) {
int check = scanf("%d", &nn[i]);
if (check != 1) return 1;
}
int nmax = 0;
for (int i = 0; i < t; ++i) {
if (nn[i] > nmax) nmax = nn[i];
}
int count[nmax+1];
count[0] = 0;
count[1] = 1;
int pow2 = 1;
do {
pow2 *= 2;
for (int j = pow2; (j < 2*pow2) && (j <= nmax); j++) {
count[j] = 1 + count[j-pow2];
}
} while (pow2 <= nmax+1);
for (int i = 0; i < t; ++i) {
for (int j = 0; j <= nn[i]; ++j) {
printf ("%d ", count[j]);
}
printf ("\n");
}
return 0;
}
Let the number of measured values be t. Now if you want to take t number of integers as input, you have to run a loop t times and perform necessary tasks (like taking value of n, calculating cnt etc) inside that loop. Check the following code snippet:
int main()
{
int n,cnt=0,m;
int numberOfMeasuredValues;
scanf("%d", &numberOfMeasuredValues);
while(numberOfMeasuredValues > 0){
cnt = 0;
scanf("%d",&n);
// perform necessary calculations
printf("%d\n",cnt);
numberOfMeasuredValues--;
}
return 0;
}
In the code numberOfMeasuredValues is the t I've used in the explanation.
You can pre-allocate number of cases and work on them with outer and inner loops. I've added the code with comments below.
#include <stdio.h>
int main(void)
{
int cases; // Number of cases
scanf("%d", &cases);
int* nums = malloc(cases * sizeof *nums); // Allocate enough space.
/* Take the inputs. */
for (int i = 0; i < cases; i++)
{
scanf("%d", (nums + i));
}
int cnt = 0; // Counter for number of 1s.
// Outer loop for going through cases.
for (int i = 0; i < cases; i++)
{
// Inner loop for couting towards inputted number.
for (int j = 0; j < *(nums + i) + 1; j++)
{
/*
* You can Implement this part by yourself if you wish.
*/
for (int k = 0; k < 32; k++)
{
if ((j >> (31 - k)) & 0x01) cnt++; // Increment counter if digit is 1.
}
printf("%d ", cnt);
cnt = 0;
}
printf("\n");
}
return 0;
}
Here's the following code to your problem
#include<iostream>
using namespace std;
int main()
{
int tcs;
cin >> tcs;
while (tcs--) {
int n;
cin >> n;
for (int i = 0 ; i <= n ; i++) {
cout << __builtin_popcount(i) << " ";
}
cout << "\n";
}
return 0;
}

eclipse skips main function instead of executing it

I am using eclipse 3.2020 on WIN10 and I have a problem executing my main function.
When I run the program as it is, I get no output to conole, even when I add a printf in the first line, and the exit code is -1,073,741,819. When I comment out/ delete the line solve(s); the code run as intended and gives exit code 0.
Edit: added full code (both solve and print_sol are in solver.c)
Edit 2: As mentioned in the comments, the problem was in the code (bug) and not eclipse, I just assumed that an error message will be printed if there is one.
p.s.: I still find the fact a printf in the start won't print if there is a runtime error in another part of the main function quite weird.
main.c:
#include "solver.h"
#include <stdlib.h>
int main(int argc, char** argv){
int **grid = (int**) malloc(sizeof(int*) * 4);
for (int i = 0; i < 4 ; i++){
grid[i] = (int*) malloc(sizeof(int) * 4);
}
int mat[4][4] = {{1,0,3,0}
,{2,0,0,0}
,{3,0,0,0}
,{4,2,0,0}};
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++){
grid[i][j] = mat[i][j];
}
}
solver *s = create_solver(4, &grid);
solve(s);
print_sol(s);
}
solver.h:
#ifndef SOLVER_H_
#define SOLVER_H_
typedef struct sudoku_solver solver;
/*creates a new solver using the length of one row of the board.
*Then, the user will follow the instructions on screen to input the board*/
solver* create_solver(int row_len, int ***input_board_ptr);
/*if solver is NULL, an error will appear.
*Otherwise, The board that was given won't be changed, and neither
*the solver nor the solution (unless saved before using get_sol)
*will be accessible after this*/
void destroy_solver(solver *solver);
/*if solver is NULL, an error will appear.
*Otherwise, it will solve the inputed board*/
void solve(solver *solver);
/*if "solve" wasn't executed before, an error will appear.
*Otherwise, it will print a solution to the inputed board*/
void print_sol(solver *solver);
/*if "solve" wasn't executed before, an error will appear.
*Otherwise, returns a solution to the inputed board as a matrix of integers*/
int** get_sol(solver *solver);
#endif /* SOLVER_H_ */
solver.c:
#include "solver.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
/*the board will be represented by an array of size NxN.
*the value of every board cell is between 0 and N when 0
*means "default value"*/
typedef struct sudoku_solver{
/*length of one row of the board*/
int N;
/*a pointer to the solution board*/
int ***sol_ptr;
}solver;
solver* create_solver(int row_len, int ***input_board_ptr){
solver *s = (solver*) malloc(sizeof(solver));
/*throw an ERROR if the malloc failed*/
/*row_len is a variable, so we have to declare everything dynamically */
/*allocating the sol matrix as an array of pointers (1 out of 2D)*/
int **sol = (int**) malloc(row_len * sizeof(int*));
for (int i = 0; i < row_len; i++){
/*allocating every row (the second D)
*while making sol equal to input_board*/
sol[i] = (int*) malloc(row_len * sizeof(int));
for (int j = 0; j < row_len; j++){
sol[i][j] = (*input_board_ptr)[i][j];
}
}
s->N = row_len;
/*if row_len != pow(sqrt(row_len),2) then throw invalid input ERROR*/
s->sol_ptr = &sol;
return s;
}
void destroy_solver(solver *s){
for (int i = 0; i < s->N; i++){
free((*(s->sol_ptr))[i]);
}
free(*(s->sol_ptr));
free(s->sol_ptr);
free(s);
}
int* calc_next(int x, int y, int *next, solver *s);
bool isSafe(int x, int y, int val, solver *s);
bool solve_rec(int x, int y, solver *s);
void solve(solver *s){
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
//find next empty space
if ((*sp)[0][0] == 0){
next[0] = 0;
next[1] = 1;
}
else{
calc_next(0, 0, next, s);
}
int nextX = next[0];
int nextY = next[1];
for (int i = 1; i < n; i++){
if (isSafe(nextX, nextY, i, s)){
(*sp)[nextX][nextY] = i;
if(solve_rec(nextX, nextY, s)){
return;
}
//backtrack
(*sp)[nextX][nextY] = 0;
}
}
printf("no sol");
return;
}
bool solve_rec(int x, int y, solver *s){
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
if (x == n - 1 && y == n - 1){
return true;
}
//find next empty space
calc_next(x, y, next, s);
int nextX = next[0];
int nextY = next[1];
for (int i = 1; i < n; i++){
if (isSafe(nextX, nextY, i, s)){
(*sp)[nextX][nextY] = i;
if(solve_rec(nextX, nextY, s)){
return true;
}
//backtrack
(*sp)[nextX][nextY] = 0;
}
}
return false;
}
bool isSafe(int x, int y, int val, solver *s){
int n = s->N;
int ***sp = s->sol_ptr;
/*check row*/
for (int j = 0; j < n; j++){
if ((*sp)[x][j] == val){
return false;
}
}
/*check col*/
for (int i = 0; i < n; i++){
if ((*sp)[i][y] == val){
return false;
}
}
/*check block
*the index of a block in a grid is just like the index of entry in block.
*In sudoku, there are bs*bs blocks, and each has bs rows and bs columns*/
int bs = sqrt(n); // block size
int block_x_index = x / bs;
int block_y_index = y / bs;
for(int i = block_x_index * bs; i < bs * (block_x_index + 1); i++){
for(int j = block_y_index * bs; j < bs * (block_y_index + 1); j++){
if ((*sp)[i][j] == val){
return false;
}
}
}
return true;
}
/*assuming x,y is not the last place in the grid,
* finds the next empty place after it*/
int* calc_next(int x, int y, int *next, solver *s){
int n;
int ***sp = s->sol_ptr;
/*find the first empty place*/
do{
n = s->N;
if (y == n - 1){
x++;
y = 0;
}
else{
y++;
}
}while ((*sp)[x][y] != 0);
next[0] = x;
next[1] = y;
return next;
}
void print_sol(solver *s){
int n = s->N;
int bs = sqrt(n); // block size
char curr;
int rows_passed, col_passed;
for (int i = 0; i < n + bs - 1; i++){
for (int j = 0; j < n + bs - 1; j++){
//if it's a grid row
if (i == bs || ((i - bs) % (bs + 1)) == 0){
//if it's also a grid col
if (j == bs || ((j - bs) % (bs + 1) == 0)){
curr = '+';
}
else{
curr = '-';
}
}
//if it's only a grid col
else if (j == bs || ((j - bs) % (bs + 1) == 0)){
curr = '|';
}
else{
rows_passed = i / (bs + 1);
col_passed = j / (bs + 1);
curr = '0' + (*(s->sol_ptr))[i-rows_passed][j-col_passed];
}
printf("%c",curr);
}
printf("\n");
}
}
int** get_sol(solver *solver){
return *(solver->sol_ptr);
}
Thank you.
Please learn how to use your debugger. In this case, it would take you directly to the problem: you're crashing with an access violation (Windows 0xc0000005) here:
void solve(solver *s) {
int n = s->N;
int next[2];
int ***sp = s->sol_ptr;
//find next empty space
if ((*sp)[0][0] == 0) { // <-- Access violation here: "sp" incorrectly initialized!
next[0] = 0;
next[1] = 1;
}
The underlying problem is that although sudoku_solver.N was initialized to "4" ... sudoku_solver.sol_ptr[0][0] is pointing to uninitialized memory.
PS:
Yes, it's very definitely "executing". It wouldn't crash if it didn't run ;)

Adding two numbers [1, 10^10000] as arrays of chars - C

I tackled the problem by first figuring out the length of two given numbers and aligning the one with less digits (if one exists) into a new array so that the ones, tens, hundreds etc. align with the bigger number's ones, tens, hundreds, etc.
Then I wanted to save the sum of each two aligned elements (with a mod of 10) into a new array while checking if the sum of digits is greater than 10 - just the basic sum stuff. Now the problem occurs with adding two elements into the aplusb integer and I've tried fixing it with writing
int aplusb = (lengthA[max-i]-'0') +(temp[max-i]-'0');
but it doesn't work. I'm stuck and I don't know what to do. Please help.
The whole code:
#include <stdio.h>
#include <math.h>
int main(){
char a[10000];
char b[10000];
scanf("%s %s", &a, &b);
char sum[10000];
int lengthA = 0;
int lengthB = 0;
int i = 0;
while(a[i]){
i++;
} lengthA = i;
i = 0;
while(b[i]){
i++;
} lengthB = i;
char temp[10000];
int aplusb;
int carry = 0;
int max = lengthA;
int difference = abs(lengthA - lengthB);
if(lengthA>lengthB){
for(i=0; i<lengthA; i++){
temp[i+difference]=b[i];
}
for(i=0; i<=max; i++){
aplusb = lengthA[max-i]+temp[max-i]; //<-- this is the problematic line
if(carry = 1) aplusb++;
if(aplusb>9){
carry = 1;
aplusb%=10;
}
sum[i]=aplusb;
}
}
for(i=0; i<=max; i++){
printf("%c", sum[i]);
}
/*
if(lengthB>lengthA){
max = lengthB;
for(i=0; i<lengthB; i++){
temp[i+difference]=a[i];
}
}*/
return 0;
}
Doing operations and storing on very large numbers is very akin to doing operations and storing polynomials, i.e. with x = 10. a0 + a1.10 + a2.10^2 ... + an.10^n.
There are many polynomial libraries on the Internet, where you could find inspiration. All operations on your very large numbers can be expressed in terms of polynomials. This means that by using base 2^8, or even base 2^63, instead of base 10 to internally store your large numbers you would greatly improve performance.
You must also normalize your coefficients after operations to keep them positive. Operations may result in a negative coefficient, That can easily be fixed, as it is very similar to borrowing after a subtraction, this means coefficients must be larger than your base by 1bit.
To convert back to base 10, you'd need to solve r (your result) for v (your value), such as r(10)=v(2^63). This has only one solution, if you enforce the positive coefficients rule.
[note] After thinking about it some more: the rule on positive coefficients may only be necessary for printing, after all.
Example: adding. no memory error checking
int addPolys(signed char** result, int na, const signed char* a, int nb, const signed char* b)
{
int i, nr, nmin, carry, *r;
nr = max(na, nb) + 1;
nmin = min(na, nb);
r = malloc(sizeof(signed char) * (na + nb + 1));
if (nb < na)
{
nr = nb;
}
for (i = 0; i < nmin; ++i)
{
r[i] = a[i] + b[i];
}
for (; i < na; ++i)
{
r[i] = a[i];
}
for (; i < nb; ++i)
{
r[i] = b[i];
}
r[nr - 1] = 0;
// carry - should really be a proc of its own, unoptimized
carry = 0;
for (i = 0; i < nr; ++i)
{
r[i] += carry;
if (r[i] > 10)
{
carry = r[i] / 10;
r[i] %= 10;
}
else if (r[i] < 0)
{
carry = (r[i] / 10) - 1;
r[i] -= (carry * 10);
}
else
carry = 0;
}
// 'remove' leading zeroes
for (i = nr - 1; i > 0; --i)
{
if (r[i] != 0) break;
}
++i;
*result = r;
if (i != nr)
{
*result = realloc(i * sizeof(signed char));
}
return i; // return number of digits (0 being 1 digit long)
}
That code is working now for any two positive numbers with up to ten thousand digits:
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(){
char chara[10000];
char charb[10000];
scanf("%s %s", &chara, &charb);
int lengthA = strlen(chara);
int lengthB = strlen(charb);
int max = lengthA;
if(lengthB>lengthA) max=lengthB;
int dif = abs(lengthA - lengthB);
//ustvari int tabele
int a[max];
int b[max];
int sum[max+1];
// nastavi nule
int i;
for(i=0; i<max; i++){
a[i] = 0;
b[i] = 0;
sum[i] = 0;
} sum[max] = 0;
//prekopiraj stevila iz char v int tabele &obrni vrstni red
for(i=0; i<lengthA; i++){
a[i] = chara[lengthA-i-1]-'0';
}
for(i=0; i<lengthB; i++){
b[i] = charb[lengthB-i-1]-'0';
}
int vsota;
int prenos = 0;
for(i=0; i<max; i++){
vsota = a[i]+b[i] + prenos;
if(vsota>=10) prenos = 1;
else if (vsota<10) prenos = 0;
sum[i]=vsota%10;
}
if(prenos==1){
sum[max] = 1;
for(i = max; i>=0; i--){
printf("%d", sum[i]);
}
} else {
for(i = max-1; i>=0; i--){
printf("%d", sum[i]);
}
}
return 0;
}

Balanced work load distribution?

I have N jobs with varied work loads that is to be distributed among n persons so that the work load is as balanced as possible.
e.g-we have to divide 5 jobs with work loads <1,2,3,4,5> between 3 persons. The best way would obviously be to distribute as follows:-
<1,4>,<2,3>,<5>.
Thus the problem is to minimize
z=abs(a-b)+abs(b-c)+abs(c-a)
where a, b, c are the workloads of the three persons.What would be the most efficient way to solve the problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int *insort(int *var, int elem)
{ // insert elem into sorted variable array var[1..n] (*var holds n)
int n = var ? *var : 0;
var = realloc(var, (1 + ++n) * sizeof *var);
if (!var) exit(1);
*var = n;
int i;
for (i = 1; i < n; ++i) if (elem < var[i]) break;
memmove(var+i+1, var+i, (n-i) * sizeof *var);
var[i] = elem;
return var;
}
main()
{ // distribute jobs characterized by workloads among n persons
int n, i, j, *jobs = NULL;
printf("number of persons? "); scanf("%d", &n);
printf("job workloads? ");
while (scanf("%d", &i) > 0) jobs = insort(jobs, i);
int *w, *work[n], load[n];
for (i = 0; i < n; ++i) work[i] = NULL, load[i] = 0;
if (n > 0 && jobs) do
{ // assign the most strenuous job to the least busy person
w = insort(work[0], j = jobs[(*jobs)--]);
j += load[0];
for (i = 1; i < n; ++i) if (load[i] > j) break;
memmove(load, load+1, --i * sizeof *load), load[i] = j;
memmove(work, work+1, i * sizeof *work), work[i] = w;
} while (*jobs);
for (i = 0; i < n; ++i, puts(""))
if (w = work[i]) do printf(" %d", w[(*w)--]); while (*w);
}
sample run:
number of persons? 3
job workloads? 1 2 3 4 5.
5
3 2
4 1

Resources