Calculating displacement by getting previous position. (C) - c

I am trying to figure out how do I get previous position from the function that I wrote. I tried to solve it for hours but couldn't make it. Enemy's(N) initial position is (0,0) and every x and y values after that generate randomly. 'O' is my base and it is located in (6,6). The borders are 11x11. The problem is refresh_position function always calculate displacement by getting previus position as '0'. Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
void track_machine();
void refresh_position(int *X, int *Y, double *D, double *R);
void main()
{
track_machine();
}
void track_machine()
{
int x=0, y=0;
char op;
double D, R;
refresh_position(&x, &y, &D, &R);
for(int i=1; i<=11; i++)
{
for(int j=1; j<=11; j++)
{
if(i==x && j==y)
printf("N ");
else if(i==6 && j==6)
printf("O ");
else
printf(". ");
}
printf("\n");
}
printf("Enemies X position:%d\nY position:%d\nDisplacement:%f\nDistance to our camp:%f\nCommand waiting...:\n", x, y, D, R);
scanf(" %c", &op);
if(op=='R')
track_machine();
else if(op=='E')
main();
else
printf("\nERROR!\n");
}
void refresh_position(int *X, int *Y, double *D, double *R)
{
int x=*X, y=*Y, xD, yD, xR, yR;
srand(time(0));
while( (*X==0 || *X==6) || (*Y==0 || *Y==6) )
{
*X = rand()%11;
*Y = rand()%11;
}
xD=abs(*X-x);
yD=abs(*Y-y);
xR=abs(*X-6);
yR=abs(*Y-6);
*D = sqrt( (xD*xD) + (yD*yD) );
*R = sqrt( (xR*xR) + (yR*yR) );
}

I think, this is a kind of board game and board positions are numbered from 1 to 11. What I deduce from the while loop is, you do not want *X & *Y be '0' or '6'. However, using mod(11) w/o adding (increment) '1' will never produce a random result '11'. So, you'd better change that loop into a more efficient do-while, like;
do {
*X = rand() % 11 + 1;
*Y = rand() % 11 + 1;
} while((*X == 6) && (*Y == 6));
This way, rand() % 11 will produce a number b/w 0 - 10 (inclusive), then adding '1' will produce a number b/w 1 - 11 (inclusive). You will get rid of checking for '0' values.
Addressing your question about the code (tough not sure whether I've understood your question 100%); I think the problem arise from the function track_machine having no parameters. Initializing x & y in main and then passing those variables to the function via parameters will solve your issue (of course, if I've understood your question truly).
// main should be
int main()
{
int x = 1, y = 1;
track_machine(x, y);
}
// function decoration should be
void track_machine(int x, int y) {...}
// and your recursive call line should read as
if (op == 'R')
track_machine(x, y);

I didn't describe my problem good enough. Sorry for that but I found what I did wrong. The code prints 11 dots in both x and y direction. My goal was finding the distance between N (which is located randomly each 'R' command in 11x11 area) and O (which is my base located in 6,6) and finding the displacement every time N changes position when I give 'R' command. Here is the working code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
void track_machine();
void refresh_position(int *X, int *Y, double *D, double *R)
int main()
{
track_machine();
}
void track_machine()
{
int x=1, y=1;
char op;
double D, R;
srand(time(0));
D = 0;
R = 8.49;
while(1==1){
for(int i=1; i<=11; i++){
for(int j=1; j<=11; j++){
if(i==x && j==y)
printf("N ");
else if(i==6 && j==6)
printf("O ");
else
printf(". ");
}
printf("\n");
}
printf("Enemies X position:%d\nY position:%d\nDisplacement:%f\nDistance to our camp:%f\nCommand waiting...:\n", x, y, D, R);
scanf(" %c", &op);
if(op=='R')
refresh_position(&x, &y, &D, &R);
else if(op=='E'){
main();
break;
}
else
printf("\nERROR!\n");
}
}
void refresh_position(int *X, int *Y, double *D, double *R)
{
int x=*X, y=*Y;
do {
*X = rand()%11+1;
*Y = rand()%11+1;
} while((*X == 6) || (*Y == 6));
*D = sqrt( ((*X-x)*(*X-x)) + ((*Y-y)*(*Y-y)) );
*R = sqrt( ((*X-6)*(*X-6)) + ((*Y-6)*(*Y-6)) );
}
I can't use parameters for track_machine because I'm not allowed to :). Every time I give 'R' it refreshes the location of 'N' and calculates new 'D' and 'R' values as long as I don't give 'E' command. Actually it is not the whole code this is just a small part of it. When it returns to main it asks for 'op' to choose other functions in switch case. I hope I explained it enough this time. Thanks for help though!

Related

Find the distance of the closest pair of points ( c )

#include <stdio.h>
#include <math.h>
typedef struct
{
int x,y;
}point;
double distance(point p1[], point p2[], int i)
{
double d = sqrt((pow(p2[i+1].x-p1[i].x,2)) + (pow(p2[i+1].y-p1[i].y,2)));
return d;
}
int main()
{
int size,i;
double d;
printf("Enter number of point: ");
scanf("%d",&size);
point p[size];
for(i=0;i<size;i++)
{
printf("Enter point %d: ",i+1);
scanf("%d,%d",&p[i].x,&p[i].y);
}
d = distance(p[0].x,p[0].y,0);
for(i=0;i<size-1;i++)
{
if( d > distance(p[i+1].x,p[i+1].y,i))
{
d = distance(p[i+1].x,p[i+1].y,i);
}
}
printf("Closest pair distance = %.4lf",d);
}
I have been trying to finish this homework for a while and I'm not sure on how to fix this.
The output supposed to look like this:
This is what I got:
First, I think your distance function should get two points, and not two points arrays. you also don't need to pass the index. this way your function will only do what it should do: calculate the Euclidean distance.
double distance(point p1, point p2)
{
double d = sqrt(pow(p2.x-p1.x,2) + pow(p2.y-p1.y,2));
return d;
}
Second, in your main function, do you want to check only the distance between consecutive points or between any point? I think you want the second option but decide for yourself:
first option:
for(i=0;i<size-1;i++)
{
if( d > distance(p[i],p[i+1]))
{
d = distance(p[i],p[i+1]);
}
}
second option:
for(i=0;i<size-1;i++)
{
for (j=i+1;j<size;j++)
{
if( d > distance(p[i],p[j]))
{
d = distance(p[i],p[j]);
}
}
}
notice I set j=i+1 because first, i don't want to calculate distance(p[i],p[i]) because that will always be 0 and that is the minimal value distance can return. secondly it's sufficient to test only for j>i values because distance(p[i],p[j])==distance(p[j],p[i])
I hope that cover everything
I have done some changes. Read the comments marked with // CHANGE HERE to understand the changes.
#include <stdio.h>
#include <math.h>
#include <float.h>
#include <stdlib.h>
typedef struct
{
// CHANGE HERE: double instead of int
double x, y;
} point;
// CHANGE HERE: just accept two points whose distance needs to be calculated
double distance(point p1, point p2)
{
return sqrt((pow(p1.x - p2.x, 2)) + (pow(p1.y - p2.y, 2)));
}
int main()
{
int size, i, j;
double d;
printf("Enter number of points: ");
scanf("%d", &size);
// CHANGE HERE: use malloc for variable sized arrays
point* p = malloc(size * sizeof(point));
for (i = 0; i < size; i++)
{
// CHANGE HERE: read double instead of int
printf("Enter point %d: ", i + 1);
scanf("%lf,%lf", &p[i].x, &p[i].y);
}
// CHANGE HERE: store a high value by default
d = DBL_MAX;
for (i = 0; i < size - 1; i++)
{
// CHANGE HERE: to get the exact pair of points with closest distance
// you need to compare the distance of each point with the rest
for (j = i + 1; j < size; j++)
{
// CHANGE HERE: pass previous and current point to distance
double dist = distance(p[i], p[j]);
if (d > dist)
{
d = dist;
}
}
}
printf("Closest pair distance = %.4lf", d);
// CHANGE HERE: don't forget to free malloc()ed memory
free(p);
return 0;
}
As mentioned by #tstanisl, you can also use hypot function present in math.h, like:
double distance(point p1, point p2)
{
return hypot(p1.x - p2.x, p1.y - p2.y);
}

function that the user inputs coordinates x,y and find if the coordinates are inside the area of an given rectangle c

#include <stdio.h>
char dentroRetangulo(int v1x, int v1y, int v2x, int v2y, int x, int y);
int main()
{
int a, b, c, f,d,g,x,y;
char D, h;
printf("== Coordinates of a rectangle ==\n");
printf("Inform the coordinates of the left inferior corner : \n");
scanf("%d %d", &a, &b);
printf("Inform the coordinates of the superior right corner: \n");
scanf("%d %d", &c, &d);
printf("=== points ===\n");
printf("inform the coordinates of the point (x,y)\n");
scanf("%d %d", &f, &g);
h = dentroRetangulo(a,b,c,d,f,g);
if(h == D)
{
printf("O ponto(%d, %d) encontra-se dentro do retangulo", x, y);
}
return 0;
}
char dentroRetangulo(int v1x, int v1y, int v2x, int v2y, int x, int y)
{
char D;
char B;
char F;
if(x>v1x && x<v2x || y> v1y && y<v2y)
{
return D;
}
so basically, this function is about of checking if a point is inside of a rectangle with the inferior corner x,y coordinates being v1x and v1y, and the superior coordinates v2x and v2y, and in the main function the user is supposed to input x and y coordinates to verify if they are inside it, i'm kinda of a newbie in C, but i already lost 1 entire day trying to find out what i did wrong here and idk maybe i'm too stupid to not see what is going on wrong here
The posted code has some issues, but the main problem seems to arise from some basic misunderstandings.
// The following will declare, but WON'T initialize two variables
// of type 'char'. Here, D, is the NAME of the variable, not its content,
// which is indeterminated.
char D, h;
// Here h is assigned the value returned by OP's function, which has the
// exact same issue noted before. Its value will still remain indeterminated.
h = /* ... */;
// Comparing two variables with indeterminated values has undefined behavior.
if ( h == D ) { /* ... */ }
If the intent is to write a function that returns a char value of 'D' when a point is inside a rectangle or 'F' otherwise (maybe 'B' if it's on one of the edges), the following could be a possible implementation.
typedef struct point_s
{
int x, y;
} Point;
char point_rectangle_intersection(Point bottom_left, Point top_right, Point p)
{
// Check if the point is outside.
if ( p.x < bottom_left.x || p.x > top_right.x ||
p.y < bottom_left.y || p.y > top_right.y )
return 'F';
// Check if the point is on one of the edges.
if ( p.x == bottom_left.x || p.x == top_right.x ||
p.y == bottom_left.y || p.y == top_right.y )
return 'B';
// The point is inside.
return 'D';
}
You are trying too much in a single line... this one is too complex:
if(x>v1x && x<v2x || y> v1y && y<v2y)
and it's also wrong. It should be:
if(x>v1x && x<v2x && y> v1y && y<v2y)
But avoid such statements...
Keep things simple by writing more code lines.
But first notice that a function like this should return 0 (aka false) when the point is outside and 1 (aka true) when it's inside.
So to keep it simple do:
int dentroRetangulo(int v1x, int v1y, int v2x, int v2y, int x, int y)
{
if (x < v1x) return 0; // If the point is to the left, return 0
if (x > v2x) return 0; // If the point is to the rigth, return 0
if (y < v1y) return 0; // If the point is below, return 0
if (y > v2y) return 0; // If the point is above, return 0
return 1; // The point is inside, return 1
}
One simple check on each line makes your code more simple.
And in main call it like
if(dentroRetangulo(a,b,c,d,f,g))
{
printf("O ponto(%d, %d) encontra-se dentro do retangulo", f, g);
}

Recursive exponentiation

so I have to write a recursive algorithm for exponentiation and I have to use this to make the algorithm faster: and then I'd have to figure out how many time multiplication is happening. I wrote it, but I am not sure if I am right - also I need some help with figuring out the multiplication part.
#include <stdio.h>
#include <math.h>
double intpower(double x, int n)
{
double result;
if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2);}
if(n>1&&n%2==0) {result=intpower(x,n/2)*intpower(x,n/2);}
if(n==1) return x;
else return result;
}
int main()
{
int n;
double x,result;
printf("x\n");
scanf("%lf", &x);
printf("n\n");
scanf("%d", &n);
printf("result = %.2f\n", intpower(x,n));
return 0;
}
The inductive definitions are saying
If k is even, then x^k = [ x^(k/2) ] ^ 2
If k is odd, then x^k = x * [ x^(floor(k)/2) ] ^ 2
With these it's a bit easier to see how to arrange the recursion:
#include <stdio.h>
double int_pwr(double x, unsigned k)
{
if (k == 0) return 1;
if (k == 1) return x; // This line can be omitted.
double y = int_pwr(x, k/2);
return (k & 1) ? x * y * y : y * y;
}
int main(void)
{
double x;
unsigned k;
scanf("%lf%u", &x, &k);
printf("x^k=%lg\n", int_pwr(x, k));
return 0;
}
I've changed types to be a bit more logical and saved an exponential (in k) amount of work that the OP's solution does by making two recursive calls at each level.
As to the number of multiplications, it's pretty easy to see that if k's highest order bit is 2^p (i.e. at position p), then you'll need p multiplications for the repeated squarings. Another way of saying this is p = floor(log_2(k)). For example if k=4=2^2, you'll square the square to get the answer: 2 multiplications. Additionally you'll need q-1 more, where q is the number of 1's in k's binary rep. This is the number of times the check for "odd" will be true. I.e. if k = 5 (which has 2 bits that are 1's), you'll square the square and then multiply the result by x one more time. To summarize, the number of multiplications is p + q - 1 with p and q as defined above.
To figure out how many times multiplication is happening, you could count them in intpower().
static int count = 0;
double intpower(double x, int n) {
double result;
if(n>1&&n%2!=0) {result=x*intpower(x,(n-1)/2)*intpower(x,(n-1)/2); count += 2;}
if(n>1&&n%2==0) {result=intpower(x,n/2)*intpower(x,n/2); count++;}
if(n==1) return x;
else return result;
}
int main() {
int n;
double x,result;
printf("x\n");
scanf("%lf", &x);
printf("n\n");
scanf("%d", &n);
mcount = 0;
printf("result = %.2f\n", intpower(x,n));
printf("multiplcations = %d\n", mcount);
return 0;
}
Try this
double intpower(double x, int n)
{
if(n == 0) return 1;
if(n == 1) return x;
if(n%2!=0)
{
return x*intpower(x,(n-1));
}
else
{
x = intpower(x,n/2);
return x*x;
}
}
or you can reduce your function to one line
double intpower(double x, int n)
{
return n == 0 ? 1 : n%2 != 0 ? x*intpower( x, (n-1) ) : (x = intpower(x, n/2), x*x);
}

My_sine: what is wrong with my function? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Okay, so I have tried everything I could think of and haven't been able to figure out how to get this program working. I have tested all the functions used in the main, but included them anyway just in case there is some bug in them. More than likely though, I believe my mistake is in the main.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265359
double int_power(double x, int e);
int main()
{
int my_factorial(int n);
double my_sine_taylor(double x);
double my_sine(double x);
double mod_two_pi(double x);
double get_double(void);
void safeGetString(char arr[], int limit)
char arr[255];
double x,y,ans;
printf("Enter a number: ");
safeGetString(arr[255],255);
my_sine(mod_two_pi(get_double()));
printf("The sine is %f \n", ans);
return 0;
}
/*
int_power should compute x^e, where x is a double and e is an integer.
*/
double int_power(double x, int e)
{
int i = 0;
double ans = 1;
while(i <= e)
{
ans = ans*x;
i++;
}
return ans;
}
/*
my_factorial will find the factorial of n
*/
int my_factorial(int n)
{
int i = n;
int ans = 1;
while(i > 0)
{
ans = ans*i;
i = i-1;
}
return ans;
}
/*
my_sine_taylor computes the approxmiation
of sin(x) using the taylor series up through x^11/11!
*/
double my_sine_taylor(double x)
{
return x - int_power(x,3)/my_factorial(3) + int_power(x,5)/my_factorial(5) -
int_power(x,7)/my_factorial(7) + int_power(x,9)/my_factorial(9) -
int_power(x,11)/my_factorial(11);
}
/*
my_sine(x) should return a very good approximation of sin(x).
It should first reduce x mod 2pi and then map the result into the
upper right quadrant (where the taylor approximation is quite accurate).
Finally, it should use my_sine_taylor to compute the answer.
*/
double my_sine(double x)
{
double ans;
if (x >= 0 && x <= PI/2){
ans = my_sine_taylor(x);
} else if (x > PI/2 && x <= PI){
x=PI-x;
ans = my_sine_taylor(x);
} else if (x > PI && x <= 3*(PI/2)){
x = x-PI;
ans = -(my_sine_taylor(x));
} else {
x=2*PI-x;
ans = -(my_sine_taylor(x));
}
}
/*
mod_two_pi(x) should return the remainder when x
is divided by 2*pi. This reduces values like
17pi/2 down to pi/2
*/
double mod_two_pi(double x)
{
int y;
y = floor(x/(2*PI));
x = x - 2*PI*y;
return x;
}
/*
get_double and safeGetString are used to get floating point
input from the user
*/
double get_double(void)
{
double x;
char arr[255];
x=atof(arr);
}
void safeGetString(char arr[], int limit)
{
int c, i;
i = 0;
c = getchar();
while (c != '\n'){
if (i < limit -1){
arr[i] = c;
i++;
}
c = getchar();
}
arr[i] = '\0';
}
oh my... where to begin?
Let's see...
You have this function:
double get_double(void)
{
double x;
char arr[255];
x=atof(arr);
}
Which you call like this:
my_sine(mod_two_pi(get_double()));
So you're not sending it anything, but you're expecting to get some meaningful value. Basically, arr[255] is not initialized, so it holds garbage. You're taking this garbage and converting it to a float with atof, but that doesn't do anything.
If I had to guess, I'd say that this is what's really breaking your program. The rest of what I wrote below is just commentary.
For some reason, you're declaring all of these functions inside your main. I don't think this should break anything, but it sure is bad coding style.
my_sine_taylor calculates using a 6-element taylor approximation of the sine. Are you sure you need that accuracy? 11! is pretty large, and certain numbers to the 11th power can also be pretty large. You may be introducing unnecessary rounding or overflow errors with this.

Help implementing Least Squares algorithm in C [was: want to find the square root of an array]

the formula is pretty complicated. the numerator is num and the denominator is den, in the formula there is a root on the denominator so i have putted den in sqrrt() but sqrrt only accepts doubles
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define LEN 11
// for the following set of x and y find r by the formula ..
float sum(float arr[]);
void main(void)
{ int i;
float x[]={43.22,39.87,41.85,43.23,40.06,53.29,53.29,54.14,49.12,40.71,55.15};
float y[]={102.43,100.93,97.43,97.81,98.32,98.32,100.07,97.08,91.59,94.85,94.6};
float num,den[LEN],r[LEN],xy[LEN],x2[LEN],y2[LEN];
for(i=0;i<LEN;i++)
{
x2[i]=x[i]*x[i];
y2[i]=y[i]*y[i];
xy[i]=x[i]*y[i];
}
num=sum(xy)-sum(x)*sum(y);
for(i=0;i<LEN;i++)
{
den[i]=((LEN*sum(x2)-(sum(x))*(sum(x)))*(LEN*sum(y2))-(sum(y2))*(sum(y2)));
r[i]=num /sqrt(den); /*<----------the problem is here-----> */
}
printf("%f",r);
getch();
}
float sum(float arr[])
{
int i;
float total=0;
for(i=0;i<=LEN;i++)
{
total+=arr[i];
}
return total;
}
Out of sheer boredom I have fixed your code. It is still ugly and extremely inefficient but compiles and should work. I'll leave you or someone else to make it decent.
#include <stdio.h>
#include <math.h>
#define LEN 11
// for the following set of x and y find r by the formula ..
float sum(float arr[]);
int main(void)
{ int i;
float x[]={43.22,39.87,41.85,43.23,40.06,53.29,53.29,54.14,49.12,40.71,55.15};
float y[]={102.43,100.93,97.43,97.81,98.32,98.32,100.07,97.08,91.59,94.85,94.6};
float num,den,r[LEN],xy[LEN],x2[LEN],y2[LEN];
for(i=0;i<LEN;i++)
{
x2[i]=x[i]*x[i];
y2[i]=y[i]*y[i];
xy[i]=x[i]*y[i];
}
num=LEN*sum(xy)-sum(x)*sum(y);
den = (LEN*sum(x2)) - sum(x)*sum(x);
float alpha = sum(y)/LEN - (num/den)*sum(x)/LEN;
printf("beta = %f, alpha = %f\n", num/den, alpha);
for(i=0;i<LEN;i++)
{
float term = y[i] - alpha - (num/den)*x[i];
r[i] = (term*term);
printf("%f",r[i]);
}
}
float sum(float arr[])
{
int i;
float total=0;
for(i=0;i<=LEN;i++)
{
total+=arr[i];
}
return total;
}
To be consistent with the rest of the code, you should presumably be writing:
r[i] = num / sqrt(den[i]);
However, the calculation is not one I recognize. The body of the second loop is going to produce the same result for each value in den and therefore also in r, which is probably not what the question asked for.
You need to give the index den[i] at the denominator....instead in your code you have just passed the base address!
r[i]=num /sqrt(den[i]);
If this is what you want to achieve, which is quite unclear.

Resources