Defining logical operator implies in lua - if-statement

print("i", "j", "i & j")
for i = 0,1 do
for j=0,1 do
print(i, j, i & j)
end
end
The above code works fine in Lua. It gives the following output.
i j i & j
0 0 0
0 1 0
1 0 0
1 1 1
I want to define another operator implies. It is conditional logical operator. The result p implies q is false only when p is true and q is false.
print("i", "j", "i implies j")
for i = 0,1 do
for j=0,1 do
print(i, j, i implies j)
end
end
I want the above code to work. It should output the following.
i j i implies j
0 0 1
0 1 1
1 0 0
1 1 1
So far I have succeeded in defining implies function but that doesn't seem to be of great use. Of course I can write implies(i,j) but I want operator similar to & or | that I can use. So basic question is to replicate definition of logical operator & or | from lua. Here is the code for implies function (not operator).
function implies(a,b)
if a then
return b
else
return True
end
end

OOP-style calls
This gets rather hacky if it must truly be infix. What about simply using metatables for OOP-ish object:method(params) syntax?
Assuming implies is defined as
local function _implies(a, b)
if a ~= 0 then return b end
return 1
end
this would be implemented as
debug.setmetatable(0, {__index = {
implies = _implies
}})
and used as
i:implies(j)
if you want you a simpler dot syntax instead, consider using currying:
debug.setmetatable(0, {__index = {
implies = function(a) return function(b) return _implies(a, b) end end
}})
used as
i.implies(j)
A more "infix-ish" notation might be achieved by using the __call metamethod, and passing a function name:
debug.setmetatable(0, {__index = {
implies = function(a) return function(b) return _implies(a, b) end end
}, __call = function(self, index) return self[index] end})
(i)("implies")(j)
If implies = "implies", this can even be shortened to (i)(implies)(j).
Hacky, "truly" infix notation
If infix notation is of utmost importance, yet you can't use the available metamethods as they are limited and rather unreadable, you can use even more currying and workarounds to use other metamethods to create operators that seemingly turn your function (at least syntactically) into an infix operator using a "proxy" metatable instead of the function. You can use whatever operators you like; just make sure they suit your needs in terms of associativity and precedency:
local implies_right_hand_mt = {
__mul = function(self, b)
return _implies(self.a, b)
end
}
local implies_left_hand = setmetatable({}, {
__mul = function(a)
return setmetatable({a = a}, implies_right_hand_mt)
end
})
implies = implies_left_hand
The syntax would then be i *implies* j or "i *implies* j" in your example (using the multiplication operator). You could however use all other operators (except the comparison operators) as well, including other arithmetic operators, as implies is not a number but rather a table and may thus override number metamethods.
Side note
Consider using booleans instead of numbers. You'd get two advantages:
Most metamethods aren't used by booleans (especially all arithmetic & bitwise metamethods);
The logic operators not, and and or work; you don't have to use bitwise operators (although those work fine as well).

There are two metamethods available for "number" datatype: __call and __index.
debug.setmetatable(0, {__call = function(a, b) return a~1|b end})
-- Now you can use "(i)(j)" for "i implies j"
print("i", "j", "(i)(j)")
for i = 0,1 do
for j = 0,1 do
print(i, j, (i)(j))
end
end

Lua has no provision for user-defined operators.
CustomOperators
But if i and j were boolean, you could use:
i and j or true
It doesn't work with 0 and 1, because for LUA they are both true!

Related

How to convert C to C++?

How can I convert C code to C++? When I try my best, I failed every time.
Can anyone help me?
In particular, I'm trying to understand the following:
v=v%10?v%(5*r)*n--:v/10
I know if v == v mod 10,v%(5*r)*n--. if not, v/10. But I don't understand v%(5*r)*n--.
Here's the code in context:
long v=1,r=1e9;
main(n){
for(scanf("%d",&n);v=v%10?v%(5*r)*n--:v/10;n||printf("%d",v%r));
}
This C expression is also valid in C++. Expression v%(5*r)*n-- is equivalent to expression v % ((5*r)*(n--)) due to operator precedence rules. Postfix decrement operator --(it decreases a variable by one) will evaluate first, what remains is an expression of type A % B * C. Since operators % (remainder) and * (multiplication) are on the same precedence level, left to right associativity rule will be applied. Therefore, we have v % ((5*r)*(n--)). For more information check out these links:
http://en.cppreference.com/w/cpp/language/operator_precedence
https://en.wikipedia.org/wiki/Operator_associativity
You also do no understand the ternary operator. In your case, the whole statement v=v%10?v%(5*r)*n--:v/10 means: if v%10 is true (different from zero) then assign result of v%(5*r)*n-- to variable v, otherwise assign result of v/10 to variable v. For more information check out
http://www.cprogramming.com/reference/operators/ternary-operator.html
Btw, please note that the person writing this blog produces some awful code. You probably do not want to learn from it.
Your definition for main is bad. C++ does not allow implicit typing for functions1, and main takes either zero or two arguments; it should be written as
int main( int argc, char **argv )
{
...
}
if the program takes any command line arguments2 and
int main( void )
{
...
}
if it doesn't3.
The expression v=v%10?v%(5*r)*n--:v/10 is equally valid (if unspeakably ugly) in C and C++, so that's not an issue.
The expression n||printf("%d",v%r) is a bit of a head-scratcher, though; what do you think it's trying to accomplish?
Edit
Sorry, wasn't quite awake when I wrote that last bit. Obviously, the intent of that expression is to only write the value of v%r when n is 0.
The || is the logical-or operator - the expression a || b evaluates to 1 if either a or b is non-zero, or 0 if both a and b are zero. The operator short-circuits; if a is non-zero, then the result of a || b is 1 regardless of the value of b, so b won't be evaluated at all.
Thus, in the expression n || printf( "%d", v%r ), if n is non-zero, then the printf call won't be executed.
Note that the line
for(scanf("%d",&n);v=v%10?v%(5*r)*n--:v/10;n||printf("%d",v%r));
is hideous; even with some whitespace it would be hard to follow and debug. This should not be taken as an example of good code. That style of programming is only suitable for the IOCCC, except that it's not ugly enough for that particular competition.
A better way to write it for C++ would be
#include <iostream>
int main( void )
{
long v=1,r=1e9; // no reason to make these global
int n;
if ( std::cin >> n )
{
while ( v ) // v != 0
{
if ( v % 10 )
v = v % (5 * r) * n--; // whitespace is your friend, use it
else
v = v / 10;
if ( n ) // n != 0
std::cout << v % r;
}
}
else
{
std::cerr << "Error while reading \"n\"...try again" << std::endl;
}
return 0;
}
1. Neither does C since the 1999 standard, and it's bad practice anyway.
2. You don't have to use the names argc and argv, although they are the common convention.
3. Implementations may provide additional signatures for main (such as extra arguments in addition to argc and argv), but those additional signatures must be documented; don't assume any random signature is going to be valid.

Postfix operators in while loops

I was looking through some C++ code today when I stumbled upon this:
while (c--) {
a = (a + 1) % n;
while(arr[a]) a = (a + 1) % n;
}
c was an integer. Don't while loops take boolean expressions to be evaluated? I know 1 and 0 are fine because they represent true and false, respectively, but in this case c was taking on values other than 0 and 1. What does this do?
Anything that isn't 0 is considered true, so this would loop until C=0.
Could just be a simple case of "using less code"

Operator Precedence

I have a sample midterm question that I am not too sure about. Here it is:
#include <iostream.h>
void f( int i )
{
if( i = 4 || i = 5 ) return;
cout << "hello world\n" ;
}
int main()
{
f( 3 );
f( 4 );
f( 5 );
return 0;
}
So I understand that the logical OR operator has a higher precedence and that it is read left to right. I also understand that what's being used is an assignment operator instead of the relational operator. I just dont get how to make sense of it all. The first thing the compiler would check would be 4 || i? How is that evaluated and what happens after that?
Let's add all the implied parentheses (remembering that || has higher precedence than = and that = is right-associative):
i = ((4 || i) = 5)
So, it first evaluates 4 || i, which evaluates to true (actually, it even ignores i, since 4 is true and || short-circuits). It then tries to assign 5 to this, which errors out.
As written, the code doesn't compile, since operator precedence means it's i = ((4 || i) = 5) or something, and you can't assign to a temporary value like (4 || i).
If the operations are supposed to be assignment = rather than comparison == for some reason, and the assignment expressions are supposed to be the operands of ||, then you'd need parentheses
(i = 4) || (i = 5)
As you say, the result of i=4 is 4 (or, more exactly, an lvalue referring to i, which now has the value 4). That's used in a boolean context, so it's converted to bool by comparing it with zero: zero would become false, and any other value becomes true.
Since the first operand of || is true, the second isn't evaluated, and the overall result is true. So i is left with the value 4, then the function returns. The program won't print anything, whatever values you pass to the function.
It would make rather more sense using comparison operations
i == 4 || i == 5
meaning the function would only print something when the argument is neither 4 nor 5; so it would just print once in your example, for f(3).
Note that <iostream.h> hasn't been a standard header for decades. You're being taught an obsolete version of the language, using some extremely dubious code. You should get yourself a good book and stop wasting time on this course.
The compiler shall isuue an error because expression 4 || i is not a lvalue and may not be assigned.
As for the expression itself then the value of it is always equal to true because 4 is not equal to zero.

What is this syntax in while loop condition?

while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
I came across this on codegolf
Please explain the usage of ? and : and why is there no statement following the while loop? As in why is there a ; after the parenthesis.
There is a boolean operation going on inside the parentheses of the while loop:
while (boolean);
Since the ternary operator is a boolean operator, it's perfectly legal.
So what's this doing? Looks like modular arithmetic, printing going on over a range up to 101.
I'll agree that it's cryptic and obscure. It looks more like a code obfuscation runner up. But it appears to be compilable and runnable. Did you try it? What did it do?
The ?: is a ternary operator.
An expression of form <A> ? <B> : <C> evaluates to:
If <A> is true, then it evaluates to <B>
If <A> is false, then it evaluates to <C>
The ; after the while loop indicates an empty instruction. It is equivalent to writing
while (<condition>) {}
The code you posted seems like being obfuscated.
Please explain the usage of ? and :
That's the conditional operator. a ? b : c evaluates a and converts it to a boolean value. Then it evaluates b if its true, or c if its false, and the overall value of the expression is the result of evaluating b or c.
So the first sub-expression:
assigns t-i%10 to i. The result of that expression is the new value of i.
if i is not zero, the result of the expression is i/10
otherwise, print j, and the result of the expression is zero (since printf returns a non-zero count of characters printed, which ! converts to zero).
Then the second sub-expression, after ||, is only evaluated if the result of the first expression was zero. I'll leave you to figure out what that does.
why is there no statement following the while loop?
There's an empty statement, ;, so the loop body does nothing. All the action happens in the side effects of the conditional expression. This is a common technique when the purpose of the code is to baffle the reader; but please don't do this sort of thing when writing code that anyone you care about might need to maintain.
This is the Conditional Operator (also called ternary operator).
It is a one-line syntax to do the same as if (?) condition doA else (:) doB;
In your example:
(i=t-i%10 ? i/10 : !printf("%d\n",j)
Is equivalent to
if (i=t-i%10)
i/10;
else
!printf("%d\n",j);
?: is the short hand notation for if then else
(i=t-i%10 ? i/10 : !printf("%d\n",j)<br>
equals to
if( i= t-i%10 )
then { i/10 }
else { !printf("%d\n",j) }
Your while loop will run when the statement before the || is true OR the statement after the || is true.
notice that your code does not make any sense.
while ( (i=t-i%10 ? i/10 : !printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
in the most human-readable i can do it for u, it's equivalent to:
while (i < 101)
{
i = (t - i) % 10;
if (i > 0)
{
i = i / 10;
}
else
{
printf("%d\n",j);
}
i = ++j;
if (i < 0)
{
i = i - j;
}
else
{
i = j;
}
}
Greetings.
I am the proud perpetrator of that code. Here goes the full version:
main()
{
int t=getchar()-48,i=100,j=-i;
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
}
It is my submission to a programming challenge or "code golf" where you are asked to create the tinniest program that would accept a digit as a parameter and print all the numbers in the range -100 to 100 that include the given digit. Using strings or regular expressions is forbidden.
Here's the link to the challenge.
The point is that it is doing all the work into a single statement that evaluates to a boolean. In fact, this is the result of merging two different while loops into a single one. It is equivalent to the following code:
main()
{
int i,t=getchar()-'0',j=-100;
do
{
i = j<0? -j : j;
do
{
if (t == i%10)
{
printf("%d\n",j);
break;
}
}
while(i/=10);
}
while (j++<100);
}
Now lets dissect that loop a little.
First, the initialisation.
int t=getchar()-48,i=100,j=-i;
A character will be read from the standard input. You are supposed to type a number between 0 and 9. 48 is the value for the zero character ('0'), so t will end up holding an integer between 0 and 9.
i and j will be 100 and -100. j will be run from -100 to 100 (inclusive) and i will always hold the absolute value of j.
Now the loop:
while ((i=t-i%10?i/10:!printf("%d\n",j)) || (i=++j<0?-j:j)<101 );
Let's read it as
while ( A || B ) /* do nothing */ ;
with A equals to (i=t-i%10?i/10:!printf("%d\n",j)) and B equals to (i=++j<0?-j:j)<101
The point is that A is evaluated as a boolean. If true, B won't be evaluated at all and the loop will execute again. If false, B will be evaluated and in turn, if B is true we'll repeat again and once B is false, the loop will be exited.
So A is the inner loop and B the outer loop. Let's dissect them
(i=t-i%10?i/10:!printf("%d\n",j))
It's a ternary operator in the form i = CONDITION? X : Y; It means that first CONDITION will be evaluated. If true, i will be set to the value of X; otherwise i will be set to Y.
Here CONDITION (t-i%10) can be read as t - (i%10). This will evaluate to true if i modulo 10 is different than t, and false if i%10 and t are the same value.
If different, it's equivalent to i = i / 10;
If same, the operation will be i = !printf("%d\n",j)
If you think about it hard enough, you'll see that it's just a loop that checks if any of the decimal digits in the integer in i is equal to t.
The loop will keep going until exhausting all digits of i (i/10 will be zero) or the printf statement is run. Printf returns the number of digits printed, which should always be more than zero, so !printf(...) shall always evaluate to false, also terminating the loop.
Now for the B part (outer loop), it will just increment j until it reaches 101, and set i to the absolute value of j in the way.
Hope I made any sense.
Yes, I found this thread by searching for my code in google because I couldn't find the challenge post.

Effect of using a comma instead of a semi-colon in C and C++

I've noticed on a number of occasions when refactoring various pieces of C and C++ code that a comma is used rather than a semi-colon to seperate statements. Something like this;
int a = 0, b = 0;
a = 5, b = 5;
Where I would have expected
int a = 0, b = 0;
a = 5; b = 5;
I know that C and C++ allow use of commas to seperate statements (notably loop headers), but what is the difference if any between these two pieces of code? My guess is that the comma has been left in as the result of cut & pasting, but is it a bug and does it effect execution?
It doesn't make a difference in the code you posted. In general, the comma separates expressions just like a semicolon, however, if you take the whole as an expression, then the comma operator means that the expression evaluates to the last argument.
Here's an example:
b = (3, 5);
Will evaluate 3, then 5 and assign the latter to b. So b = 5. Note that the brackets are important here:
b = 3, 5;
Will evaluate b = 3, then 5 and the result of the whole expression is 5, nevertheless b == 3.
The comma operator is especially helpful in for-loops when your iterator code is not a simple i++, but you need to do multiple commands. In that case a semicolon doesn't work well with the for-loop syntax.
The comma is a operator that returns a value which is always the 2nd (right) argument while a semicolon just ends statements. That allows the comma operator to be used inside other statements or to concatenate multiple statements to appear as one.
Here the function f(x) gets called and then x > y is evaluated for the if statement.
if( y = f(x), x > y )
An example when it's used just to avoid a the need for block
if( ... )
x = 2, y = 3;
if( ... ) {
x = 2;
y = 3;
}
The comma operator evaluates all operands from left to right, and the result is the value of the last operand.
It is mostly useful in for-loops if you want to do multiple actions in the "increment" part, e.g (reversing a string)
for (int lower = 0, upper = s.size() - 1; lower < upper; ++lower, --upper)
std::swap(s[lower], s[upper]);
Another example, where it might be an option (finding all occurrences in a string):
#include <string>
#include <iostream>
int main()
{
std::string s("abracadabra");
size_t search_position = 0;
size_t position = 0;
while (position = s.find('a', search_position), position != std::string::npos) {
std::cout << position << '\n';
search_position = position + 1;
}
}
In particular, logical and cannot be used for this condition, since both zero and non-zero can mean that the character was found in the string. With comma, on the other hand, position = s.find() is called each time when the condition is evaluated, but the result of this part of the condition is just ignored.
Naturally there are other ways to write the loop:
while ((position = s.find('a', search_position)) != std::string::npos)
or just
while (true) {
position = s.find('a', search_position);
if (position == std::string::npos)
break;
...
}
As Frank mentioned, how the comma operator is used in your example doesn't cause a bug. The comma operator can be confusing for several reasons:
it's not seen too often because it's only necessary in some special situations
there are several other syntactic uses of the comma that may look like a comma operator - but they aren't (the commas used to separate function parameters/arguments, the commas used to separate variable declarations or initializers)
Since it's confusing and often unnecessary, the comma operator should be avoided except for some very specific situations:
it can be useful to perform multiple operation in one or more of a for statement's controlling expressions
it can be used in preprocessor macros to evaluate more than one expression in a single statement. This is usually done to allow a macros to do more than one thing and still be a a single expression so the macro will 'fit' in places that only allow an expression.
The comma operator is a hackish operator pretty much by definition - it's to hack in 2 things where only one is allowed. It's almost always ugly, but sometimes that's all you've got. And that's the only time you should use it - if you have another option, don't use the comma operator.
Off the top of my head I can't think of too many other reasons to use the operator, since you can get a similar effect by evaluating the expressions in separate statements in most other situations (though I'm sure that someone will comment on a another use that I've overlooked).
One usage would be in code golfing:
if (x == 1) y = 2, z = 3;
if (x == 1) { y = 2; z = 3; }
The first line is shorter, but that looks too confusing to use in regular development.