Related
I am trying to write a piece of code for my old Highschool teacher for a game he had us play literally called the "Dice Game." Let's just say that the game takes two d12's and multiplies them together to get a number (D) in this instance. Then you take 3 d6's and roll them to get your A, B, and C variables. You would then either Add, Subtract, Multiply, Divide, Exponentiate, or Root by that number to get as close to as you could to D. Those operations would stand for x and y in the following equation
AxByC=D
I don't know how else to word this, but I am having trouble finding any way to solve these equations and then compare them. Maybe I am missing something simple, but I don't know.
EDIT: I should probably be more clear about the question. I know how to set all the equations up. It is just a matter of finding a way to compare the answers to the D variable and then the other answers to the equation to see which one is closer. The closest number to D wins, thus the whole point to the dice game.
If you are just trying to compare the answers to the D variable, why not loop through each equations result and compare them equal to D?
for (int i = 0; i < equationResults.size(); i++) {
if (equationResults[i] == D)
return true;
}
EDIT: If you are trying to find the closest to D, you can compare each answer to D and subtract the answer from D and store it, then return the min value:
closeToD[0] = D - equationResults[0];
return *min_element(closeToD.begin(), closeToD.end());
Since you can juggle the values around, as well as picking operators, you actually have two problems: generating the permutations of variables and generating the permutations of operators. The first part is rather straightforward:
std::array<int, 3> input;
std::sort(input.begin(), input.end());
do {
compute(input[0], input[1], input[2]);
} while (std::next_permutation(input.begin(), input.end()));
The compute part could be a function that takes such an array of 3 values and finds the best value, or closest to D, or just all values.
Generating all permutations of operators is slightly more annoying because next_permutation can't compare them, and also we accept duplicates. The easiest way is to just brute-force through them; I'll do it just for the slightly easier operators:
std::array<int, 16> compute(int a, int b, int c) {
return {
a + b + c,
a + b - c,
a + b * c,
a + b / c,
a - b + c,
a - b - c,
a - b * c,
a - b / c,
a * b + c,
a * b - c,
a * b * c,
a * b / c,
a / b + c,
a / b - c,
a / b * c,
a / b / c,
};
}
Generating such list of operations programmatically is a bit more challenging; you can't simply do (a op b) op c because of the aforementioned precedence. Doing it this way guarantees that the results are actually achievable because of the operator precedence built into the language.
This will still do redundant computations - e.g. in the first case, the result will be the same regardless of the permutation of a/b/c. Eliminating those is perhaps a more interesting exercise for later. Perhaps a small relief is the fact that if a == b or b == c, next_permutation will already take care of that for us, cutting the number of iterations from 6 to either 3 or 1.
I have a very simple question by I am very confused by the way I could implement this. I want to create a Boolean variable in a single line composed of ternary statement such as this:
boolean = a ? b : (c ? d : (e ? f : (g ? i : j );
It is working for 1, 2 or 3 such imbricate conditions for the purposes of my codes but I which to write it in a way that I could choose how many such ternary conditions I want to put into each other to define the Boolean variable.
And I am stuck with this because at the end it looks like I cannot add the last condition. I have tried to think of a recursive function, maybe with some counter, but I could not manage to write it. I do not know if what I ask is simpler or clear.
The condition are not fully independent of each other, there are intervals (coordinates in space) that follow each other somehow. So for example the 'a' in my example would be something like 11 and then it would continue when it is false with a new condition saying 22 and so on. Hence my idea of introducing some counter to put into the conditions.
But when I arrive at the last false condition, I don't know what to do because I cannot set up a random z>something to make my code work.
I am trying something like:
bool f(double x, double value, double z, double d, double n, double step, int &count);{
bool result;
count++;
if (count == n) {return result}
result = (x >=value+count*step && x<value+(count+1)*step) ? z>=d : f(x,value,z,d,n,step, &count);
}
So of course, besides probably many mistakes in the way I am writing recursive function since I never use them and do not use C or C++ usually, it will appear that in the last call of the function by itself, we will have something like a ? b : without the last parameter if the statement is false.
I tried to be as clear as I could. You can ask questions if you do not get the point. And any help is welcome, recursive functions, normal functions or a way to do it with no function at all...
Best regards and thanks in advance for your answers!
Edit:
The code with if should be something like:
if (a){
b}
else{
if (c){
d}
else{
if(e){
f}
else{
if(g){
I}
else{
j}
I may have forgotten some bracket but I hope it is understandable. And this point is to continue with, say n, if statements like this in a single line to create a Boolean variable and then being able to choose n instead of rewriting a new code each time I want to add an if statement.
EDIT about recursion:
Can someone explains me why this kind of function creates an infinite loop?
bool f(double x, double l, double z, double d, double step, int &count){
int n = (int)l/step;\\number of steps
count++;
if (count < n)
return (x >=l+count*step && x<l+(count+1)*step) ? z>=d*count : f(x,l,z,d,step,count);
else
return z>=d*(count-1);
}
I set the counter 'count' to -1 before calling the function and it seems to be the problem. It does the loop correctly but then it restarts again and again so that I cannot even check if my code makes any sense for my purpose. I thought after each return calling the function recursively, it would increase the counter but once it reaches n, it should return something else and go out of the function, not restart the counter and doing everything again...
To write that if ... else if ladder more clearly, get rid of the brackets and get rid of the indentation. Like this:
if (a)
boolean = b;
else if (c)
boolean = d;
and so on. But I’d be inclined to write it as a function:
if (a)
return b;
else if (c)
return d;
and so on. Still, if you like the ternary operator, it can be written in a disciplined way that is easily read:
boolean = a ? b
: c ? d
: e ? f
: g;
[4th version of the answer, taking into account comments]
In the particular case of the first simple example provided, it is possible to write a variadic function. Here the template ...args parameter indicates a variable number of parameters. One can call f(false,false,true) or f(false,false,false,true,true) or more parameters.
bool ff(bool a, bool b, bool c) {
return a ? b : c;
}
template<class ...Args>
bool ff(bool a, bool b, Args ...args){
return a ? b : ff(args...);
}
As user463035818 mentioned, there is a risk of short-circuiting in this first call of ff(.) function (by main), when all booleans are likely to be evaluated during this fist call. I don't know what would really happen with optimization by the compiler, with possible inlining and unrolling, but it is useless to stress the compiler.
Anyway I now understand that the number of steps is an input parameter, and a variadic template function does not seem to be applicable. It is certainly possible to solve it with a recursive function, similar to the one you proposed. However, in my opinion, a simple 'for loop' will be both efficient and flexible.
In my previous answer, I proposed a solution based on a for loop. However, as it does not correspond to your needs, because I misunderstood the mathematical problem, I removed it.
Instead, I come back to the second recursive function that you proposed in your post. You asked why the recursion did not finish. I could not comment it directly because of my poor reputation. As I did not see why the programme did not stop, I implemented it and the programme finished normally, but with a result that does not seem correct. I see a problem about parameter l. It seems to correspond both to a range for x and to a minimal value for x. I tried to correct it. It may happen that I did not select the input parameter values correctly . Therefore, I put the corresponding program hereafter for you to be able to check it.
#include <iostream>
bool f(double x, double xmin, double range, double z, double d, double step, int &count){
int n = range/step; //number of steps
count++;
if (count < n) {
double a = xmin + count*step;
return ((x >=a) && (x< a + step)) ? z>=d*count : f(x,xmin,range,z,d,step,count);
} else
return z>=d*(count-1);
}
int main () {
int count = -1;
double xmin = 0.0;
double x = 2.0;
double range = 4.0;
double step = 1.0;
double d = 1.0;
double z = 2.0;
bool test = f (x, xmin, range, z, d, step, count);
std::cout << "test = " << test << "\n";
std::cout << "count = " << count << "\n";
return 0;
}
In this particular case, it would be better to replace range by n as input parameter, to avoid redundant calculation of n.
Readability vs efficiency
The point is I don't want my code to be elegant or readable but efficient.
Honestly, I think this is not a good strategy. Inefficient code is not elegant. This does of course not imply that readable code is automatically efficient.
However, it is much easier to accidentally prevent the compiler doing an optimization rather than pushing it to emit better code than it already does anyhow. Readable code does contain less errors and helps you to avoid obvious inefficiencies. That being said,...
Why not to write a variadic conditional function?
Besides readability there is one more thing to consider: short-circuiting. With the plain conditional
bool x = condition ? t : some_other_function_call();
in case condition is true, then some_other_function_call() will not be evaluated, while in
bool x = foo(t,some_other_function_call());
the other function will be called in either case. You cannot get short-circuiting with foo.
What to do instead?
The answer by Pete Becker nicely demonstrates how to write the conditions in a clean way (most importantly you don't need to nest the cases when they are mutually exclusive (they are for the ternary!)).
Anyhow... how could a variadic conditional function be written?
Just for the sake of completeness, this is how you could write such a function to replace bool x = a ? b : (c ? d : (e ? f : (g ? i : j ); with a funciton call (please dont):
// DISCLAIMER: DONT DO THIS
bool my_conditional(std::vector<bool> x){
if (x.size() == 1) return *x.begin();
bool condition = *x.begin();
bool true_value = *(x.begin()+1);
return condition ? true_value : my_ternary({x.begin()+2,x.end()});
}
You could call it like this:
my_conditional({ condition1, true_value1, condition2, true_value2, false_value});
eg
std::cout << my_conditional({false,false,false,false,false});
prints 0.
I am just getting familiar with Boost GIL (and image processing in general) and suspect that this is simple, but I haven't found the relevant documentation.
I have a set of image views that I would like to combine with an arbitrary function. For simplicity, lets say the images are aligned (same size and locator type) and I just want to add the pixel values together. One approach would be to create a combining iterator from a zip_iterator and a transform_iterator, but I'm guessing that there are image processing algorithms that are conveniently abstracted for this purpose.
The Mandelbrot example in the documentation is probably relevant, because it computes pixel values from a function, but I'm getting lost in the details and having trouble adapting it to my case.
The only binary channel algorithm I can find is channel_multiply.
The algorithm you're probably really looking for is transform_pixels which does combine in a binary variation.
Here's the simplest example I could make.
#include <boost/gil/gil_all.hpp>
#include <boost/gil/extension/io/png_io.hpp>
namespace gil = boost::gil;
int main() {
using Img = gil::rgba8_image_t;
using Pix = Img::value_type;
Img a, b;
gil::png_read_image("/tmp/a.png", a);
gil::png_read_image("/tmp/b.png", b);
assert(a.dimensions() == b.dimensions());
Img c(a.dimensions());
gil::transform_pixels(view(a), view(b), view(c), [](gil::rgba8_ref_t a, gil::rgba8_ref_t b) {
gil::red_t R;
gil::green_t G;
gil::blue_t B;
gil::alpha_t A;
return Pix (
get_color(a, R) + get_color(b, R),
get_color(a, G) + get_color(b, G),
get_color(a, B) + get_color(b, B),
get_color(a, A) + get_color(b, A)
);
});
gil::png_write_view("/tmp/c.png", view(c));
}
When a.png is and b.png is (note transparencies too), c.png became (again, note the transparencies).
You will want to fine-tune the transformation function to do something more useful suppose.
Okay, so I've tried to use sort to vector of items so the size of two adjecant items is <= 2d.
So here's my attempt:
struct item{
long number;
long size;
};
// d is global variable.
bool check(const item& x, const item& y)
{
return ((x.size + y.size) <= (2 * d));
}
// Items is a vector of item.
sort(items.begin(), items.end(), check);
What am I doing wrong or it's even impossible to sort using condition like that ?
it's even impossible to sort using condition like that ?
No. The comparer in sort must satisfy the criteria of a strict weak ordering which yours clearly doesn’t (for instance it’s not irreflexive).
This problem cannot be solved in O(N log N) time. I don't know if it's NP-hard, but it's quite non-trivial. I do think it's safe to say that a program solving the problem as expressed in your code would require exponential time. There are such programs: I think it could be fiddled around and plugged into a linear optimizer.
No standard library function will get you even most of the way to a general solution. There are no standard library functions slower than O(N log N), and none solve problems that may be intractable.
This problem is intractable if, for example, every size equals 10 * d.
You're using the sort() method wrong.
STL sort is used to order a list of elements. For an 'ordering', you need to satisfy conditions like:
if check( A, B ) == false AND A != B, then check( B, A ) returns true.
if check( A, B ) == false AND check( B, C) == false AND A, B, C are distinct, then check ( A, C ) returns false.
A good idea for where you can use STL's sort() is, given your list of items S and the order you want the items to be in:
If the order of the items in S changes, the output order should remain the same.
The output is unique.
All the items in the output order have some relation that is a strict partial order relation.
If this is the case, then you probably can write the check function to work for you :)
I've got two ways of fetching a bunch of data. The data is stored in a sorted vector<map<string, int> >.
I want to identify whether there are inconsistencies between the two vectors.
What I'm currently doing (pseudo-code):
for i in 0... min(length(vector1), length(vector2)):
for (k, v) in vector1[i]:
if v != vector2[i][k]:
// report that k is bad for index i,
// with vector1 having v, vector2 having vector2[i][k]
for i in 0... min(length(vector1), length(vector2)):
for (k, v) in vector2[i]:
if v != vector1[i][k]:
// report that k is bad for index i,
// with vector2 having v, vector1 having vector1[i][k]
This works in general, but breaks horribly if vector1 has a, b, c, d and vector2 has a, b, b1, c, d (it reports brokenness for b1, c, and d). I'm after an algorithm that tells me that there's an extra entry in vector2 compared to vector1.
I think I want to do something where when I encountered mismatches entries, I look at the next entries in the second vector, and if a match is found before the end of the second vector, store the index i of the entry found in the second vector, and move to matching the next entry in the first vector, beginning with vector2[i+1].
Is there a neater way of doing this? Some standard algorithm that I've not come across?
I'm working in C++, so C++ solutions are welcome, but solutions in any language or pseudo-code would also be great.
Example
Given the arbitrary map objects: a, b, c, d, e, f and g;
With vector1: a, b, d, e, f
and vector2: a, c, e, f
I want an algorithm that tells me either:
Extra b at index 1 of vector1, and vector2's c != vector1's d.
or (I'd view this as an effectively equivalent outcome)
vector1's b != vector2's c and extra d at index 2 of vector1
Edit
I ended up using std::set_difference, and then doing some matching on the diffs from both sets to work out which entries were similar but different, and which had entries completely absent from the other vector.
Something like the std::mismatch algorithm
You could also use std::set_difference
It sounds like you're looking for the diff algorithm. The idea is to identify the longest common subsequence of the two vectors (using map equality), then recurse down the non-common portions. Eventually you'll have an alternating list of vector sub-sequences that are identical, and sub-sequences that have no common elements. You can then easily produce whatever output you like from this.
Apply it to the two vectors, and there you go.
Note that since map comparison is expensive, if you can hash the maps (use a strong hash - collisions will result in incorrect output) and use the hashes for comparisons you'll save a lot of time.
Once you're down to the mismatched subsequences at the end, you'll have something like:
Input vectors: a b c d e f, a b c' d e f
Output:
COMMON a b
LEFT c
RIGHT c'
COMMON d e f
You can then individually compare the maps c and c' to figure out how they differ.
If you have a mutation and insertion next to each other, it gets more complex:
Input vectors: a b V W d e f, a b X Y d e f
Output:
COMMON a b
LEFT V W
RIGHT X Y
COMMON d e f
Determining whether to match V and W against X or Y (or not at all) is something you'll have to come up with a heuristic for.
Of course, if you don't care about how the content of the maps differ, then you can stop here, and you have the output you want.
What exactly are you trying to achieve? Could you please define precisely what output you expect in terms of the input? Your pseudo code compares maps at the vector index. If that is not the correct semantics, then what is?
Can you associate with each map some kind of checksum (or Blumen filter) - that at single check you could be able to decide if comparison has a sense.
In your example, note that is not possible to differentiate between
Extra b at index 1 of vector1, and
vector2's c != vector1's d.
and
Extra b at index 1 of vector 1, extra
d at index 2 of v1, and extra c at 1
in v2
because it is not clear that "c" shoud be compared to "d", it could be compared to "b" either. I assume the vectors are not sorted, because std::map doesn't provide a relational operator. Rather are the maps, which is as far as I see completly irrelevant ;-)
So your example is slightly misreading. It could even be
Compare
b f e a d
with
a c f e
You can check each element of the first vector against each element of the second vector.
This has quadratic runtime.
for i in 0... length(vector1):
foundmatch = false;
for j in 0... length(vector2):
mismatch = false;
for (k, v) in vector1[i]:
if v != vector2[j][k]:
mismatch = true;
break; // no need to compare against the remaining keys.
if (!mismatch) // found matching element j in vector2 for element i in vector1
foundmatch = true;
break; // no need to compare against the remaining elements in vector2
if (foundmatch)
continue;
else
// report that vector1[i] has no matching element in vector2[]
// "extra b at i"
If you want the find the missing elements, just swap vector1 and vector2.
If you want to check in a element in vector2 mismatches to a element in vector1 in only a single key, you have to add additional code around "no need to compare against the remainig keys".