why doesn't my sorting code work? - c++

Write the definition of a function minMax that has five parameters . The first three parameters are integers . The last two are set by the function to the largest and smallest of the values of the first three parameters . The function does not return a value .
The function can be used as follows:
int a=31, b=5, c=19 big, small; minMax(a,b,c,&big,&small); /* big is now 31 / / small is now 5 */
void minMax (int a, int b, int c, int *big, int *small) {
if (a > b && a > c)
*big = a;
else if (b>a && b>c)
*big = b;
else if (c>a && c>b)
*big = c;
if (a < b && a < c)
*small = a;
else if (b<a && b<c)
*small = b;
else if (c<a && c<b)
*small = c;
return;
}
Remarks:
⇒ Your function did not change the value of small. Make sure you are dereferencing it in your function.
Common Errors:
Make sure your if/else statements are correct.
Make sure you have semicolons at the end of each statement.
Make sure you are assigning the correct values to big and small.

If the 3 numbers a, b and c are all different, your code should work fine. But if 2 (or even all 3) values are the same, you will get an error, because you are always checking for "strictly greater than" and "strictly less than", that is, you are using > and < instead of >= and <=. Try it with a=31, B=31, C=31 and you will see that you will neither assign a value to *big nor to *small.

How about this:
void minMax(int x, int y, int z, int * big, int * small)
{
*big = x;
if (y > *big)
{
*big = y;
}
if (z > *big)
{
*big = z;
}
*small = x;
if (y < *small)
{
*small = y;
}
if (z < *small)
{
*small = z;
}
}

Related

Minimum cuts on a rectangle to make into squares

I'm trying to solve this problem:
Given an a×b rectangle, your task is to cut it into squares. On each move you can select a rectangle and cut it into two rectangles in such a way that all side lengths remain integers. What is the minimum possible number of moves?
My logic is that the minimum number of cuts means the minimum number of squares; I don't know if it's the correct approach.
I see which side is smaller, Now I know I need to cut bigSide/SmallSide of cuts to have squares of smallSide sides, then I am left with SmallSide and bigSide%smallSide. Then I go on till any side is 0 or both are equal.
#include <iostream>
int main() {
int a, b; std::cin >> a >> b; // sides of the rectangle
int res = 0;
while (a != 0 && b != 0) {
if (a > b) {
if (a % b == 0)
res += a / b - 1;
else
res += a / b;
a = a % b;
} else if (b > a) {
if (b % a == 0)
res += b / a - 1;
else
res += b / a;
b = b % a;
} else {
break;
}
}
std::cout << res;
return 0;
}
When the input is 404 288, my code gives 18, but the right answer is actually 10.
What am I doing wrong?
It seems clear to me that the problem defines each move as cutting a rectangle to two rectangles along the integer lines, and then asks for the minimum number of such cuts. As you can see there is a clear recursive nature in this problem. Once you cut a rectangle to two parts, you can recurse and cut each of them into squares with minimum moves and then sum up the answers. The problem is that the recursion might lead to exponential time complexity which leads us directly do dynamic programming. You have to use memoization to solve it efficiently (worst case time O(a*b*(a+b))) Here is what I'd suggest doing:
#include <iostream>
#include <vector>
using std::vector;
int min_cuts(int a, int b, vector<vector<int> > &mem) {
int min = mem[a][b];
// if already computed, just return the value
if (min > 0)
return min;
// if one side is divisible by the other,
// store min-cuts in 'min'
if (a%b==0)
min= a/b-1;
else if (b%a==0)
min= b/a -1;
// if there's no obvious solution, recurse
else {
// recurse on hight
for (int i=1; i<a/2; i++) {
int m = min_cuts(i,b, mem);
int n = min_cuts(a-i, b, mem);
if (min<0 or m+n+1<min)
min = m + n + 1;
}
// recurse on width
for (int j=1; j<b/2; j++) {
int m = min_cuts(a,j, mem);
int n = min_cuts(a, b-j, mem);
if (min<0 or m+n+1<min)
min = m + n + 1;
}
}
mem[a][b] = min;
return min;
}
int main() {
int a, b; std::cin >> a >> b; // sides of the rectangle
// -1 means the problem is not solved yet,
vector<vector<int> > mem(a+1, vector<int>(b+1, -1));
int res = min_cuts(a,b,mem);
std::cout << res << std::endl;
return 0;
}
The reason the foor loops go up until a/2 and b/2 is that cuting a paper is symmetric: if you cut along vertical line i it is the same as cutting along the line a-i if you flip the paper vertically. This is a little optimization hack that reduces complexity by a factor of 4 overall.
Another little hack is that by knowing that the problem is that if you transpose the paper the result is the same, meaining min_cuts(a,b)=min_cuts(b,a) you can potentially reduce computations by half. But any major further improvement, say a greedy algorithm would take more thinking (if there exists one at all).
The current answer is a good start, especially the suggestions to use memoization or dynamic programming, and potentially efficient enough.
Obviously, all answerers used the first with a sub-par data-structure. Vector-of-Vector has much space and performance overhead, using a (strict) lower triangular matrix stored in an array is much more efficient.
Using the maximum value as sentinel (easier with unsigned) would also reduce complexity.
Finally, let's move to dynamic programming instead of memoization to simplify and get even more efficient:
#include <algorithm>
#include <memory>
#include <utility>
constexpr unsigned min_cuts(unsigned a, unsigned b) {
if (a < b)
std::swap(a, b);
if (a == b || !b)
return 0;
const auto triangle = [](std::size_t n) { return n * (n - 1) / 2; };
const auto p = std::make_unique_for_overwrite<unsigned[]>(triangle(a));
/* const! */ unsigned zero = 0;
const auto f = [&](auto a, auto b) -> auto& {
if (a < b)
std::swap(a, b);
return a == b ? zero : p[triangle(a - 1) + b - 1];
};
for (auto i = 1u; i <= a; ++i) {
for (auto j = 1u; j < i; ++j) {
auto r = -1u;
for (auto k = i / 2; k; --k)
r = std::min(r, f(k, j) + f(i - k, j));
for (auto k = j / 2; k; --k)
r = std::min(r, f(k, i) + f(j - k, i));
f(i, j) = ++r;
}
}
return f(a, b);
}

Finding smallest float x such that x+d=y

How to find the smallest float/double number x which satisfies x + d = y given d and y?
(iiuc this is theoretically solved via setting fesetround (FE_DOWNWARD) and just doing y - d but in clang/Xcode I got a warning that FENV_ACCESS isn't supported and in practice found that it didn't work)
So, so far I made this:
// Find minimum x value so that x + d = y
template<typename T, bool supportDenormals = false>
T subtractMost (const T y, const T d)
{
T x = y - d;
while (true)
{
const T nextX =
x == 0 && !supportDenormals
? -std::numeric_limits<T>::min()
: nextafter (x, -std::numeric_limits<T>::infinity());
if (nextX + d != y)
return x;
T step = x - nextX;
while (true)
{
const T nextStep = step + step;
if (x - nextStep + d != y)
break;
step = nextStep;
}
x -= step;
}
}
Which does quite a lot of actions to find the result, but I wonder:
Is there's a more efficient solution or a more standard way to achieve this?

Why this code produce 1?

Why this code produce 1? Someone, describe it for me pls.
#include <iostream>
using namespace std;
int main(){
int x = 0;
int y = 0;
if (x++&&y++){
y += 2;
}
cout << x + y << endl;
return 0;
}
Initially x and y are 0
Therefore x++ evaluates to false, and the second operand of && is never evaluated. x++ does increment x to 1. Since the condition is false, the conditional branch is not entered.
x + y is 1 + 0 which equals 1
user2079303 explains nicely (+1 by me already), as extension, I'll go a little more into detail:
if(x++) evaluates the value of x before the incrementation, so this little piece of code is equivalent to the following (need to buffer the old value!):
int tmp = x;
x++;
if(tmp)
Be aware that within c && cc, the second condition cc is not evaluated any more if c is already false! So if(x && y) is equivalent to
if(x)
{
if(y)
{
// ...
}
}
Putting all this together, your code is equivalent to this variant, where I separated the if clause into code lines each one containing only one single instruction:
int x = 0;
int y = 0;
int tmp = x;
x++;
if(tmp)
{
tmp = y;
y++;
if(tmp)
y += 2;
}
Suppose, your output now is quite obvious...

How to compute distance between numbers in c++?

I want to compute the distance between numbers with help of the system described in the attached image.
For example: distance between 7 and 5 is -2, distance between 7 and 1 is 2 etc...
Any ideas how to do this in c++? The prefered direction is counter clockwise...
I am using a (int) vector.
If you do it in straightforward way (by considering all possibilities) it might look as follows
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return
a <= b ?
(d <= +4 ? d : d - 8) :
(d <= -4 ? d + 8 : d);
}
which, if you prefer, can be rewritten as
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = b - a;
return -4 < d && d <= 4 ? d : (d > 0 ? d - 8 : d + 8);
}
An alternative, more elegant approach would be to always calculate the positive CCW distance and flip it to negative CW distance if it is greater than 4
int distance(int a, int b)
{ // Distance from `a` to `b`
int d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : d - 8;
}
But if you want the compiler to generate the most efficient code for this, follow the golden rule "use unsigned types everywhere you can, use signed types only if you have to":
int distance(unsigned a, unsigned b)
{ // Distance from `a` to `b`
unsigned d = (b + 8 - a) % 8;
// `d` is CCW distance from `a` to `b`
return d <= 4 ? d : (int) d - 8;
}
These are really complicated answers. Here is a simpler one:
int distance(int x, int y) {
int d = (y - x) & 7;
return d > 4 ? d - 8 : d;
}
This always returns a result in the range -3..+4. Modular arithmetic is a little simpler to write when the ring size is a power of two, as is the case here.
distance(7, 5) = -2
distance(5, 7) = +2
distance(6, 2) = +4
distance(2, 6) = +4
We use & 7 because it is the simplest way to get the modulo. Alternatively, you can use % 8, but you must also add 8 in order to make sure that the input is not negative:
int d = (y - x + 8) % 8; // same result
Alternatively, you can handle negative numbers explicitly:
int d = (y - x) % 8;
if (d < 0) {
d += 8;
}
// same result
This is just a matter of style.
For simplicity you can find the element from std::find and get the distance from start from std::distance
for example
as you mentioned the data saved in int vector
std::vector<int>::iterator it1 = std::find(myvec.begin(), myvec.end(), val_1);
std::vector<int>::iterator it2 = std::find(myvec.begin(), myvec.end(), val_2);
int dist = std::distance(myvec.begin(),it1) - std::distance(myvec.begin.it2);
if(dist < 0) return dist
else(dist > 0) return myvector.size() - dist()
So hope this will give the distance as the image ...
I am pretty sure this works:
list = [0,1,2,3,4,5,6,7]
distance(x,y) {
a = y-x
b = length(list)-abs(y-x)
z = min(abs(a), abs(b))
if(z=abs(a)) { return a }
if(z=abs(b)) { return b }
}
where abs() is the mathematical absolute value function.
I make a few assumptions here.
As #Hédi Ghédiri pointed out, you are not counting counter-clockwise both times. I am assuming you count the shortest path to the number. (I used the mathematical min() function)
You prefer the positive value over the negative value (#Harper's comment). If you prefer the negative value, switch the last two if statements.
There may be a more concise method, but this (hopefully) works. Please comment if it is wrong. Hope this is helpful!
Edit: this is psuedocode. It should be easy to write in c++. Use the abs() function in <stdlib.h> Forget about list and length(list). Use int types for the variables, and everything else should work.
The following code is prepared to meet all of your needs, for example I assume, that if direction is clockwise the distance is to be negative.
#include <iostream>
#define RING_SIZE 8
enum direction
{
clockwise,
counterClockwise
};
int distance(int a, int b, direction dir)
{
int dist;
if(dir == clockwise)
{
if(a>b)
{
dist = -(a-b);
}
else
{
dist =-(RING_SIZE-b+a);
}
}
else
{
if(a<b)
{
dist = b-a;
}
else
{
dist = RING_SIZE-a+b;
}
}
if(a==b) dist = 0;//Add this if distance between same point must to be 0
return dist;
}
int main()
{
std::cout << distance(7, 2, clockwise) << std::endl;
}
I think this should work
int func(a,b)
{
dist=(b-a);
if(dist<0)
dist +=8;
return dist;
}
in case you're really stuck

Returning the actual value of maximum of absolutes of variables

I want to find the maximum of the absolute of two variables, and return the actual value of that variable, rather than the absolute value of that variable.
For example:
int x = 3;
int y = -5;
int z = max(abs(x), abs(y))
Will just set z to 5, whereas I want it to return -5. Is there a C++ function to perform this?
If you're using C++11, with the STL you could use a vector of int, max_element and a lambda Compare
std::vector<int> values = {3, -5};
int largest_abs = *std::max_element(values.begin(), values.end(), [](const int& a, const int& b)
{
return abs(a) < abs(b);
});
This returns the iterator between the start and end of values, whose absolute value is the largest. (this is found through the comparator) The * is then used to convert the iterator (returned by std::max_element) to an int
It's not a commonly used function, but writing your own function is trivial.
int max_abs(int x, int y)
{
if (x == INT_MIN || y == INT_MIN)
return INT_MIN;
return (abs(x) > abs(y)) ? x : y;
}
int z = (max(abs(x), abs(y)) == abs(x)) ? x : y;
This is like an if-condition. Its equivalent to
int z = x;
if(max(abs(x), abs(y)) != abs(z))
z = y;
But much shorter.
There is no function in the STL to fit into your needs directly, so you need to make your own and this one could be one version.
A more handy one can be int z = (abs(y) < abs(x)) ? x : y thought.