I was trying to solve a programming problem from a website and got time limit exceed. Now I'm trying to change some parts of my code where I use C++ string to C style strings.
Here is a part from my code that I wanted some advice:
x1 = X1 + X2 + X3;
x2 = X1 + X3 + X2;
x3 = X2 + X1 + X3;
x4 = X2 + X3 + X1;
x5 = X3 + X2 + X1;
x6 = X3 + X1 + X2;
Before, all of those variables above were C++ strings, now I have changed the uppercase ones to C-style, so those assignments are no longer valid...
What would be the fastest way to initialize the lower-case ones?
x1 = X1;
x1 += X2;
x1 += X3;
or
char buffer[20]; //would use x1 instead of a buffer if the answer to the second question
//is to convert it(x1) to C-style
strcpy(buffer, X1);
strcat(buffer, X2);
strcat(buffer, X3);
x1 = buffer;
the only use for the lowercase ones is in this comparison:
if(current == x1 || current == x2 || current == x3 || current == x4 || current == x5 || current == x6)
where 'current' is C++ string (And this one I won't change because I'm updating its value through elements inside a container)
this IF is going to be executed MANY times, so I want to know if it is better to let x1 ... x6 as C++ strings (I suppose if I compare C++ string with a C-style string it will call a constructor from C++ string and pass the C-style as argument before the comparison).
EDIT:
Reformulating: I what I want to know in the second is:
When I make a comparison like this:
string st = "something";
char st2[20] = "other thing";
if(st == st2)
Is it going to call the constructor string(st2) and the compare constructed string to the one at the left? Lets say I do this comparison 500000x, would it be faster if st2 were already a C++ string?
EDIT2: The complete code is here
If you want speed, don't create a string just in order to do a comparison; especially, don't create six strings since you might sometimes only need one or two of them. It's not relevant whether they are C strings or C++ strings.
Do you know how long X1, X2 and X3 are? It's easy enough to find out, if not. Assuming you do, what you want to know is something like:
if ( current.compare(0, lenX1, X1) == 0 &&
( current.compare(lenX1, lenX2, X2) == 0
&& current.compare(lenX1+lenX2, lenX3, X3) == 0
|| current.compare(lenX1, lenX3, X3) == 0
&& current.compare(lenX1+lenX3, lenX2, X2) == 0)
|| current.compare(0, lenX2, X2) == 0 &&
( current.compare(lenX2, lenX1, X1) == 0
&& current.compare(lenX2+lenX1, lenX3, X3) == 0
|| current.compare(lenX2, lenX3, X3) == 0
&& current.compare(lenX2+lenX3, lenX1, X1) == 0)
|| current.compare(0, lenX3, X3) == 0 &&
( current.compare(lenX3, lenX1, X1) == 0
&& current.compare(lenX3+lenX1, lenX2, X2) == 0
|| current.compare(lenX3, lenX2, X2) == 0
&& current.compare(lenX3+lenX2, lenX1, X1) == 0))
Your version is more readable, of course, and mine might have typos.
I suspect that this, too, is unnecessary; you need to reexamine your design. Why are you using concatenated strings instead of, for example, tuples of small integers?
Related
My code tries to check if there is a solution to unknown value n in this equation:
x1 + nv1 = x2 + nv2
with given inputs x1, v1, x2, v2 with input for x1 v1 x2 v2. So that I can tell "YES" if there is a value that meets in the same value for both sides of the equation.
n is addressed as output in my code.
For curious here is the problem link
string kangaroo(int x1, int v1, int x2, int v2) {
string output;
int x3;
int v3;
x3 = x1-x2;
v3 = v2-v1;
int div = x3/v3;
int remain = x3%v3;
if(div > 0 && remain == 0){
output = "YES";
}else{
output = "NO";
}
return output;
}
My code works but it raises runtime error where x1 v1 x2 v2 are 43 2 70 2 which is too big for my solution. I am asking what possible improvements can be implemented for my case?
here is my resolution to this problem
if(x1<x2 && v1<v2){
return "NO";
}else{
if(v1!=v2 && ((x2-x1)%(v1-v2)==0)){
return "YES";
}else{
return "NO";
}
}
As a result:
1. check if x1,x2 and v1,v2 values are creating any unwanted result
(x1-x2 and v1-v2 are negative then this is unwanted)
2. check for divider not be zero (if v1 != v2, no divide by zero
situation)
Regards.
You are receiving runtime_error which indicates this error can only be detected during runtime.
int div = x3/v3;
Here you have to make sure v3 is not zero.
You should study math, linear algebra, in more detail. For v1 = v2, any value of these variables will result in a runtime error because you will be dividing by zero.
The system of equations is unsolvable for v1 = v2 case.
I want to compute a variable X=x1+x2+x3. x1, x2 and x3 have either the values 1 or 0. I recoded system missings to -77. There are some conditions which should be met.
1) If there is a missing value in either x1,x2 or x3, then it should be ignored if one or two of the other variables have the value 1. So the sum should be calculated although there is a missing value but only if there is at least one 1 (Eg. X = x1 + x2 + x3 = 0 + missing + 1 = 1)
2) If there is a missing value in either x1, x2 or x3, then it should not be ignored if there is no 1 at all and the sum should not be calculated. (Eg. X = x1 + x2 + x3 = 0 + missing + missing = missing).
I tried to make a loop with IF but it won't work and I just can't figure out why.
COMPUTE X =SUM(x1, x2, x3).
IF (x1=-77 AND x2~=1 AND x3~=1) X=999.
IF (x2=-77 AND x1~=1 AND x3~=1) X=999.
IF (x3=-77 AND x1~=1 AND x2 ~=1)X=999.
EXECUTE.
These are the returned results:
when x1=1, x2 = 0, x3=-77 then X=1. (That is the result I want.
The problem arises when x1=-77, x2=0, x3=0 because then X=0 and not 999 as I want it to be.
I think that with the loop above I am close to the result but something is missing.
Below I post some other loops I made, but neither did work and I think the one above is the closest to the right answer.
Thank you so much for your help and happy easter!
Cheers desperate Ichav :)
COMPUTE X = x1 + x2 + x3.
RECODE X (SYSMIS=-77).
IF ((X = -77 AND x1 = 1) OR (X = -77 AND x2 = 1) OR (X = -77 AND x3 = 1)) X =1.
EXECUTE.
Here X is always returned as -77.
This is to create some sample data to work on:
data list list/x1 x2 x3.
begin data
1 0 -77
0 -77 0
0 0 0
1 0 1
end data.
MISSING VALUES x1 x2 x3 (-77).
As you can see this is assuming -77 was defined as a missing value - otherwise calculating sum(x1, x2, x3) will fail.
COMPUTE X=SUM(x1, x2, x3).
if X=0 and nmiss(x1, x2, x3)>0 X=999.
Now - if there were no 1 values, the sum is 0. If the sum is zero and there were any (more than 0) missing values involved - the sum is changed to 999.
If you somehow calculated X indirectly without turning -77 into a missing value, you would be able to use the value -77 in if statements (as you tried before). An easier way to do it then:
if X=0 and any(-77, x1, x2, x3) X=999.
I have an assignment in codeforces which says:
Like all problem solvers, Ebram loves eating crepe! As we all know, crepe usually served in a triangular shape. Now Ebram wants to know how large can a crepe side be! So he tries to draw a triangle on a plane using three points and calculate the maximum length of the three sides of the triangle. But sometimes he falls asleep as he has been busy with the team preparing the training problems! As a result, the three points he uses may not form a triangle that could represent a piece of crepe! A triangle can represent a piece of crepe only if it has a positive area. So you are here to help Ebram! Given the coordinates Ebram used, determine whether they form a triangle that could represent a piece of crepe or not.
Input:
Three integer coordinates (X,Y) that represent the three points Ebram used. Each point on a separate line.
Output: If the points form a triangle that can represent a piece of crepe, print the square of the maximum length of the three sides of the triangle. Otherwise print "Poor boy"
Examples
input
1 1
3 1
3 9
output
68
input
-10 8
9 100
3 8
output
8825
input
7 3
3 3
19 3
output
Poor boy
Here is my code that I used:
#include <iostream>
#include <cmath>
using namespace std;
int main () {
double x1,y1,x2,y2,x3,y3;
double area;
double s1,s2,s3;
double slope1, slope2;
cin >> x1 >> y1;
cin >> x2 >> y2;
cin >> x3 >> y3;
slope1 =((y2-y1)/(x2-x1));
slope2 =((y3-y2)/(x3-x2));
area = 0.5*abs(((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)));
if (slope1!=slope2 && (area)!=0){
s1 = sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
s2 = sqrt(((x2-x3)*(x2-x3))+((y2-y3)*(y2-y3)));
s3 = sqrt(((x1-x3)*(x1-x3))+((y1-y3)*(y1-y3)));
if (s1 > s2 && s1 > s3)
cout<<s1*s1<<endl;
if (s2 > s1 && s2 > s3)
cout<<s2*s2<<endl;
if (s3 > s1 && s3 > s2)
cout <<s3*s3<<endl;
}
else
cout <<"Poor boy";
return 0;
}
First I find the slope1 and slope2 to check if the three points aren't at the same line. So If they're not equal it forms a triangle (crepe).
Using this:
slope1 =((y2-y1)/(x2-x1));
slope2 =((y3-y2)/(x3-x2));
Then I wrote a relation to find the area of triangle using this formula:
area = 0.5*abs(((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)));
Finally I put the if statements to find if it is a triangle or not and find the length of each side of the triangle then find the maximum length and print the square of it.
if (slope1!=slope2 && (area)!=0){
s1 = sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)));
s2 = sqrt(((x2-x3)*(x2-x3))+((y2-y3)*(y2-y3)));
s3 = sqrt(((x1-x3)*(x1-x3))+((y1-y3)*(y1-y3)));
if (s1 > s2 && s1 > s3)
cout<<s1*s1<<endl;
if (s2 > s1 && s2 > s3)
cout<<s2*s2<<endl;
if (s3 > s1 && s3 > s2)
cout <<s3*s3<<endl;
}
else
cout <<"Poor boy";
return 0;
}
I tested the code in my compiler and it runs the i/o shown in the example perfectly fine. I submitted the code on codeforces but I stuck wrong answer at test 8 I don't know why?, and my code runs inputs and outputs fine. I will be very pleased if you help guys.
As in Sani's answer, I recommend calculating the rise and run between each pair of points:
rise1 = y2 - y1
rise2 = y3 - y2
rise3 = y1 - y3
run1 = x2 - x1
run2 = x3 - x2
run3 = x1 - x3
Also the same, I recommend checking whether any two points are coincident. Note that this is equivalent to what Sani's code is checking:
if (rise1 = run1 = 0) or (rise2 = run2 = 0) or (rise3 = run3 = 0) then
print "Poor Boy"
return 0
Now, similar to Sani, we move on to checking whether the points are on a line. However, we can simplify the conditions to check somewhat. Note that, if no two points are on a vertical line, then the three points are on one line if the slopes between any two points are equal. That is, m1 = m2, m2 = m3, or m3 = m1, equivalently. We can check whether m1 = m2. This is true when rise1/run1 = rise2/run2, which is safe since we assume no points are on a vertical line. We can rearrange this to rise1 * run2 = rise2 * run1, again safely. If no two points are on a vertical line, this is the only check we need.
What if two points are on a vertical line? Then at least one of run1 and run2 will be zero. However, because we have already guaranteed no two points are coincident, we can be absolutely sure that if either of these is zero, the corresponding rise is non-zero. There are two other cases (besides no two points being on a vertical line):
Exactly two points are on a vertical line. Then either run1 or run2, but not both, are zero. Without loss of generality, assume run1 is zero. Then the condition rise1 * run2 = rise2 * run1 simplifies to rise1 * run2 = 0. Because we know rise1 is not zero, this is satisfied only if run2 = 0, which contradicts our assumed case. This means that, in this case, the condition we derived earlier will produce the correct result and identify the points as not being on the same line.
Three points are on a vertical line. Then both run1 and run2 are zero. Then the condition rise1 * run2 = rise2 * run1 simplifies to 0 = 0, which is always true. In this case, the condition will produce the correct result and identify three points as being on the same line.
Because the condition we derived for the case of no two points on a vertical line happens to produce the correct result for all other possible cases, we can use it in all cases (under the assumption no two points are coincident). Therefore, we don't need to check anything except rise1 * run2 = rise2 * run1:
if rise1 * run2 = rise2 * run1 then
print "Poor Boy"
return 0
Now we know we have a triangle and need to return the largest of the three sides. We need the sum of squared differences of respective coordinates. Luckily, we already have the coordinate differences, so:
d1 = (rise1 * rise1) + (run1 * run1)
d2 = (rise2 * rise2) + (run2 * run2)
d3 = (rise3 * rise3) + (run3 * run3)
return max(d1, d2, d3)
Your biggest problem is that you keep getting division by 0 on inputs where the denominator is 0 when calculating the slope. I.e. Points (3, 4), (3, 5) and (5, 6) will yield -1/0.
Another thing is that you are "over-complicating" things.
This is a step by step example for clarity how to approach this (I.e. not optimal code):
// Check if any two points are the same. I.e. no triangle
if (x1 == x2 && y1 == y2 || x1 == x3 && y1 == y3 || x2 == x3 && y2 == y3) {
cout << "Poor boy";
return 0;
}
// Check if all points are on the same horizontal or vertical line
if (x1 == x2 && x1 == x3 || y1 == y2 && y1 == y3) {
cout << "Poor boy";
return 0;
}
// Calculate the nominators and denominators
nominator1 = y2-y1;
denominator1 = x2-x1;
nominator2 = y3-y2;
denominator2 = x3-x2;
nominator3 = y1-y3;
denominator3 = x1-x3;
// Calculate the slopes, if possible.
if (denominator1 == 0) slope1 = 0;
else slope1 = nominator1 / denominator1;
if (denominator2 == 0) slope2 = 0;
else slope2 = nominator2 / denominator2;
if (denominator3 == 0) slope3 = 0;
else slope3 = nominator3 / denominator3;
// Check if the three points form a triangle or a straight line.
// I.e. if all slopes are the same, it is a line.
if ((slope1 == slope2 && slope1 == slope3)) {
cout << "Poor boy";
return 0;
}
// Calculate the square of the length of each side
// (No abs is needed since a square of negative numbers is positive.)
// (Also no sqrt is needed since we're only interrested in the square of the longest side.)
side1 = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
side2 = (x3-x2)*(x3-x2) + (y3-y2)*(y3-y2);
side3 = (x1-x3)*(x1-x3) + (y1-y3)*(y1-y3);
// Note: This can be used instead which is the same calculation:
// side1 = denominator1 * denominator1 + nominator1 * nominator1;
// side2 = denominator2 * denominator2 + nominator2 * nominator2;
// side3 = denominator3 * denominator3 + nominator3 * nominator3;
// Get the longest side squared.
maxSide = side1 > side2 ? side1 > side3 ? side1 : side2 > side3 ? side2 : side3;
cout << maxSide;
Disclaimer: Code not tested!
I was going through Algorithm which identify crossing point using data points on x axis. I can understand calculation but could not understand purpose of this calculation. As per my understanding, it determine each time new y point and slope and subtract them.
I want to insert Image also but I do not have 10 reputation point.
Please let me know if I need to provide info.
//This function determine the crossing point when the graph is intersecting x axis.
XPoint findXingPoint(Curve & curve, double rfix, double vcc, int type, int pull_up)
{
//curve class contain x and y data point
// rfix is fixed value which is generally 50
// vcc also fix value
// type contain 0 and 1
//pull up to identify graph
XPoint p = { 0.0, 0.0 };
double r_fix = rfix;
double m = -1 / r_fix;
double c = vcc / r_fix;
if(type)
c=0;
double r, s, X1, X2, Y1, Y2, Y3, Y4;
r = (m * curve[0].first) + c;
// r is a kind of y value which determine from x and y point
s = abs(r);
for (Curve::iterator i = curve.begin(); i != curve.end(); i++) {
curve_point p = (*i);
double xcurve = p.first;
double ycurve = p.second;
double yloadline = m * xcurve + c;
double B = ycurve - yloadline;
if (B >= 0 && r >= B) {
r = B;
X1 = xcurve;
Y1 = yloadline;
Y2 = ycurve;
}
if (B <= 0 && r >= abs(B)) {
s = abs(B);
X2 = xcurve;
Y4 = yloadline;
Y3 = ycurve;
}
}
#could not understand purpose of B calculation
if (s == 0)
X1 = X2;
if (r == 0)
X2 = X1;
if (X1 != X2) {
double m1, m2, c1, c2;
m1 = (Y3 - Y2) / (X2 - X1);
m2 = (Y4 - Y1) / (X2 - X1);
c1 = Y3 - (m1 * X2);
c2 = Y4 - (m2 * X2);
// CASE m1==m2 should be handled.
p.x = (c2 - c1) / (m1 - m2);
p.y = (m2 * p.x) + c2;
} else {
p.x = X1;
p.y = Y1;
}
#not able to also understand calculation
if (verbosityValue >= 1)
loginfo<<"found crossing point # " << p.x << " " << p.y << endl;
return p;
}
Output:
first
found crossing point # 7.84541e-08 -1.96135e-09 with type 0
found crossing point # 0.528564 0.0182859 with type 1
second
found crossing point # 0.654357 -0.0163589 with type 0
found crossing point # 1.25827 4.31937e-05 with type 1
This appears to be a straightforward implementation. For a given point x,y on the curve, find the slope, draw a line through the slope, find where that line would cross the x axis, and then find the new y value at that point. For well-behaved functions, the new y value is a lot closer to 0 than the initial y value. You iterate until the approximation is good enough.
If you look at the graph, you see that the middle part is quite straight. Hence, the slope of the line is a locally good approximation of the curve, and your new y value is a lot closer to zero (At least 10x times, probably 100x, looking at the graph.0. If you start on the the steeper slopes on either side, you'll need one extra step. Your second x point will be on the middle part.
Is this the most efficient way to do this in Lua? Thank you!
if X >= 0 and Y >= 0 then
if X1 <= 960 and Y1 <= 720 then
someCode()
else end
else end
It is a good idea to avoid nested if statements, I would try a single if check.
The best way to be sure is to profile the functions and see what works faster.
-- Be paranoid and use lots of parenthesis:
if ( ( (X >= 0) and (Y >= 0) ) and ( (X1 <= 960) and (Y1 <= 720) ) ) then
someCode()
end
This is the same but easier to read. Good code is not only fast, but easy to read.
local condition1 = ((X >= 0) and (Y >= 0))
local condition2 = ((X1 <= 960) and (Y1 <= 720))
if (condition1 and condition2) then
someCode()
end
You can also use operators to make it a tad bit shorter:
if ((X >= 0 && Y >= 0) && (X1 <= 960 && Y1 <= 920)) then
someCode()
end
The answer by Yowza should also suffice tho, if you're looking for readability.