Changing code to make it parallel [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
#include <conf.h>
#include <kernel.h>
#include <stdio.h>
#define MAX_ITEMS 50
typedef long double LD;
int run_solve_equ();
void xmain(){
int pid;
pid = create(run_solve_equ, 20*INITSTK, INITPRIO, "B", 0);
resume(pid);
}
int solve_equ(LD b, int n, LD a[], int choosen[] ){
if ( n == 1 )
if (a[0] == b) {
choosen[0] = 1;
return 1;
} /* if */
else if (b == 0) {
choosen[0] = 0;
return 1;
} /* else if*/
else {
choosen[0] = 0;
return 0;
}
else /* n > 1 */
if (solve_equ(b, n-1, a, choosen)) {
choosen[n-1] = 0;
return 1;
} /* if */
else if (solve_equ(b - a[n-1],n-1, a, choosen)) {
choosen[n-1] = 1;
return 1;
} /* else if */
else{
choosen[n-1] = 0;
return 0;
}
} /* solve_equ */
LD a[MAX_ITEMS];
int choosen[MAX_ITEMS];
char pstr[200];
extern long int tod;
int run_solve_equ() {
int n, i, result;
LD b, sum;
printf("How many numbers? No more than %d:", MAX_ITEMS );
scanf("%d",&n);
puts("Enter b:");
scanf("%Lf",&b);
a[0] = 1;
for (i = 1; i < n; i++)
a[i] = a[i-1]*2;
result = 0;
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
result = solve_equ(b,n, a, choosen);
sprintf(pstr, "time = %ld\n", tod);
printf(pstr);
sprintf(pstr, "Solution for b = %Lf, n = %d, value = %d :\n", b,
n,result);
printf(pstr);
printf("\ni:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d",i);
printf(pstr);
} // for
printf("\na[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16.1Lf", a[i]);
printf(pstr);
} // for
printf("\nchoosen[i]:\n");
for (i = 0; i < n; i++) {
sprintf(pstr, "%-16d", choosen[i]);
printf(pstr);
} // for
printf("\n");
sum = 0;
for (i = 0; i < n; i++)
if (choosen[i]) {
sum += a[i];
sprintf(pstr, " + %-16.1Lf", a[i]);
printf(pstr);
} /* if */
sprintf(pstr, " = %-16.1Lf\n", sum);
printf(pstr);
return 0;
}
I need to change this program so the search will be "parallel" by two processes:
Each will search a n-1, the first user on a [n-1] and the other not.
the problem is to find a number in the array that all the number togother are equal to another number b !

Not an answer, but I do have some constructive comments for you.
Reading the above code hurts. It hurts my eyes and it hurts my brain. Why?
Variable Names are non-descriptive an often one letter (outside of I). b, n, a - I don't know what these are at a glance and I don't want to find out by understanding what you wrote. I bet you won't understand what you wrote next week either. Do everyone a favor and make the names better.
Please, please use a bit of white space between your "code thoughts". Your code looks like one long run-on sentence that also hides what it does.
Don't mix braced and non-braced code - especially when your indentation is not consistent. It is very, very difficult to follow your if logic as-is right now. Go ahead and waste a few bytes of hard disk space and perhaps .25 seconds adding braces or at least fixing your indents.
Write useful comments. /* if */ is a terrible comment and you do similar stuff everywhere. I know what an if is, but perhaps a quick not of what you are checking?
Don't mix globals and extern defines in the middle of your code. Keep them together and it makes it easier to remember what is global and what is not. This is the most minor offense though and others may disagree.
Anyways, a bit off topic for your question, which will more than likely close as you've put little effort into solving it yourself, but my comments may help you with future coding projects and will at least make it easier for others to help you going forward.

Related

Why can't I return the last value of the recursive fuction in C?

I've been trying to build a recursive function which calculates the max value, but even I can see the total value when I print in the function, I can't return the value to the main function. Can you tell me where do I do wrong? Thanks for help!
note : more explanation about what I ve been trying to build is : user defines an object and as long as user doesn't give the price, I keep asking what the object is..
small example :
Define the object:
Car
What is Car?:
4*Wheel+1*Frame
What is Wheel?:
2*Rim
What is Rim?
5.0
What is Frame?:
10.0
Total is : 50.0
Current code:
#include <stdio.h>
#include <stdlib.h>
#define INPUT_SIZE 101
void delete_space(char arr[])
{
int a, i, j, len;
for(a = 0; a < INPUT_SIZE; a++)
{
for(i = 0; i < INPUT_SIZE; i++)
{
if(arr[i] == ' ')
{
for(j = i; j < INPUT_SIZE; j++)
{
arr[j] = arr[j + 1];
}
}
}
}
}
double result(char input[], double coeff, double total)
{
/* if the input is number, num_of_obj is 0, if the input is object, num_or_obj is more than 0.
*/
int i, k = 1, num_of_obj = 0;
char temp_input[INPUT_SIZE];
char temp_input_1[INPUT_SIZE];
char x;
int* p;
double value;
p = (int*)calloc(1, sizeof(int));
p[0] = 0;
printf("What is %s:?\n", input);
scanf("%[^\n]s", temp_input);
getchar();
delete_space(temp_input);
for(i = 0; i < INPUT_SIZE; i++)
{
if(temp_input[i] == '*')
{
num_of_obj++;
}
}
if(num_of_obj == 0) // if the input is number.
{
sscanf(temp_input, "%lf", &value);
total = total + coeff * value;
printf("total : %lf", total);
return total;
}
if(num_of_obj > 0)
{
for(i = 0; i < INPUT_SIZE; i++)
{
if(temp_input[i] == '+')
{
p = (int*)realloc(p, (k + 1) * sizeof(int));
p[k] = i + 1;
k++;
}
}
for(i = 0; i < k; i++)
{
sscanf(&temp_input[p[i]], "%lf%c%[^+]s", &coeff, &x, temp_input_1);
result(temp_input_1, coeff, total);
}
}
printf("test");
return total;
}
int main()
{
double total = 0;
char input[INPUT_SIZE];
printf("Define the object :\n");
scanf("%[^\n]s", input);
getchar();
delete_space(input);
printf("total : %.2lf", result(input, 0, 0));
return 0;
}
I believe that the main issue is the recursive call: result(temp_input_1, coeff, total);, which is ignoring the returned result.
Two possible solutions: (1) do the aggregation in result OR (2) tail recursion. I'm not sure that this case fit into tail recursion (or that there are any benefits here). Consider removing the 'total' from result prototype, and doing the aggregation (over the 'components') in the loop.
double result(char input[], double coeff) {
double total ;
...
for(i = 0; i < k; i++)
{
sscanf(&temp_input[p[i]], "%lf%c%[^+]s", &coeff, &x, temp_input_1);
total += result(temp_input_1, coeff, total);
}
Side comment: Consider also removing the 'delete_space' function. I believe it does not property fix the string. Much easier to skip over the spaces in the scanf call.
Welcome to stackoverflow! I too am new here, but if you word your questions right, you'll get better answers. If this is a homework assignment, I highly recommend including that, it can be hard to follow descriptions.
So as a general rule of thumb, when writing C functions its best to use as few return statements as possible. But I too have difficulty with this.
It looks like your are checking for
is first condition met?
if not check next condition
should you be using if, if else, and else?
Also you have if statements with no else, generally needed, especially in a recursive function (you might be skipping over the next step after the last recursive call)
Hope this helps! Swamped with the end of the semester myself or else I would have attempted a solution!
You need three things to write a recursive method successfully:
A terminating condition, so that the method doesn't call itself forever,
Some work to do, and
A recursive call.
Consider the following code:
typedef struct node{
void* item;
struct node* next;
} Node;
int CountNodes(Node* list)
{
if (list == null) return 0;
return 1 + CountNodes(list.next);
}
This code works because it counts the current node plus all remaining nodes. The recursive call counts the next node and all remaining nodes. And so on.

Wrong output for prime numbers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
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.
Improve this question
#include <stdio.h>
int main()
{
int i, n, c, p;
printf("enter\n");
scanf("%d", n);
c = find(n);
if (c == 1)
{
printf("no. is not prime");
}
else
{
printf("no. is prime");
}
}
find(int n)
{
int i = 2, p;
while (i < n)
{
p = n % i;
printf("value of p%d", p);
if (p == 0)
{
return 1;
}
i = i + 1;
}
return 2;
}
....................................
Above program giving me 'not a prime number' output for all inputs...also the value of p is always zero and this shouldn't be the case...
Please help...badly stuck...
Your scanf() call must take the address of n. Furthermore you primality test fails for numbers smaller than 2. It is also better to return non-zero for true, zero otherwise, so that the value can directly be tested with if. And you should find a better name than find.
Try something like this:
#define TRUE 1
#define FALSE 0
int is_prime (int n)
{
int i;
if (n < 2)
return FALSE;
for (i = 2; i < n; i++) {
if (n % i == 0) {
return FALSE;
}
}
return TRUE;
}
int main()
{
int n;
printf ("enter number: ");
scanf ("%d", &n);
if (is_prime (n)) {
printf ("number is prime.\n");
}
else {
printf("number is not prime.\n");
}
return 0;
}
Various improvements are possible but I wanted to stay as close to your code as possible.
This looks like a student exercise so let me start by suggesting that the debugger is your friend. :)
Having said that, you may want to review the Sieve of Eratosthenes and leverage Wikipedia for a source of some good test content.
As already suggested, there are loads of potential improvements... I'd modify your "find" function to be more clear as follows:
bool IsPrime(unsigned int n)
{
unsigned int nCounter = 2;
while (n % nCounter++);
return (nCounter > n);
}
Prime's can't be negative and since you're asking a "TRUE/FALSE" question, the name and return type should enforce that contract.
Several issues:
scanf("%d", n); should be scanf("%d", &n); - you need to pass the address of n so scanf can update it (note that you risk a runtime error,
since the value of n most likely isn't a valid address value);
Implicit typing of functions such as find(int n) {...} is no longer supported as of the C99 standard, and it was never good practice to begin with. You should (and for C99 and later, must) provide a type specifier along with the function name in both function declarations and function definitions - int find( int n ) {...};
Similar to 2, a function declaration must be visible before a function is called; the simplest way to accomplish this is to move the function definition above the definition for main. If you don't want to do that, then you need to add the declaration int find(int n); somewhere before find is called.
Note that you can speed up the primality test in a couple of ways. First, you can skip testing against even factors; if a number is divisible by a multiple of 2, then it's divisible by 2, and you would have already checked for that. Secondly, you don't need to test all factors up to n - 1; you only need to test factors up to the square root of n. You can put that all together like so:
if ( n < 2 )
return 0; // zero indicates false
if ( n == 2 )
return 1; // non-zero indicates true
int result = n % 2;
for ( int i = 3; result && i * i <= n; i += 2 ) // loops as long as result
result = n % i; // is non-zero, only tests
// against odd numbers up to
return result; // sqrt(n)

Trying to turn the factorial part into another function

I have to begin my thanking you guys for the help. I am trying to turn the factorial part of the code into another function and was wondering if I needed to add everything within the
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int arrayIndx;
int accumulator;
int fact;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++)
{
individualDigit[length] = num % 10;
num /= 10;
}
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
fact = 1;
while(individualDigit[arrayIndx] > 0)
{
fact*= individualDigit[arrayIndx];
individualDigit[arrayIndx]--;
}
accumulator += fact;
}
if(accumulator == indx)
{
printf("%d ", accumulator);
}
}
return 0;
}
You program is badly designed. It is not indented, you are using variable names index, indx and idex which is confusing for the reader and would lead to nightmares for long term maintenance. Also the factorial computation would deserve to be in a function for better modularity.
But apart from that, your program does what you ask, correctly computes factorials and adds them in the accumulator variable. The only problem is that you never print that accumulator except for the last 2 cases (2 and 1) where n = n!.
Simply replace :
if (accumulator == indx)
{
printf("\n%d\n", indx);
}
with
printf("\n%d\n", accumulator);
and you will see your results.
If you want to store the sum of factorials in an array, you just have to declare int sumOfFact[26] = {0}; just before int individualDigit[50]; to define the array and initialize sumOfFact[0] to 1, and then add sumOfFact[indx] = accumulator; just before printing the accumulator.
To put the factorial part in a function, it is quite simple. First declare it above your main:
int ffact(int n);
the define it anywhere in your code (eventually in another compilation unit - a .c file - if you want)
inf ffact(int n) {
fact = 1;
while (n > 1) {
fact *= n--;
/* if (fact < 0) { fprintf(stderr, "Overflow in ffact(%d)\n", n); return 0; } */
}
return fact
}
I commented out the test for overflow, because I assume you use at least 32 bits int and fact(9) will not overflow (but fact(13) would ...)
The loop computing the sum of factorials becomes:
accumulator = 0;
for (arrayIndx = 0; arrayIndx < length; arrayIndx++)
{
accumulator += ffact(individualDigit[arrayIndx]);
}
printf("\n%d\n", accumulator);
Advantages for that modularity: it is simpler to separately test the code for ffact. So when things go wrong, you have not to crawl among one simple piece of code of more than 40 lines (not counting the absent but necessaries comments). And the code no longers clutters the individualDigit array.

Sorting array of integers C [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 7 years ago.
Improve this question
i'm a beginner c programmer studying computer science and i'm trying to create a sorting program to sort an array of integers although i keep getting wrong results, this is what i got so far:
#include <stdio.h>
#include <string.h>
#define TAM 9
int sort_array(int num1[],int num2[]);
int main(){
int i=0;
int num1[TAM] = {5,6,2,4,7,1,3,0};
int num2[TAM] = {0};
int * ptr_num2 = num2;
sort_array(num1,num2);
while(*ptr_num2 != '\0'){
printf("%c",*ptr_num2+48);
ptr_num2++;
}
putchar('\n');
return 0;
}
int sort_array(int num1[],int num2[]){
int min=256,max=0,i,j;
int * ptr_num1 = num1;
int * ptr_max = num1;
int * ptr_num2 = num2;
/* check for max */
while(*ptr_max != '\0'){
if(*ptr_max > max) max = *ptr_max;
ptr_max++;
}
for(i=0;i<TAM-1;i++){
/* check for min */
for(j=0;j<TAM-1;j++){
if(*ptr_num1 < min) min = *ptr_num1;
ptr_num1++;
num1[i] = max;
}
*ptr_num2 = min;
ptr_num2++;
}
return 0;
}
I've been banging my head for several hours on this already.
EDIT: Forgot to mention that some of these things might not make sense since i'm just experimenting with a few things.
I understand you do not know about the typical array sorts... Well, let me to introduce you to one of the more simple ones. Allthough it's usually not the most efficient one, it's the easiest one to understand, and considering the fact you are messing with little arrays and not databases, it will be just fine.
I am talking about good old Chum, our Bubble sort.
Bubble sort is a well known simple array sorting algorithm -
The logic is simple. You go over the whole array on pairs of two - I.e, Array[0] with Array[1], Array[1] with Array[2], etc...
Whenever you find that things are not the way they are supposed to be - in your case, The larger index number is bigger than the lower index number - you swap between them, until you reach an iteration where you passed through the whole array and didnt swap at all.
In case you didn't understand well, here's Pseudo code from wikipedia (OMG who the heck uses wikipedia i'm such a n00b):
procedure bubbleSort( A : list of sortable items )
n = length(A)
repeat
swapped = false
for i = 1 to n-1 inclusive do
/* if this pair is out of order */
if A[i-1] > A[i] then
/* swap them and remember something changed */
swap( A[i-1], A[i] )
swapped = true
end if
end for
until not swapped
end procedure
And here's some C code:
#include <stdio.h>
int main()
{
int array[100], n, c, d, swap;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (array[d] > array[d+1]) /* For decreasing order use < */
{
swap = array[d];
array[d] = array[d+1];
array[d+1] = swap;
}
}
}
printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%d\n", array[c]);
return 0;
}
Here again, btw, the credit is not for me:
http://www.programmingsimplified.com/c/source-code/c-program-bubble-sort
Hope this helped you, and good luck :)

why is my 3n+1 problem solution wrong

I have recently started reading "Programming Challenges" book by S. Skiena and believe or not I am kind of stuck in the very first problem.
Here's a link to the problem: 3n+1 problem
Here's my code:
#include <stdio.h>
long get_cycle(long input){
if (input == 1){
return 1;
}
else{
if (input & 1){
return 2 + get_cycle((3*input+1)>>1);
}
else{
return 1 + get_cycle(input >> 1);
}
}
}
long get_range_cycle(int k, int j){
int i;
int max = 0;
int current_cycle;
int to = k > j ? k : j;
int from = k < j ? k : j;
for (i=from; i<=to; ++i){
current_cycle = get_cycle(i);
if (current_cycle > max){
max = current_cycle;
}
}
return max;
}
int main(){
long p, q;
long re[100][3];
int i = 0;
while (scanf("%ld %ld",&p,&q) == 2){
re[i][0] = p;
re[i][1] = q;
re[i][2] = get_range_cycle(p,q);
++i;
}
int j;
for (j=0; j<i; ++j){
printf("%ld %ld %ld\n",re[j][0],re[j][1],re[j][2]);
}
}
what is wrong with my code? the input and out is exactly the same with sample.But the submission result is always run time error!
You're code seems to assume maximum 100 lines in the input file - the sample data they are testing on might be bigger? They make no explicit claim wrt the maximum set size of the input data.
I believe that the problem you seek answer for is in the answer #Elemental . If you fix that, however, your solution will time out.
What you should do is to build up a list of all answers between 0 and 1000000. This can be done in linear time (I will not give you the full answer).

Resources