Is it possible to define a variable in expression in C++? - c++

I have this insane homework where I have to create an expression to validate date with respect to Julian and Gregorian calendar and many other things ...
The problem is that it must be all in one expression, so I can't use any ;
Are there any options of defining variable in expression? Something like
d < 31 && (bool leapyear = y % 4 == 0) || (leapyear ? d % 2 : 3) ....
where I could define and initialize one or more variables and use them in that one expression without using any ;?
Edit: It is explicitly said, that it must be a one-line expression. No functions ..
The way I'm doing it right now is writing macros and expanding them, so I end up with stuff like this
#define isJulian(d, m, y) (y < 1751 || (y == 1752 && (m < 9) || (m == 9 && d <= 2)))
#define isJulianLoopYear(y) (y % 4 == 0)
#define isGregorian(d, m, y) (y > 1573 || (y == 1752 && (m > 9) || (m == 9 && d > 13)))
#define isGregorianLoopYear(y) ((y % 4 == 0) || (y % 400 = 0))
// etc etc ....
looks like this is the only suitable way to solve the problem
edit: Here is original question
Suppose we have variables d m and y containing day, month and year. Task is to write one single expression which decides, if date is valid or not. Value should be true (non-zero value) if date is valid and false (zero) if date is not valid.
This is an example of expression (correct expression would look something like this):
d + 4 == y ^ 85 ? ~m : d * (y-2)
These are examples of wrong answers (not expressions):
if ( log ( d ) == 1752 ) m = 1;
or:
for ( i = 0; i < 32; i ++ ) m = m / 2;
Submit only file containing only one single expression without ; at the end. Don't submit commands or whole program.
Until 2.9.1752 was Julian calendar, after that date is Gregorian calendar
In Julian calendar is every year dividable by 4 a leap year.
In Gregorian calendar is leap year ever year, that is dividible by 4, but is not dividible by 100. Years that are dividable by 400 are another exception and are leap years.
1800, 1801, 1802, 1803, 1805, 1806, ....,1899, 1900, 1901, ... ,2100, ..., 2200 are not loop years.
1896, 1904, 1908, ..., 1996, 2000, 2004, ..., 2396,..., 2396, 2400 are loop years
In september 1752 is another exception, when 2.9.1752 was followed by 14.9.1752, so dates 3.9.1752, 4.9.1752, ..., 13.9.1752 are not valid.

((m >0)&&(m<13)&&(d>0)&&(d<32)&&(y!=0)&&(((d==31)&&
((m==1)||(m==3)||(m==5)||(m==7)||(m==8)||(m==10)||(m==12)))
||((d<31)&&((m!=2)||(d<29)))||((d==29)&&(m==2)&&((y<=1752)?((y%4)==0):
((((y%4)==0)&&((y%100)!=0))
||((y%400)==0)))))&&(((y==1752)&&(m==9))?((d<3)||(d>13)):true))

<evil>
Why would you define a new one, if you can reuse an existing one? errno is a perfect temporary variable.
</evil>

I think the intent of the homework is to ask you to do this without using variables, and what you are trying to do might defeat its purpose.

In standard C++, this is not possible. G++ has an extension known as statement expressions that can do that.

I don't believe you can, but even if you could, it would only have scope inside of the parentheses they are defined in (in your example) and cannot be used outside of them.

Your solution, which I will not provide fully for you, will probably go along these lines:
isJulian ? isJulianLeapyear : isGregorianLeapyear
To make it more specific, it could be like this:
isJulian ? (year % 4) == 0 : ((year % 4) == 0 || (year % 400) == 0)
You'll have to just make sure your algorithm is correct. I'm not a calender expert, so I wouldn't know about that.

First: Don't. It may be cute, but even if there's an extension that allows it, code golf is a dangerous game that will almost always end up causing mmore grief than it solves.
Okay, back to the 'real' question as defined by the homework. Can you make additional functions? If so, instead of capturing whether or not it's a leap year in a variable, make a function isLeapYear(int year) that returns the correct value.
Yes, that means you'll calculate it more than once. If that ends up being a performance issue, I'd be incredibly surprised... and it's a premature optimization to worry about that in the first place.
I'd be very surprised if you weren't allowed to write functions as part of doing this. It seems like that'd be half the point of an exercise like this.
......
Okay, so here's a quick overview of what you'll need to do.
First, basic verification - that month, day, year are possible values at all - month 0-11 (assuming 0-based), day 0-30, year non-negative (assuming that's a constraint).
Once you're past that, I'd probably check for the 1752 special cases.
If that's not relevant, the 'regular' months can be handled pretty simply.
This leaves us with the leap year cases, which can be broken down into two expressions - whether something is a leap year (which will be broken down additionally based on gregorian/julian), and whether the date is valid at that point.
So, at the highest level, your expression looks something like this:
areWithinRange(d,m,y) && passes1752SpecialCases(d,m,y) && passes30DayMonths(d,m,y) && passes31DayMonths(d,m,y) && passesFebruaryChecks(d,m,y)
If we assume that we only return false from our sub-expressions if we actively detect a rule break (31 days in June for the 30DayMonth rule returns false, but 30 days in February is irrelevant and so passes true), then we can pretty much say that the logic at that level is correct.
At this point, I'd write separate functions for the individual pieces (as pure expressions, a single return ... statement). Once you've gotten those in place, you can replace the method call in your top-level expression with the expanded version. Just make sure you parenthesize (is that a word?) everything sufficiently.
I'd also make a test harness program that uses the expression and has a number of valid and invalid inputs, and verifies that you're doing the right thing. You can write that in a function for ease of cut and paste for the final turn-in by doing something like:
bool isValidDate(int d, int m, int y)
{
return
// your expression here
}
Since the expression will be on a line by itself, it'll be easy to cut and paste.
You may find other ways to simplify your logic - excepting the 1752 special cases, days between 1 and 28 are always valid, for instance.

Considering it is homework, I think the best advice would be an approach to deriving your own solution.
If I were tackling this assignment, I would start by breaking the rules.
I would write a c++ function that given the variables d, m, and y, returns a boolean result on the validity of the date. I would use as many non-recursive helper functions as needed, and feel free to use if, else if, and else, but no looping aloud.
I would then Inline all helper functions
I would reduce all if, else if, and else statement to ? : notation
If I was successful at limiting my use of variables, I might be able to reduce all this to a single function with no variables - the body of which will contain the single expression I seek.
Good Luck.

You clearly have to have the date passed in somehow. Beyond that, all you're really going to be doing is chaining && and || (assuming we get the date as a tm struct):
#include <ctime>
bool validate(tm date)
{
return (
// sanity check that all values are positive
date.tm_mday >= 1 && date.tm_mon >= 0 && date.tm_year >= 0
// check for valid days
&& ((date.tm_mon == 0 && date.tm_mday <= 31)
|| (date.tm_mon == 1 && date.tm_mday <= (date.tm_year % 4 ? 28 : 29))
|| (date.tm_mon == 2 && date.tm_mday <= 31)
// yadda yadda for the other months
|| (date.tm_mon == 11 && date.tm_mday <= 31))
);
}
The parenthesis around date.tm_year % 4 ? 28 : 29 actually aren't needed, but I'm including them for readability.
UPDATE
Looking at a comment, you'll also need similar rules to validate dates that don't exist in the Gregorian calendar.
UPDATE II
Since you're dealing with dates in the past you will need to implement a more correct leap year test. However, I generally deal with dates in the future, and this incorrect leap year test will give correct results in 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060, 2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, and 2096. I will make a prediction that before this test fails in 2100 silicon-based computers will be forgotten relics. I seriously doubt we will use C++ on the quantum computers in use then. Besides, I won't be the programmer assigned to fix the bug.

Related

What am I misunderstanding when determining if a value is between two numbers?

I have a PDF form that adds up several different answers and displays the sum of these answer at the bottom of the page. I want to take that number, and have a sentence underneath it display three different options depending on the sum.
Greater than 60: Proceed
between 45 & 60: Consult Sales Lead
Less than 45: Decline
I am attempting to run a custom calculation script that takes the sum (which is named "total") and writes the above options, but I'm running into a myriad of errors.
My code I've written is below
var A = this.getField("total").value;
if (A >= 60){
event.value = "Proceed";
} else {
if (A <= 45){
event.value = "Decline";}
} else {
if (A < 60 && A > 45){
event.value = "Proceed, decision made with sales leader";}
}
If I were to only write the below block, I do not get any errors.
var A = this.getField("total").value;
if (A >= 60){
event.value = "Proceed";
}
I'm a newbie when it comes to most JavaScript, so any help is greatly appreciated! Thanks in advance!
I have based most of my code off of different search results from google. My main source
example 1
Below are a few other links I've referenced
example 2
example 3
You can leave away the
if (A < 60 && A > 45) {
line, because that condition is always true after the two previous conditions.
And then, it should work properly.
Just if you want to stay with that last condition, you would have to close it with a curly brace.
I think I managed to figure it out! For some reason, the addition of the "else" factor was causing syntax errors, so I tried it without and it seems to work as intended!
My code, for anyone that happens to find this, is the following:
var A = this.getField("total").value;
if (A >= 60) {event.value = "Proceed";}
if (A <= 59 && A >= 46) {event.value = "Proceed, decision made with sales leader";}
if (A <= 45) {event.value = "Decline";}
if (A == 0) {event.value = " ";}
Thanks to everyone that took a look at this, even if you didn't get to comment before I figured it out!

Can I use return to return to the start of an if statement?

I'm currently programming some homework, and we have to make a program that turns a hindu-arabic numeral into a roman numeral. I've already made the first part, where my teacher said we had to make sure the number is in between 1 and 3999. My algorithm so far is like this:
if (num-1000) > 0 {
add M to output
num -= 1000
return if
}
else {
(repeat for other digits, aka 500, 100, 50, and so on)
}
The problem is, I don't know if it's even possible. All the Stack Overflow pages I've seen say that I should use while statements for this, but since we haven't tackled while statements yet (even though I've self-learned it) we can't use while loops. So, can I use return to return to the start of an if statement?
What you are describing is a while. You can also achieve that with a go to but using that at this stage of learning would inspire some very very bad habits so I wholeheartedly discourage it. Another way you could do this is with recursion but that is an even more advance topic.
Given your restrictions (no loops, a number between 1 and 3999) I think you are supposed to use a bunch of ifs. Something like this pseudocode:
if (n >= 3000)
add 'M'
else if (n >= 2000)
add 'MM'
else if (n >= 1000)
add 'MMM'
n = n % 1000;
if (n >= 900)
add 'CM'
// and so on

Advice about how to make Z3 evaluate simple constraints faster

I'm trying to use Z3 (with C++ API) to check if lots of variable configurations satisfy my constraints, but I'm having big performance issues.
I'm looking for advice about which logic or parameter setting I might be able to use to improve the runtime, or hints about how I could try and feed the problem to Z3 in a different way.
Short description of what I'm doing and how I'm doing it:
//_______________Pseudocode and example_______________
context ctx()
solver s(ctx)
// All my variables are finite domain, maybe some 20 values at most, but usually less.
// They can only be ints, bools, or enums.
// There are not that many variables, maybe 10 or 20 for now.
//
// Since I need to be able to solve constraints of the type (e == f), where
// e and f are two different enum variables, all my
// enum types are actually contained in only one enumeration_sort(), populated
// with all the different values.
sort enum_sort = {"green", "red", "yellow", "blue", "null"}
expr x = ctx.int_const("x")
expr y = ctx.int_const("y")
expr b = ctx.bool_const("b")
expr e = ctx.constant("e", enum_sort)
expr f = ctx.constant("f", enum_sort)
// now I assert the finite domains, for each variable
// enum_value(s) is a helper function, that returns the matching enum expression
//
// Let's say that these are the domains:
//
// int x is from {1, 3, 4, 7, 8}
// int y is from {1, 2, 3, 4}
// bool b is from {0, 1}
// enum e is from {"green", "red", "yellow"}
// enum f is from {"red", "blue", "null"}
s.add(x == 1 || x == 3 || x == 3 || x == 7 || x == 8)
s.add(y == 1 || y == 2 || y == 3 || y == 4)
s.add(b == 0 || b == 1)
s.add(e == enum_value("green") || e == enum_value("red") || enum_value("yellow"))
s.add(f == enum_value("red") || f == enum_value("blue") || enum_value("null"))
// now I add in my constraints. There are also about 10 or 20 of them,
// and each one is pretty short
s.add(b => (x + y >= 5))
s.add((x > 1) => (e != f))
s.add((y == 4 && x == 1) || b)
// setup of the solver is now done. Here I start to query different combinations
// of values, and ask the solver if they are "sat" or "unsat"
// some values are left empty, because I don't care about them
expr_vector vec1 = {x == 1, y == 3, b == 1, e == "red"}
print(s.check(vec1))
expr_vector vec2 = {x == 4, e == "green", f == "null"}
print(s.check(vec2))
....
// I want to answer many such queries.
Of course, in my case this isn't hardcoded, but I read and parse the constraints, variables and their domains from files, then feed the info to Z3.
But it's slow.
Even for something like ten thousand queries, my program is already running over 10s. All of this is inside s.check(). Is it possible to make it run faster?
Hopefully it is, because what I'm asking of the solver doesn't look like it's overly difficult.
No quantifiers, finite domain, no functions, everything is a whole number or an enum, domains are small, the values of the numbers are small, there's only simple arithmetic, constraints are short, etc.
If I try to use parameters for parallel processing, or set the logic to "QF_FD", the runtime doesn't change at all.
Thanks in advance for any advice.
Is it always slow? Or does it get progressively slower as you query for more and more configurations using the same solver?
If it's the former, then your problem is just too hard and this is the price to pay. I don't see anything obviously wrong in what you've shown; though you should never use booleans as integers. (Just looking at your b variable in there. Stick to booleans as booleans, and integers as integers, and unless you really have to, don't mix the two together. See this answer for some further elaboration on this point: Why is Z3 slow for tiny search space?)
If it's the latter, you might want to create a solver from scratch for each query to clean-up all the extra stuff the solver created. While additional lemmas always help, they could also hurt performance if the solver cannot make good use of them in subsequent queries. And if you follow this path, then you can simply "parallelize" the problem yourself in your C++ program; i.e., create many threads and call the solver separately for each problem, taking advantage of many-cores your computer no doubt has and OS-level multi-tasking.
Admittedly, this is very general advice and may not apply directly to your situation. But, without a particular "running" example that we can see and inspect, it's hard to be any more specific than this.
Some Ideas:
1. Replace x == 1 || x == 3 || x == 3 || x == 7 || x == 8 with (1 <= x && x <= 8) && (x <= 1 || (3 <= x) && (x <= 4 || 7 <= x). Similar change with y.
rationale: the solver for linear arithmetic now knows that x is always confined in the interval [1,8], this can be useful information for other linear equalities/inequalities; it may be useful to also learn the trivial mutual exclusion constraints not(x <= 1) || not(3 <= x) and not(x <= 4) || not(7 <= x); there are now exactly 3 boolean assignments that cover your original 5 cases, this makes the reasoning of the linear arithmetic solver more cost-efficient because each invocation deals with a larger chunk of the search space. (Furthermore, it is more likely that clauses learned from conflicts are going to be useful with subsequent calls to the solver)
(Your queries may also contain set of values rather than specific assignments of values; this may allow one to prune some unsatisfiable ranges of values with fewer queries)
2. Just like #alias mentioned, Boolean variables ought to be Booleans and not 0/1 Integer variables. The example you provided is a bit confusing, b is declared as a bool const but then you state b == 0 || b == 1
3. I am not familiar with the enum_sort of z3, meaning that I don't know how it is internally encoded and what solving techniques are applied to deal with it. Therefore, I am not sure whether the solver may try to generate trivially inconsistent truth-assignments in which e == enum_value("green") e e == enum_value("red") are both assigned to true at the same time. This might be worth a bit of investigation. For instance, another possibility could be to declare e and f as Int and give them an appropriate interval domain (as contiguous as possible) with the same approach shown in 1., that will be interpreted by your software as a list of enum values. This should remove a number of Boolean assignments from the search space, make conflict clauses more effective and possibly speed-up the search.
4. Given the small number of problem variables, values and constraints, I would suggest you to try to encode everything using just the Bit-Vector theory and nothing else (using small-but-big-enough domains). If you then configure the solver to encode Bit-Vectors eagerly, then everything is bit-blasted into SAT, and z3 should only use Boolean Constraint Propagation for satisfiability, which is the cheapest technique.
This might be an X Y problem, why are you performing thousands of queries, what are you trying to achieve? Are you trying to explore all possible combination of values? Are you trying to perform model counting?

Having an issue with stopping a loop in Stata

So, I have a bunch of variables in my data set which are binary and contain information on whether an individual was married or not. So, for example, marr79, is whether a person was married in 1979 or not.
I'm trying to find how many years a person was married (the first time) from the child's birth. So, if the child was born in 1980, and the person was married in 1980, it would add to child_marr, and it would do the same for the following 18 years of their life. I want it to stop, though, if it encounters a 0. So if there are 1's for 1980, 1981, and 1982, and a 0 for 1983, I want it to stop at 1983, even if there is a 1 in 1984.
My code below (and it is one of many iterations I've tried) either has it run through all the years without stopping, or never run at all, leaving values of all 0.
Any help is appreciated.
gen child_marr=0;
forvalues y=79(1)99 {;
gen temp_yr=1900+`y';
if (ch_yob<=temp_yr & marr`y'==1 & temp_yr<(ch_yob+18))==1 {;
replace child_marr = child_marr + 1;
};
else if (marr`y'==0 & ch_yob<=temp_yr) {;
continue, break;
};
drop temp_yr;
};
A few comments:
Your condition if (test1 & test2 & test3) == 1 does not need the == 1 portion -- Stata infers that if (condition) means if condition == 1 (caveat: for cases where the logical test is {0,1}).
There is no need to generate a temporary variable, since you can compare the value of a variable to a local macro directly.
To the issue at hand, your loop is comparing observation-level criteria (e.g., the value of the variable temp_yr to the value of the variable ch_yob). This can seem correct, but is often problematic -- see Stata FAQ: if command versus if qualifier.
A first pass at a solution would be to recode your forvalues loop to use the if qualifier rather than the if command:
gen child_marr = 0
forvalues y = 79/99 {
local yr = 1900 + `y'
replace child_marr = child_marr + 1 if (ch_yob <= `yr') & (marr`y' == 1) & (`yr' < (ch_yob + 18))
}
But as mentioned, a concrete solution would be easier with a reproducible example.

Chaining Bool values give opposite result to expected

Unthinkingly I wrote some code to check that all the values of a struct were set to 0. To accomplish this I used:
bool IsValid() {
return !(0 == year == month == day == hour == minute == second);
}
where all struct members were of type unsigned short. I used the code as part of a larger test but noticed that it was returning false for values differing from zero, and true for values that were all equal to zero - the opposite of what I expected.
I changed the code to read:
bool IsValid() {
return (0 != year) || (0 != month) || (0 != day) || (0 != hour) || (0 != minute) || (0 != second);
}
But would like to know what caused the odd behaviour. Is it a result of precedence? I've tried to Google this answer but found nothing, if there's any nomenclature to describe the result I'd love to know it.
I compiled the code using VS9 and VS8.
== groups from left to right, so if all values are zero then:
0 == year // true
(0 == year) == month // false, since month is 0 and (0 == year) converts to 1
((0 == year) == month) == day // true
And so on.
In general, x == y == z is not equivalent to x == y && x == z as you seem to expect.
The behaviour shouldn't be seen as odd. The grammar rules for == (and most but not all binary operators) specify left to right grouping so your original expression is equivalent to:
!((((((0 == year) == month) == day) == hour) == minute) == second)
Note that when compared to an integer type a bool expression with value true will promote to 1 and with value false will promote to 0. (In C the result of the equality operator is an int in any case with a value or either 1 or 0.)
This means that, for example, ((0 == year) == month) will be true if year is zero and month is one or if year is non-zero but month is zero and false otherwise.
You have to consider how it's evaluated...
a == b == c
is asking if two of them are equal (a and b), then comparing that boolean result to the third value c! It is NOT comparing the first two values with the third. Anything beyond 2 arguments won't chain as you evidently expect.
For whatever it's worth, because C++ considers non-0 values to be "true" in a boolean context, you can express what you want simply as:
return year && month && day && hour && minute && second;
(note: your revised code says "month" twice and doesn't test minute).
Back to the chained ==s: with user-defined types and operator overloading you can create a class that compares as you expect (and it can even allow things like 0 <= x < 10 to "work" in the way it's read in mathematics), but creating something special will just confuse other programmers who already know the (weird) way these things work for builtin types in C++. Worth doing as a ten/twenty minute programming exercise though if you're keen to learn C++ in depth (hint: you need the comparison operators to return a proxy object that remembers what will be the left-hand-side value for the next comparison operator).
Finally, sometimes these "weird" boolean expressions are useful: for example, a == b == (c == d) might be phrased in English as "either (a == b) and (c == d), OR (a != b) and (c != d)", or perhaps "the equivalence of a and b is the same as the equivalence of c and d (whether true or false doesn't matter)". That might model real world situations like a double-dating scenario: if a likes/dislikes b (their date) as much as c likes/dislikes d, then they'll either hang around and have a nice time or call it quits quickly and it's painless either way... otherwise one couple will have a very tedious time of it.... Because these things can make sense, it's impossible for the compiler to know you didn't intend to create such an expression.
Your error here is writing a mathematical expression using equals signs, and unthinkingly supposing that the computer will perform the test you meant - what a human mathematician would see as the meaning of those symbols. What the computer does (as per the definition of the language) is to perform a series of discrete comparisons, each of which returns true or false - and this true or false is then used in the next comparison. You aren't comparing all of those variables to 0, you're comparing each (bar two of them) to the result of comparing another two of the said variables.
The return of the == operator is 1 if the operands are equal, so regardless wether this is read from left to right or right to left, this will not do what you expect.
so this could only work in an analogous test if you would be interested if all values are 1.
And to have a shorter expression since you seem interested in that just do year || day || ...