If statement with 3 conditions (triangleExists) - c++

Check if TriangleExists: it is when every 1 of its side is smaller than the sum of the 2 others.
I tried a lot of options:
float a=3, b=15, c=7; //its still taking 'y'
bool triangleExists(float a, float b, float c)
{
if ((a < (b + c)) || (b < (a + b)) || (c < (a + b)))
{
std::cout << "y" << std::endl;
return true;
}else
std::cout << "n" << std::endl;;
return false;
}
Options I tried (they were also tried with && marks):
if ((a < (b + c)) || (b < (a + b)) || (c < (a + b)))
if ( a < (b + c) || b < (a + b) || c < (a + b))
if ((a < (b + c))==true || (b < (a + b))==true || (c < (a + b))==true)
if (a < b + c || b < a + b || (c < a + b)
I'm probably missing something simple. I'll be glad if you can help.

In your middle condition, you have b < (a + b), when it should be b < (a + c)

Along with the typo that #Zackary Murphy already pointed out, you have a more fundamental problem with your logic.
In particular, your function should return true only if all three conditions are passed. With the middle term corrected to b < (a + c), it still returns true (and prints y) even though the numbers you've specified can't form a triangle.
For example:
#include <iostream>
bool triangleExists(float a, float b, float c)
{
if ((a < (b + c)) || (b < (a + c)) || (c < (a + b)))
{
std::cout << "y" << std::endl;
return true;
}
else
std::cout << "n" << std::endl;;
return false;
}
int main() {
float a = 3, b = 4, c = 500; //its still taking 'y'
triangleExists(a, b, c);
}
... prints y, even though sides of 3, 4 and 500 can't form a triangle.
To get correct behavior, you can change from using || to && (i.e., from or to and). Alternatively, you can invert the test and invert the results--that is, if a > (b + c) || b > (a + c) || c > (a + b), then return false. Only otherwise, return true.

Related

How to compare sum of two int64 with INT64_MAX?

I know number greater than INT64_MAX will wrap around negative, So how to compare when sum overflow, that is sum greater than INT64_MAX.
#include <iostream>
using namespace std;
int main() {
int64_t a = INT64_MAX;
int64_t b = 1;
// cin >> a >> b;
if (a + b <= INT64_MAX) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
return 0;
}
First compare b to either INT64_MIN - a or INT64_MAX - a before the addition to prevent undefined behavior (UB) of signed integer overflow.
// True when sum overflows.
bool is_undefined_add64(int64_t a, int64_t b) {
return (a < 0) ? (b < INT64_MIN - a) : (b > INT64_MAX - a);
}
Worst case: 2 compares.
For div, mul, sub
Before compare, check a + b to see if it will overflow.
int is_overflow(int64_t a, int64_t b) {
if (((b > 0) && (a > (INT64_MAX - b))) ||
((b < 0) && (a < (INT64_MIN - b)))) {
return 1;
}
return 0;
}

please explain this statement(cout << 1 + int((a < b) ^ ((b - a) & 1)) << endl)

#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int a, b;
cin >> a >> b;
if (a == b) cout << 0 << endl;
else cout << 1 + int((a < b) ^ ((b - a) & 1)) << endl;
}
return 0;
}
please someone describe the above statement.how this statement works and what is the result of this statement.
this code is snippet from codeforces.
link:https://codeforces.com/blog/entry/74224
Let's make it step by step.
c = (b - a) & 1 - check if last bit of b - a is set, same as check that b - a is odd.
d = (a < b) ^ c - returns true if int(a < b) != c.
1 + int(d) - should be clear
Then we have
(b - a) - odd (b - a) - even
(a < b) 1 2
(a >= b) 2 1

C++ Merge Overlapping Strings

Let's say that I have string A: "info_mesh", and I want to add it string B: "mesh_foo".
However, I want string "info_mesh_foo", not string "info_meshmesh_foo".
I can't just say:
std::string A = "randomstuffoverlap", B = "overlapwithmorestuff"
std::string C = A + B;
Because I would end up with:
C = "randomstuffoverlapoverlapwithmorestuff",
when I want:
C = "randomstuffoverlapwithmorestuff"
without the "overlap" mentioned twice, as if the created string had a "mesh" of two strings.
However, I also would want this to work if:
std::string A = "juststuff", B = "unrelatedstuff", C;
//std::string C should be made equal to "juststuffunrelatedstuff".
(so there is No shared substring between them)
How would I go about doing this?
Thanks in advance.
Try this;
std::string A = "randomstuffoverlap", B = "overlapwithmorestuff", C;
size_t pos = A.find_last_of(B[0]);
if (pos != std::string::npos)
{
std::string::difference_type d = A.size() - pos;
if (A.substr(pos) == B.substr(0, d))
C = A + B.substr(d);
else
C = A + B;
}
else
C = A + B;
std::cout << C << std::endl;
Well, starting with the maximum possible (full overlap), loop down until it fits, and then return the result from overlapping them:
std::string overlap(std::string_view a, std::string_view b) {
for (auto n = std::min(a.size(), b.size());; --n) {
if (b.endswith(a.substr(0, n))) // b.substr(b.size() - n) == a.substr(0, n)
return std::string(b) + a.substr(n);
else if (a.endswith(b.substr(0, n))) // a.substr(a.size() - n) == b.substr(0, n)
return std::string(a) + b.substr(n);
}
If you cannot use C++20 std::string_view::endswith(), use the alternative in the comment.
This has taken me a while, but I have this function:
string overlapjoin(string a, string b) {
for (long long x = (b.length()<= a.length())? b.length(): a.length(); x > 0; --x)
if (a.substr(a.length() - x, a.length() - 1) == b.substr(0, x))
return(a.substr(0, a.length() - x) + b);
return(a + b);
}
Which can also be expressed as, if you want a limit to shared characters:
string overlapjoin(string a, string b, int maxlength) {
for (long long x = maxlength; x > 0; --x)
if (a.substr(a.length() - x, a.length() - 1) == b.substr(0, x))
return(a.substr(0, a.length() - x) + b);
return(a + b);
}

How to get the sum of divisors in a given range efficiently?

I'm trying to find the sum of all divisors of c in a give range a, b a <= b.
I've tried to loop from a to b and sum all divisors of c, but this seems inefficient, because the absolute difference between a and b can be 10^9.
Is there a way that reduces the time complexity of this approach?
int a, b, c;
cin >> a >> b >> c;
long long sum = 0;
for (int i = a; i <= b; i++) {
if (i % c == 0) {
ans += i;
}
}
cout << sum << endl;
Note: the question is unclear whether we need to sum divisors (in the description) or divisible integers (in the code sample). The answer sums up divisible items.
This is simple.
Find from, the smallest value such that from % c == 0 && from >= a
Find to, the largest value such that to % c == 0 && to <= b
.
int n = (to - from) / c + 1;
return n * (to + from) / 2;
Return to - from + c. Take care of boundary conditions when to could overflow your type and from can underflow.
To find from do something like:
if (c < 0) c *= -1; // works unless c == MIN_INT
if (a % c == 0)
from = a;
else if (a >= 0)
from = (a / c * c) + c
else
from = a / c * c;
Similarly for to, but accounting for the fact that we need to round down, and not up.
Also, need to handle the case of a > b separately.
EDIT
Here is the complete code with no loops, recursion, or containers. It runs in O(1):
int a, b, c;
std::cin >> a >> b >> c;
if (!std::cin) {
std::cout << "input error\n";
return 0;
}
if (c < 0) c*= -1;
const int from = [a,c] {
// no rounding needed
if (a % c == 0) return a;
// division rounds down to zero
if (a > 0) return (1 + a / c) * c;
// division rounds up to zero
return a / c * c;
}();
const int to = [b,c] {
// no rounding needed
if (b % c == 0) return b;
// division rounds down to zero
if (b > 0) return (b / c) * c;
// division rounds up to zero
return (b / c - 1) * c;
}();
int64_t sum = 0;
if (from <= to)
{
const int n = (to - from) / c + 1;
sum = n * (to + from) / 2;
}
std::cout << sum << '\n';
Identify all the prime numbers that are divisors of c first. That will leave you with a list of numbers [w,x,y,z…]. Then keep a hash table set of all multiples of integers in this list that are also divisors.
int a, b, c;
cin >> a >> b >> c;
long long sum = 0;
std::vector<int> all_prime_factors = // Get all prime factors of c
std::unordered_set<int> factorSet;
for (int primefactor : all_prime_factors)
{
int factor = primefactor;
while (factor <= b)
{
if (factor % c == 0)
factorSet.insert(factor);
factor += primefactor;
}
}
for (int x : factorSet)
{
sum += x;
}
cout << sum << endl;

Conditioning for the four cases of the signs of two numbers

I have two numbers A and B. I would like to condition for the four cases of the signs of these two numbers. We could do
if ((A >= 0) && (B >= 0)){
// Do something
};
if ((A >= 0) && (B < 0)){
// Do something
};
if ((A < 0) && (B >= 0)){
// Do something
};
if ((A < 0) && (B < 0)){
// Do something
};
One could produce a function that outputs different values in each case and then use a switch{ case:} statement. For the functions I have thought this doesn't improve the number of comparisons, so there is no much gain.
Which way is recommended for doing this conditioning?
Well, I guess some of those if-s could be put inside else-s of the others so that not all the conditions have to be evaluated always.
if (A >= 0)
{
if (B >= 0)
{
}
else // B < 0
{
}
}
else // A < 0
{
if (B >= 0)
{
}
else // B < 0
{
}
}