Algorithm to evaluate value of Boolean expression - boolean

I had programming interview which consisted of 3 interviewers, 45 min each.
While first two interviewers gave me 2-3 short coding questions (i.e reverse linked list, implement rand(7) using rand(5) etc ) third interviewer used whole timeslot for single question:
You are given string representing correctly formed and parenthesized
boolean expression consisting of characters T, F, &, |, !, (, ) an
spaces. T stands for True, F for False, & for logical AND, | for
logical OR, ! for negate. & has greater priority than |. Any of these
chars is followed by a space in input string. I was to evaluate value
of expression and print it (output should be T or F). Example: Input:
! ( T | F & F ) Output: F
I tried to implement variation of Shunting Yard algorithm to solve the problem (to turn input in postfix form, and then to evaluate postfix expression), but failed to code it properly in given timeframe, so I ended up explaining in pseudocode and words what I wanted.
My recruiter said that first two interviewers gave me "HIRE", while third interviewer gave me "NO HIRE", and since the final decision is "logical AND", he thanked me for my time.
My questions:
Do you think that this question is appropriate to code on whiteboard in approx. 40 mins? To me it seems to much code for such a short timeslot and dimensions of whiteboard.
Is there shorter approach than to use Shunting yard algorithm for this problem?

Well, once you have some experience with parsers postfix algorithm is quite simple.
1. From left to right evaluate for each char:
if its operand, push on the stack.
if its operator, pop A, then pop B then push B operand A onto the stack. Last item on the stack will be the result. If there's none or more than one means you're doing it wrong (assuming the postfix notation is valid).
Infix to postfix is quite simple as well. That being said I don't think it's an appropriate task for 40 minutes if You don't know the algorithms. Here is a boolean postfix evaluation method I wrote at some stage (uses Lambda as well):
public static boolean evaluateBool(String s)
{
Stack<Object> stack = new Stack<>();
StringBuilder expression =new StringBuilder(s);
expression.chars().forEach(ch->
{
if(ch=='0') stack.push(false);
else if(ch=='1') stack.push(true);
else if(ch=='A'||ch=='R'||ch=='X')
{
boolean op1 = (boolean) stack.pop();
boolean op2 = (boolean) stack.pop();
switch(ch)
{
case 'A' : stack.push(op2&&op1); break;
case 'R' : stack.push(op2||op1); break;
case 'X' : stack.push(op2^op1); break;
}//endSwitch
}else
if(ch=='N')
{
boolean op1 = (boolean) stack.pop();
stack.push(!op1);
}//endIF
});
return (boolean) stack.pop();
}
In your case to make it working (with that snippet) you would first have to parse the expression and replace special characters like "!","|","^" etc with something plain like letters or just use integer char value in your if cases.

Related

Checking whether values are Upper case or lower case

I'm trying to build a function in q/kdb+ that can detect whether the string passed to the function is Upper case (True) OR lower case (false)
I have done several attempts but I'm constantly hitting a road block
Here's my function, would appreciate the help. TIA
isAllCaps: {[input] if[input = lower; show 0b; show 1b]}
The above function basically takes an input as specified. It then checks from the if statement whether it is lower, if it is lower then it should return a false(0b), if not then return a true (1b). Really struggling with something so simple here. I'm just getting the following error:
evaluation error:
type
[1] isAllCaps:{[input] if[input = lower; show 0b; show 1b]}
^
[0] isAllCaps"a"
I have also tried other methods but only certain inputs were coming out to be successful.
For instance:
isAllCaps: {[x] if[ x = upper type 10h; show 1b; show 0b]}
This equates to if x is upper type string, show true, else show false. Again, getting a type error. Idk why? All the tests are in strings i.e., "John_Citizen" etc. etc.
EDIT
Tried this but I'm getting 2 outputs.
isAllCaps: {[L] if[L = lower L; show 0b; show 1b] } Am I missing something?
Try following code:
isAllCaps: {[L] show L~upper L};
It shows 1b if string is uppercase, and 0b otherwise.
There are 2 mistakes in you code
~ should be used to compare strings. = does character-wise comparison. I.e. "aa"~"aa" gives 1b, but "aa"="aa" gives 11b
Use if-else, instead of if. See 10.1.1 Basic Conditional Evaluation for more details
You can use the in-built uppercase alphabet .Q.A to achieve what you want:
{all x in .Q.A}
This lambda will return 1b if the input string consists only of capital letters and false otherwise.
Start by removing some misapprehensions.
lower returns the lower case of its argument.
show displays and returns its result. You can use it as you have to ensure the function’s result is printed on the console, but it is not required as, for example return would be in JavaScript.
If you have a boolean as the result of a test, that can just be your result.
Compare strings for equality using Match ~ rather than Equals
That said, two strategies: test for lower-case chars .Q.a, or convert to upper case and see if there is a difference.
q){not any x in .Q.a}"AAA_123"
1b
q){not any x in .Q.a}"AaA_123"
0b
The second strategy could hardly be simpler to write:
q){x~upper x}"AaA_123"
0b
q){x~upper x}"AAA_123"
1b
Together with the Apply . operator, the Zen monks construction gives you fast ‘point-free’ code – no need for a lambda:
q).[~] 1 upper\"AaA_123"
0b
q).[~] 1 upper\"AAA_123"
1b

Does pattern match in Raku have guard clause?

In scala, pattern match has guard pattern:
val ch = 23
val sign = ch match {
case _: Int if 10 < ch => 65
case '+' => 1
case '-' => -1
case _ => 0
}
Is the Raku version like this?
my $ch = 23;
given $ch {
when Int and * > 10 { say 65}
when '+' { say 1 }
when '-' { say -1 }
default { say 0 }
}
Is this right?
Update: as jjmerelo suggested, i post my result as follows, the signature version is also interesting.
multi washing_machine(Int \x where * > 10 ) { 65 }
multi washing_machine(Str \x where '+' ) { 1 }
multi washing_machine(Str \x where '-' ) { -1 }
multi washing_machine(\x) { 0 }
say washing_machine(12); # 65
say washing_machine(-12); # 0
say washing_machine('+'); # 1
say washing_machine('-'); # -1
say washing_machine('12'); # 0
say washing_machine('洗衣机'); # 0
TL;DR I've written another answer that focuses on using when. This answer focuses on using an alternative to that which combines Signatures, Raku's powerful pattern matching construct, with a where clause.
"Does pattern match in Raku have guard clause?"
Based on what little I know about Scala, some/most Scala pattern matching actually corresponds to using Raku signatures. (And guard clauses in that context are typically where clauses.)
Quoting Martin Odersky, Scala's creator, from The Point of Pattern Matching in Scala:
instead of just matching numbers, which is what switch statements do, you match what are essentially the creation forms of objects
Raku signatures cover several use cases (yay, puns). These include the Raku equivalent of the functional programming paradigmatic use in which one matches values' or functions' type signatures (cf Haskell) and the object oriented programming paradigmatic use in which one matches against nested data/objects and pulls out desired bits (cf Scala).
Consider this Raku code:
class body { has ( $.head, #.arms, #.legs ) } # Declare a class (object structure).
class person { has ( $.mom, $.body, $.age ) } # And another that includes first.
multi person's-age-and-legs # Declare a function that matches ...
( person # ... a person ...
( :$age where * > 40, # ... whose age is over 40 ...
:$body ( :#legs, *% ), # ... noting their body's legs ...
*% ) ) # ... and ignoring other attributes.
{ say "$age {+#legs}" } # Display age and number of legs.
my $age = 42; # Let's demo handy :$var syntax below.
person's-age-and-legs # Call function declared above ...
person # ... passing a person.
.new: # Explicitly construct ...
:$age, # ... a middle aged ...
body => body.new:
:head,
:2arms,
legs => <left middle right> # ... three legged person.
# Displays "42 3"
Notice where there's a close equivalent to a Scala pattern matching guard clause in the above -- where * > 40. (This can be nicely bundled up into a subset type.)
We could define other multis that correspond to different cases, perhaps pulling out the "names" of the person's legs ('left', 'middle', etc.) if their mom's name matches a particular regex or whatever -- you hopefully get the picture.
A default case (multi) that doesn't bother to deconstruct the person could be:
multi person's-age-and-legs (|otherwise)
{ say "let's not deconstruct this person" }
(In the above we've prefixed a parameter in a signature with | to slurp up all remaining structure/arguments passed to a multi. Given that we do nothing with that slurped structure/data, we could have written just (|).)
Unfortunately, I don't think signature deconstruction is mentioned in the official docs. Someone could write a book about Raku signatures. (Literally. Which of course is a great way -- the only way, even -- to write stuff. My favorite article that unpacks a bit of the power of Raku signatures is Pattern Matching and Unpacking from 2013 by Moritz. Who has authored Raku books. Here's hoping.)
Scala's match/case and Raku's given/when seem simpler
Indeed.
As #jjmerelo points out in the comments, using signatures means there's a multi foo (...) { ...} for each and every case, which is much heavier syntactically than case ... => ....
In mitigation:
Simpler cases can just use given/when, just like you wrote in the body of your question;
Raku will presumably one day get non-experimental macros that can be used to implement a construct that looks much closer to Scala's match/case construct, eliding the repeated multi foo (...)s.
From what I see in this answer, that's not really an implementation of a guard pattern in the same sense Haskell has them. However, Perl 6 does have guards in the same sense Scala has: using default patterns combined with ifs.
The Haskell to Perl 6 guide does have a section on guards. It hints at the use of where as guards; so that might answer your question.
TL;DR You've encountered what I'd call a WTF?!?: when Type and ... fails to check the and clause. This answer talks about what's wrong with the when and how to fix it. I've written another answer that focuses on using where with a signature.
If you want to stick with when, I suggest this:
when (condition when Type) { ... } # General form
when (* > 10 when Int) { ... } # For your specific example
This is (imo) unsatisfactory, but it does first check the Type as a guard, and then the condition if the guard passes, and works as expected.
"Is this right?"
No.
given $ch {
when Int and * > 10 { say 65}
}
This code says 65 for any given integer, not just one over 10!
WTF?!? Imo we should mention this on Raku's trap page.
We should also consider filing an issue to make Rakudo warn or fail to compile if a when construct starts with a compile-time constant value that's a type object, and continues with and (or &&, andthen, etc), which . It could either fail at compile-time or display a warning.
Here's the best option I've been able to come up with:
when (* > 10 when Int) { say 65 }
This takes advantage of the statement modifier (aka postfix) form of when inside the parens. The Int is checked before the * > 10.
This was inspired by Brad++'s new answer which looks nice if you're writing multiple conditions against a single guard clause.
I think my variant is nicer than the other options I've come up with in previous versions of this answer, but still unsatisfactory inasmuch as I don't like the Int coming after the condition.
Ultimately, especially if/when RakuAST lands, I think we will experiment with new pattern matching forms. Hopefully we'll come up with something nice that provides a nice elimination of this wart.
Really? What's going on?
We can begin to see the underlying problem with this code:
.say for ('TrueA' and 'TrueB'),
('TrueB' and 'TrueA'),
(Int and 42),
(42 and Int)
displays:
TrueB
TrueA
(Int)
(Int)
The and construct boolean evaluates its left hand argument. If that evaluates to False, it returns it, otherwise it returns its right hand argument.
In the first line, 'TrueA' boolean evaluates to True so the first line returns the right hand argument 'TrueB'.
In the second line 'TrueB' evaluates to True so the and returns its right hand argument, in this case 'TrueA'.
But what happens in the third line? Well, Int is a type object. Type objects boolean evaluate to False! So the and duly returns its left hand argument which is Int (which the .say then displays as (Int)).
This is the root of the problem.
(To continue to the bitter end, the compiler evaluates the expression Int and * > 10; immediately returns the left hand side argument to and which is Int; then successfully matches that Int against whatever integer is given -- completely ignoring the code that looks like a guard clause (the and ... bit).)
If you were using such an expression as the condition of, say, an if statement, the Int would boolean evaluate to False and you'd get a false negative. Here you're using a when which uses .ACCEPTS which leads to a false positive (it is an integer but it's any integer, disregarding the supposed guard clause). This problem quite plausibly belongs on the traps page.
Years ago I wrote a comment mentioning that you had to be more explicit about matching against $_ like this:
my $ch = 23;
given $ch {
when $_ ~~ Int and $_ > 10 { say 65}
when '+' { say 1 }
when '-' { say -1 }
default { say 0 }
}
After coming back to this question, I realized there was another way.
when can safely be inside of another when construct.
my $ch = 23;
given $ch {
when Int:D {
when $_ > 10 { say 65}
proceed
}
when '+' { say 1 }
when '-' { say -1 }
default { say 0 }
}
Note that the inner when will succeed out of the outer one, which will succeed out of the given block.
If the inner when doesn't match we want to proceed on to the outer when checks and default, so we call proceed.
This means that we can also group multiple when statements inside of the Int case, saving having to do repeated type checks. It also means that those inner when checks don't happen at all if we aren't testing an Int value.
when Int:D {
when $_ < 10 { say 5 }
when 10 { say 10}
when $_ > 10 { say 65}
}

isdigit function for BCPL

I am currently programming in BCPL for an OS course and wanted to write a simple is_digit() function for validation in a program of mine.
A code snippet of my current code follows:
let is_digit(n) be {
if ((n >= '0') /\ (n <= '9')) then
resultis true;
}
I am aware that BCPL has no notion of types, but how would I be able to accomplish this sort of thing in the language?
Passing in a number yields a false result instead of the expected true.
is_digit() is a function returning a value, rather than a routine, so should use = VALOF rather than BE. Otherwise, the code is OK.
let is_digit(n) = valof {
.....
resultis true
}
Functions that return values should be using valof rather than be, the latter (a routine rather than a function) can be called as a function but the return value you get back from it will be undefined(a).
In addition, you should ensure you return a valid value for every code path. At the moment, a non-digit will not execute a RESULTIS statement, and I'm not entirely certain what happens in that case (so best to be safe).
That means something like this is what you're after, keeping in mind there can be implementation variations, such as & and /\ for and, or {...} and $(...$) for the block delimiters - I've used the ones documented in Martin's latest manual:
LET is_digit(n) = VALOF {
RESULTIS (n >= '0') & (n <= '9')
}
(a) Since Martin Richards is still doing stuff with BCPL, this manual may help in any future questions (or see his home page for a large selection of goodies).

Perl booleans, negation (and how to explain it)?

I'm new here. After reading through how to ask and format, I hope this will be an OK question. I'm not very skilled in perl, but it is the programming language what I known most.
I trying apply Perl to real life but I didn't get an great understanding - especially not from my wife. I tell her that:
if she didn't bring to me 3 beers in the evening, that means I got zero (or nothing) beers.
As you probably guessed, without much success. :(
Now factually. From perlop:
Unary "!" performs logical negation, that is, "not".
Languages, what have boolean types (what can have only two "values") is OK:
if it is not the one value -> must be the another one.
so naturally:
!true -> false
!false -> true
But perl doesn't have boolean variables - have only a truth system, whrere everything is not 0, '0' undef, '' is TRUE. Problem comes, when applying logical negation to an not logical value e.g. numbers.
E.g. If some number IS NOT 3, thats mean it IS ZERO or empty, instead of the real life meaning, where if something is NOT 3, mean it can be anything but 3 (e.g. zero too).
So the next code:
use 5.014;
use Strictures;
my $not_3beers = !3;
say defined($not_3beers) ? "defined, value>$not_3beers<" : "undefined";
say $not_3beers ? "TRUE" : "FALSE";
my $not_4beers = !4;
printf qq{What is not 3 nor 4 mean: They're same value: %d!\n}, $not_3beers if( $not_3beers == $not_4beers );
say qq(What is not 3 nor 4 mean: #{[ $not_3beers ? "some bears" : "no bears" ]}!) if( $not_3beers eq $not_4beers );
say ' $not_3beers>', $not_3beers, "<";
say '-$not_3beers>', -$not_3beers, "<";
say '+$not_3beers>', -$not_3beers, "<";
prints:
defined, value><
FALSE
What is not 3 nor 4 mean: They're same value: 0!
What is not 3 nor 4 mean: no bears!
$not_3beers><
-$not_3beers>0<
+$not_3beers>0<
Moreover:
perl -E 'say !!4'
what is not not 4 IS 1, instead of 4!
The above statements with wife are "false" (mean 0) :), but really trying teach my son Perl and he, after a while, asked my wife: why, if something is not 3 mean it is 0 ? .
So the questions are:
how to explain this to my son
why perl has this design, so why !0 is everytime 1
Is here something "behind" what requires than !0 is not any random number, but 0.
as I already said, I don't know well other languages - in every language is !3 == 0?
I think you are focussing to much on negation and too little on what Perl booleans mean.
Historical/Implementation Perspective
What is truth? The detection of a higher voltage that x Volts.
On a higher abstraction level: If this bit here is set.
The abstraction of a sequence of bits can be considered an integer. Is this integer false? Yes, if no bit is set, i.e. the integer is zero.
A hardware-oriented language will likely use this definition of truth, e.g. C, and all C descendants incl Perl.
The negation of 0 could be bitwise negation—all bits are flipped to 1—, or we just set the last bit to 1. The results would usually be decoded as integers -1 and 1 respectively, but the latter is more energy efficient.
Pragmatic Perspective
It is convenient to think of all numbers but zero as true when we deal with counts:
my $wordcount = ...;
if ($wordcount) {
say "We found $wordcount words";
} else {
say "There were no words";
}
or
say "The array is empty" unless #array; # notice scalar context
A pragmatic language like Perl will likely consider zero to be false.
Mathematical Perspective
There is no reason for any number to be false, every number is a well-defined entity. Truth or falseness emerges solely through predicates, expressions which can be true or false. Only this truth value can be negated. E.g.
¬(x ≤ y) where x = 2, y = 3
is false. Many languages which have a strong foundation in maths won't consider anything false but a special false value. In Lisps, '() or nil is usually false, but 0 will usually be true. That is, a value is only true if it is not nil!
In such mathematical languages, !3 == 0 is likely a type error.
Re: Beers
Beers are good. Any number of beers are good, as long as you have one:
my $beers = ...;
if (not $beers) {
say "Another one!";
} else {
say "Aaah, this is good.";
}
Boolification of a beer-counting variable just tells us if you have any beers. Consider !! to be a boolification operator:
my $enough_beer = !! $beers;
The boolification doesn't concern itself with the exact amount. But maybe any number ≥ 3 is good. Then:
my $enough_beer = ($beers >= 3);
The negation is not enough beer:
my $not_enough_beer = not($beers >= 3);
or
my $not_enough_beer = not $beers;
fetch_beer() if $not_enough_beer;
Sets
A Perl scalar does not symbolize a whole universe of things. Especially, not 3 is not the set of all entities that are not three. Is the expression 3 a truthy value? Yes. Therefore, not 3 is a falsey value.
The suggested behaviour of 4 == not 3 to be true is likely undesirable: 4 and “all things that are not three” are not equal, the four is just one of many things that are not three. We should write it correctly:
4 != 3 # four is not equal to three
or
not( 4 == 3 ) # the same
It might help to think of ! and not as logical-negation-of, but not as except.
How to teach
It might be worth introducing mathematical predicates: expressions which can be true or false. If we only ever “create” truthness by explicit tests, e.g. length($str) > 0, then your issues don't arise. We can name the results: my $predicate = (1 < 2), but we can decide to never print them out, instead: print $predicate ? "True" : "False". This sidesteps the problem of considering special representations of true or false.
Considering values to be true/false directly would then only be a shortcut, e.g. foo if $x can considered to be a shortcut for
foo if defined $x and length($x) > 0 and $x != 0;
Perl is all about shortcuts.
Teaching these shortcuts, and the various contexts of perl and where they turn up (numeric/string/boolean operators) could be helpful.
List Context
Even-sized List Context
Scalar Context
Numeric Context
String Context
Boolean Context
Void Context
as I already said, I don't know well other languages - in every language is !3 == 0?
Yes. In C (and thus C++), it's the same.
void main() {
int i = 3;
int n = !i;
int nn = !n;
printf("!3=%i ; !!3=%i\n", n, nn);
}
Prints (see http://codepad.org/vOkOWcbU )
!3=0 ; !!3=1
how to explain this to my son
Very simple. !3 means "opposite of some non-false value, which is of course false". This is called "context" - in a Boolean context imposed by negation operator, "3" is NOT a number, it's a statement of true/false.
The result is also not a "zero" but merely something that's convenient Perl representation of false - which turns into a zero if used in a numeric context (but an empty string if used in a string context - see the difference between 0 + !3 and !3 . "a")
The Boolean context is just a special kind of scalar context where no conversion to a string or a number is ever performed. (perldoc perldata)
why perl has this design, so why !0 is everytime 1
See above. Among other likely reasons (though I don't know if that was Larry's main reason), C has the same logic and Perl took a lot of its syntax and ideas from C.
For a VERY good underlying technical detail, see the answers here: " What do Perl functions that return Boolean actually return " and here: " Why does Perl use the empty string to represent the boolean false value? "
Is here something "behind" what requires than !0 is not any random number, but 0.
Nothing aside from simplicity of implementation. It's easier to produce a "1" than a random number.
if you're asking a different question of "why is it 1 instead of the original # that was negated to get 0", the answer to that is simple - by the time Perl interpreter gets to negate that zero, it no longer knows/remembers that zero was a result of "!3" as opposed to some other expression that resulted in a value of zero/false.
If you want to test that a number is not 3, then use this:
my_variable != 3;
Using the syntax !3, since ! is a boolean operator, first converts 3 into a boolean (even though perl may not have an official boolean type, it still works this way), which, since it is non-zero, means it gets converted to the equivalent of true. Then, !true yields false, which, when converted back to an integer context, gives 0. Continuing with that logic shows how !!3 converts 3 to true, which then is inverted to false, inverted again back to true, and if this value is used in an integer context, gets converted to 1. This is true of most modern programming languages (although maybe not some of the more logic-centered ones), although the exact syntax may vary some depending on the language...
Logically negating a false value requires some value be chosen to represent the resulting true value. "1" is as good a choice as any. I would say it is not important which value is returned (or conversely, it is important that you not rely on any particular true value being returned).

What's the difference between XOR and NOT-EQUAL-TO?

My question uses Java as an example, but I guess it applies to probably all.
Is there any practical difference between the XOR operator (^ in Java) and the not-equal-to operator (!= in Java), when comparing booleans?
I evaluated things here, but I just kept wondering (seems weird, two things equal)... and didn't find anything on the net. Just one discussion in some forum that ended quickly without any result.
For Boolean values, they mean the same thing - although there's a compound assignment operator for XOR:
x ^= y;
There's no equivalent compound assignment operator for inequality.
As for why they're both available - it would be odd for XOR not to be available just because it works the same way as inequality. It should logically be there, so it is. For non-Boolean types the result is different because it's a different result type, but that doesn't mean it would make sense to remove XOR for boolean.
As stated in the Java Language Specification:
The result of != is false if the operands are both true or both false; otherwise, the result is true. Thus != behaves the same as ^ (§15.22.2) when applied to boolean operands.
In addition if you try looking at bytecode of a simple snippet:
void test(boolean b1, boolean b2) {
boolean res1 = b1^b2;
boolean res2 = b1!=b2;
}
you obtain:
test(ZZ)V
L0
LINENUMBER 45 L0
ILOAD 1
ILOAD 2
IXOR
ISTORE 3
L1
LINENUMBER 46 L1
ILOAD 1
ILOAD 2
IXOR
ISTORE 4
L2
LINENUMBER 47 L2
RETURN
L3
This assures that, in addition to the same semantics, there's no any actual practical difference in implementation. (you can also see that internally ints are used to store boolean values)
Yes, you can use XOR to test booleans for (in)equality, although the code is less intuitive: if (x ^ y) versus if (x != y).
With boolean values, there should be no difference. You should choose whichever is more appropriate for your sense of operation.
Example:
bool oldChoice = ...;
bool newChoice = ...;
if (oldChoice != newChoice)
...
Here XOR would give the same result, but will not reflect the real code intention.
They should be essentially the same in this case.
There's a big difference, XOR works at bit-level, keeping differences as ones,
so 0b0011 xor 0b1101 => 0b1110
regards,
//t