Recently I'm working on Macros and I got stuck in very simple problem. Here is my code:
#include <iostream>
#define abs(A) (A<0)? -A:A;
using namespace std;
int dis(int x, int y)
{
return abs(x-y);
}
int main()
{
cout<<dis(2,4);
}
Basically abs() takes the absolute of the given value, then the distance is calculated. But in this case it gives the output -6 rather than the 2.
This is because of the way your macro will be evaluated, i.e. during the preprocessor stage of code compilation process, the return abs(x-y) would be changed to:
return abs(x-y)
(A<0) -> -A
(2-4) < 0 = -2 -> -2-4 = -6
You should either change the definition of your macro (better solution), by wrapping macro variables in brackets, to:
#define abs(A) ((A)<0) ? -(A):(A);
or change your code to:
int dis(int x, int y)
{
int res = x-y;
return abs(res);
}
Please note that there is also a abs() function in C Standard Library.
Related
#define minimum(mn, b) mn = min(b)
#define maximum(mx, c) mx = max(c)
#define INF 10000000
#define toStr(a) #a
#define io(v) v.push_back()
#define FUNCTION(a,b) #
#include <iostream>
#include <vector>
using namespace std;
#if !defined toStr || !defined io || !defined FUNCTION || !defined INF
#error Missing preprocessor definitions
#endif
FUNCTION(minimum, <)
FUNCTION(maximum, >)
int main(){
int n; cin >> n;
vector<int> v(n);
foreach(v, i) {
io(v)[i];
}
int mn = INF;
int mx = -INF;
foreach(v, i) {
minimum(mn, v[i]);
maximum(mx, v[i]);
}
int ans = mx - mn;
cout << toStr(Result =) <<' '<< ans;
return 0;
}
This is a sample question from a hackerrank question, so there would be some mistakes in it. I want to know what does the part
FUNCTION(minimum, <)
FUNCTION(maximum, >)
mean ? It doesn't look like a macro as it doesn't start with #define. The discussion forums too didn't have a good explanation about this part, just that it relates to the macro defined as #define minimum(mn, b) mn = min(b) and #define maximum(mx, c) mx = max(c).
'
I want to know what's it called and some advice on good resource to read about it.
The title is poorly written as I have no clue what to refer to that doubtful part of code as.
Let's break this answer into parts:
First, the thing you show here isn't valid code. #define FUNCTION(a, b) # doesn't compile on GCC, it correctly says:
error: '#' is not followed by a macro parameter
# is supposed to work like shown in your toStr example, where #a causes it to emit a string with a's value as contents.
Second, I assume that the poster of this "solution" wanted FUNCTION to just do nothing.
It seems that some compilers do treat a sole # that way, but it's not correct. It would have worked to write #define FUNCTION(a, b) without anything afterwards (or
#define FUNCTION(a, b) // like I saw in some other solutions for this question).
So, the answer to "what does this part do" is literally "nothing". (At least, it was intended this way.)
Third, even with that fixed, the code doesn't look right, because unless I'm misreading this, it doesn't really calculate any minimum or maximum, because min doesn't get the previous minimum as argument (same for max)! I'd expect this...
#define minimum(mn, b) mn = min(mn, b)
#define maximum(mx, c) mx = max(mx, c)
...instead of the current min(b) and max(c) there.
Forth, it seems that most solutions on this hackerrank question turn FUNCTION into a no-op and instead create minimum and maximum as macros.
But, I feel like the intention behind FUNCTION was something else, something a bit more clever. You could define it as macro that creates functions (hence the name) named after the first argument, that compare the minimum/maximum based on the second argument used as comparison operator:
#define FUNCTION(_FN_NAME_, _COMPARISON_OP_) \
void _FN_NAME_(int& limit, int newValue) { \
if (newValue _COMPARISON_OP_ limit) { \
limit = newValue; \
} \
}
This way, FUNCTION(minimum, <) and FUNCTION(maximum, >) would expand to:
void minimum(int& limit, int newValue) {
if (newValue < limit) {
limit = newValue;
}
}
void maximum(int& limit, int newValue) {
if (newValue > limit) {
limit = newValue;
}
}
I was recently solving a problem from Codeforces. After giving it a lot of tries I was not able to get how in tree dp the matrix calculation works in the editorial solution. The following is the code where I have added comments to the parts I don't understand in it.
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int f[2][10010][110];//0 max 1 min
char s[10010];
int tr[10010][2],size,n,fa[10010],p,m,minn,pre;
void dfs(int x)
{
//cout<<x<<" "<<f[0][x][0]<<endl;
if (!tr[x][0]) return;
int l=tr[x][0],r=tr[x][1];
dfs(l),dfs(r);
/*The part which gets complicated need help why and how this calculation works*/
for (int i=0;i<=minn;i++)
for (int j=0;i+j<=minn;j++)
{
f[0][x][i+j+(p<m)]=max(f[0][x][i+j+(p<m)],f[0][l][i]+f[0][r][j]);
f[0][x][i+j+(p>=m)]=max(f[0][x][i+j+(p>=m)],f[0][l][i]-f[1][r][j]);
f[1][x][i+j+(p<m)]=min(f[1][x][i+j+(p<m)],f[1][l][i]+f[1][r][j]);
f[1][x][i+j+(p>=m)]=min(f[1][x][i+j+(p>=m)],f[1][l][i]-f[0][r][j]);
}
}
int main()
{
scanf("%s",s+1);
scanf("%d%d",&p,&m);
memset(f[0],-63,sizeof(f[0]));
memset(f[1],63,sizeof(f[1]));
/* Why we have used min of the two and how does it handle both condition */
minn=min(p,m);
n=strlen(s+1);
size=1;pre=size;
for (int i=1;i<=n;i++)
{
if (s[i]=='('||s[i]=='?')
{
tr[pre][tr[pre][0]?1:0]=++size;
fa[size]=pre;
pre=size;
}
else if (s[i]==')') pre=fa[pre];
else f[0][size][0]=f[1][size][0]=s[i]-'0',pre=fa[pre];
}
dfs(1);
printf("%d",f[0][1][minn]);
}
The part where I get lost is this
f[0][x][i+j+(p<m)]=max(f[0][x][i+j+(p<m)],f[0][l][i]+f[0][r][j]);
f[0][x][i+j+(p>=m)]=max(f[0][x][i+j+(p>=m)],f[0][l][i]-f[1][r][j]);
f[1][x][i+j+(p<m)]=min(f[1][x][i+j+(p<m)],f[1][l][i]+f[1][r][j]);
f[1][x][i+j+(p>=m)]=min(f[1][x][i+j+(p>=m)],f[1][l][i]-f[0][r][j]);
I always struggle with such types of problems. Can someone give the link to approach such problems.
Which part of the lines don't you understood? I take one line
f[0][x][i+j+(p<m)]=max(f[0][x][i+j+(p<m)],f[0][l][i]+f[0][r][j]);
and rewrite it
const int index_max = 0;
int y = i+j + (p<m? 1: 0); // in your code p<m is cast to int, true=1, false=0
int old_max = f[index_max][x][y];
int next_value = f[index_max][l][i] + f[index_max][r][j]:
f[index_max][x][y] = max(old_max, next_value);
You are looking for the maximum of the next_values of your double-loop. As l, r are fixed the next_values are sums of values in two rows.
Similar for the other 3 lines.
First a little code:
int counter = 0;
int get_counter() { return counter++; }
#define EVEN_OR_ZERO(cc) ( (cc) % 2 == 0 ? (cc) : 0 )
int next_even_or_zero = EVEN_OR_ZERO(get_counter());
This code might seem OK, but... Let's expand the macro:
int next_even_or_zero = get_counter() % 2 == 0 ? get_counter() : 0;
As you can see the macro will only return odd numbers - which is the opposite of what was expected (or desired).
The question: Is there any way to get this work as intended with a macro? Or is a regular function the only way to go?
//This works as wanted
int even_or_zero(int value) { return value % 2 == 0 ? value : 0; }
#define EVEN_OR_ZERO(cc) even_or_zero(cc)
This may be the perfect answer or a bad joke, depending on why you need a macro, which you haven't told us.
The answer is simple: Don't use a macro, unless there's a good reason for it. This case isn't one of them:
int even_or_zero(int i) {
if (i % 2) {
return 0;
} else {
return i;
}
}
Make two functions.
int getCurrentCounter() { ... } // just return here
int getNextCounter() { ... } // increment here
This is how - in example - sequences is PSQL works.
Also, this seems like very bad code design.
don't use macros in C++, there are more better ways to achieve what you want (usally) without using them
functions with sideeffects on global variables are not that good. Think if it would not be better to create struct/class with it's counter and add methods to it. Or better yet, could hide methods as prive at set methods/class as their friends to limit who can affect counter.
There is an example on the FAQ to explain the difference between inline and #define. The code is here
and the link is: http://www.parashift.com/c++-faq/inline-vs-macros.html
Tried with Visual C++, both unsafe() and unsafe(f()) didn't increase i twice. Is there a mistake on the example?
The main idea of #define is that it is just a preprocessor directive, meaning that this:
#define unsafe(i) ( (i) >= 0 ? (i) : -(i) )
will preprocess your code before it is compiled, and will replace the statement
unsafe(x++);
with the following
((x++) >= 0 ? (x++) : -(x++));
Everytime x++ is evaluated, x gets incremented.
One possible reason why you have problems with getting this sample code right might be that you compile your code with optimizations that optimize out all the unused / unnecessary code.
If you don't use your x anywhere, then it is considered as unused, hence does not get included into compiled code.
Just tested the example, Check Eric Gopak's answer for the explanation:
// A macro that returns the absolute value of i
#define unsafe(i) \
((i) >= 0 ? (i) : -(i))
// An inline function that returns the absolute value of i
inline
int safe(int i)
{
return i >= 0 ? i : -i;
}
int countCalls = 0;
int f()
{
return countCalls++;
};
int main()
{
int x = 0;
int ans = 0;
ans = unsafe(x++); // Error! x is incremented twice
ans = unsafe(f()); // Danger! f() is called twice
// x = 2
// countCalls = 2
ans = safe(x++); // Correct! x is incremented once
ans = safe(f()); // Correct! f() is called once
// x = 3
// countCalls = 3
return 0;
}
This problem has annoyed me for years, and I'm wondering if anyone has had a solution. The problem is that in C++ mode, it seems like emacs cant decide if the < operator is "less than" or "begin template parameters", which messes up the auto-indent feature. Consider something like this:
bool foo() {
return X < Y &&
Y < Z;
}
That Y is way over to the right and if I run c-set-offset (with C-c C-o) on the line with Y < Z, it tells me that the current line offset is template-args-cont. The worst part is that any code below this, including other functions, will have totally screwed up tabbing. Usually I just carefully manually space the beginning of the next function.
EDIT: To confirm, the following code indents correctly:
bool foo() {
return X == Y &&
Y == Z;
}
EDIT 2: I have some custom style and offset stuff, but even starting emacs with -q to ignore my .emacs file shows the same problem. I'm currently using version:
GNU Emacs 24.1.1 (x86_64-apple-darwin, NS apple-appkit-1038.36)
of 2012-06-10 on bob.porkrind.org
On mac OS X 10.8 but I'm sure I've seen the same problem on ubuntu, but I'd have to go double check versions.
Has anyone found a solution to this? Corey discovered that adding parens (X < Y) is a workaround.
This looks more like C++ issue than that of cc-mode. The latter probably could use some smarter heuristics to handle simpler issues, like yours, but in general this less-than/template-open conflict is very hard to solve without knowing if X is a template.
Consider the following code:
#include <iostream>
using std::cout;
#ifdef TEMPLATE
template <int I>
int X(int arg)
{
return I + arg;
}
#else
int X = -1;
#endif
int main(int argc, char** argv)
{
const int Y = 0;
int foo = 1, bar = 2;
cout << (X < Y && 10 > (foo + bar)) << '\n';
return 0;
}
It prints 3 if #define TEMPLATE is into the source and 1 otherwise, and should you break the cout << ... line at &&-op there's no way to figure out proper indentation unless you know exact build environment for that file.