What's the fastest way to check if input String is a correct RPN expression? - algorithm

I came across a task which makes you check if a String passed as an argument to your method/function is a correct statement in the Reverse Polish Notation sense. It can contain lowercase alphabet letters, operation signs and integers. Is there any faster way to check it than to read every character separately and actually try to evaluate the whole expression?

You don't have to evaluate the whole expression but you do need to split it into tokens, and you have to know the valence of every operator (that is, how many operands it takes). For simplicity, let the valence of an operand be 0; then do the following:
Set stack_size to 0;
For Each token In expression:
Set stack_size to stack_size + 1 - valence(token)
If stack_size <= 0: Report failure
If stack_size == 1: Report success
Else : Report failure
Examples using _ for unary minus.
expression: 3 4 + 1 * _
stack_size: 0 1 2 1 2 1 1 -> success
expression: 2 3 4 + 1 * _
stack_size: 0 1 2 3 2 3 2 2 -> failure (not 1 at the end)
expression: 2 3 + + 1 * _
stack_size: 0 1 2 1 0 -> failure (stack_size <= 0)

You can use a parse table to recognize reverse polish notation. It requires looking at each character, but it's fast.

Related

Is the assignment operator really "just" an operator?

My question was triggered by this discussion on SO, which did not lead to an answer that would really explain the issue. I am "rewriting" it here in a slightly different way, because I want to make it more clear what the real problem is and therefore hope to get an answer here.
Consider the following two Ruby expressions:
1 * a - 3
1 && a = 3
From the Ruby precedence table, we know that of the operators mentioned here, * has the highest precedence, followed by -, then by && and finally by =.
The expressions don't have parenthesis, but - as we can verify in irb, providing a suitable value for a in the first case - they are evaluated as if the bracketing were written as (1*a) - 3, respectively 1 && (a=3).
The first one is easy to understand, since * binds stronger than -.
The second one can't be explained in this way. && binds stronger than =, so if precedence only would matter, the interpretation should be (1 && a) = 3.
Associativity (= is right-associative and - is left-associative) can't explain the effect either, because associativity is only important if we have several operators of the same kind (such as x-y-z or x=y=z).
There must be some special rule in the assignment operator, which I did not find in the docs I checked in particular the docs for assignment and syntax.
Could someone point out, where this special behaviour of the assignment operator is documented? Or did I miss / misunderstand something here?
From the doc: https://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#assign
Assignment expression are used to assign objects to the variables or such. Assignments sometimes work as declarations for local variables or class constants. The left hand side of the assignment expressions can be either:
variables
variables `=' expression
On the right there is an expression, so the result of the expression is assigned to the variable.
So, you should look for expressions (*) before following the precedence.
1 && a = 3 are basically two "chained" expressions:
3 and 1 && 3
Maybe it is more readable as:
1 && a = 3 + 4 where the expressions are 3 + 4 and 1 && 7, see:
1 && a = 3 + 4 #=> 7
1 && 7 #=> 7
res = 1 && a = 3 + 4
res #=> 7
(*) The precedence table also helps to find the expression (Find the precedence table in the linked doc at the Operator expressions paragraph):
What's above the = in the table "forms" an expression to be assigned by =, what's below does not.
For example:
1 + 3 and 2 + 4 #=> 4
a = 1 + 3 and b = 2 + 4 #=> 4
(a = 1 + 3) and (b = 2 + 4) #=> 4
a = (1 + 3 and b = 2 + 4) #=> 6
You can also check these examples respect to the precedence table:
1 && 3 #=> 3
1 && a = 3 #=> 3
a #=> 3
3 and 1 #=> 3
3 and b = 1 #=> 3
b #=> 1
2 ** c = 2 + 1 #=> 8
c #=> 3
d = 2 ** 3
d #=> 8
e = 3
e **= 2
e #=> 9
I think the understanding of 1 && (a = 3) is, understandably, mislead.
a = false
b = 1
b && a = 3
b
=> 1
a
=> 3
Why is a being assigned to in the && expression when a is false? Should the && expression not return when encountering a false value? Spoiler, it does return!
Taking a step back, we think of the purpose of the && operator to control the flow of logic. Our disposition to the statement
1 && a = 3
is to assume the entire statement is returned if a is nil or false. Well no, the interpreter is evaluating like so:
(1 && a) = 3
The interpreter does not raise a if it is nil or false nor does it return the left side if a is nil or false
a = nil
1 && a
=> nil # a was returned
The interpreter returns the variable, this is why the original statement can be read:
a = 3
due to 1 && a returning a which is a variable that can be assigned to by the = operand on the second half of the statement.
TLDR
In your origin example: 1 is neither nil nor false so the variable a is returned in (1 && a) which is subsequently assigned in a = 3
Probably because the other interpretation does not work:
irb(main):003:0> (1 && a) = 3
Traceback (most recent call last):
3: from /home/w/.rbenv/versions/2.7/bin/irb:23:in `<main>'
2: from /home/w/.rbenv/versions/2.7/bin/irb:23:in `load'
1: from /home/w/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
SyntaxError ((irb):3: syntax error, unexpected '=', expecting `end')
(1 && a) = 3
^
So, perhaps Ruby parenthesizes 1 && a = 3 in the only way that is legally interpretable by the language.

Count characters starting at zero?

I need to write a for-each loop that lists each character in
mystery_string with its index. Example below:
mystery_string= "Olivia," output would be:
0 O
1 l
2 i
3 v
4 i
5 a
I cannot use the range function on this problem.
This is my code, but the number starts at 1. What am I doing wrong?
mystery_string = "CS1301"
count = 0
for current_letter in mystery_string:
count = count + 1
print (count , current_letter)
I have been getting this as output:
1 C
2 S
3 1
4 3
5 0
6 1
but it needs to start at zero.
Just add the count (count += 1) after you print in the for loop
Note: Also, please format your code in a code block surrounded with a tick(`) or multiline code with 3 tick (```)
The pythonic way is to use enumerate() in such a case. This way you'll get both the index and the content of your string.
mystery_string = "CS1301"
for count, current_letter in enumerate(mystery_string):
print (count , current_letter)

Check if a number is divisible by 3 in logic design

i seen a post on the site about it and i didn't understand the answer, can i get explanation please:
question:
Write code to determine if a number is divisible by 3. The input to the function is a single bit, 0 or 1, and the output should be 1 if the number received so far is the binary representation of a number divisible by 3, otherwise zero.
Examples:
input "0": (0) output 1
inputs "1,0,0": (4) output 0
inputs "1,1,0,0": (6) output 1
This is based on an interview question. I ask for a drawing of logic gates but since this is stackoverflow I'll accept any coding language. Bonus points for a hardware implementation (verilog etc).
Part a (easy): First input is the MSB.
Part b (a little harder): First input is the LSB.
Part c (difficult): Which one is faster and smaller, (a) or (b)? (Not theoretically in the Big-O sense, but practically faster/smaller.) Now take the slower/bigger one and make it as fast/small as the faster/smaller one.
answer:
State table for LSB:
S I S' O
0 0 0 1
0 1 1 0
1 0 2 0
1 1 0 1
2 0 1 0
2 1 2 0
Explanation: 0 is divisible by three. 0 << 1 + 0 = 0. Repeat using S = (S << 1 + I) % 3 and O = 1 if S == 0.
State table for MSB:
S I S' O
0 0 0 1
0 1 2 0
1 0 1 0
1 1 0 1
2 0 2 0
2 1 1 0
Explanation: 0 is divisible by three. 0 >> 1 + 0 = 0. Repeat using S = (S >> 1 + I) % 3 and O = 1 if S == 0.
S' is different from above, but O works the same, since S' is 0 for the same cases (00 and 11). Since O is the same in both cases, O_LSB = O_MSB, so to make MSB as short as LSB, or vice-versa, just use the shortest of both.
thanks for the answers in advanced.
Well, I suppose the question isn't entirely off-topic, since you asked about logic design, but you'll have to do the coding yourself.
You have 3 states in the S column. These track the value of the current full input mod 3. So, S0 means the current input mod 3 is 0, and so is divisible by 0 (remember also that 0 is divisible by 3). S1 means the remainder is 1, S2 means that the remainder is 2.
The I column gives the current input (0 or 1), and S' gives the next state (in other words, the new number mod 3).
For 'LSB', the new number is the old number << 1, plus either 0 or 1. Write out the table. For starters, if the old modulo was 0, then the new modulo will be 0 if the input bit was 0, and will be 1 if the new input was 1. This gives you the first 2 rows in the first table. Filling in the rest is left as an exercise for you.
Note that the O column is just 1 if the next state is 0, as expected.

Algorithm for building an equation from a list of numbers using basic operators (+,-,*,/)

I am struggling to find a smart/creative way to approach this problem instead of a brute force algorithm. Any insights that could allow me to view this problem in a different light would be greatly appreciated. Any language can be used.
Given a sequence of numbers, it is sometimes possible to place the basic operations of =, +, −, ×, and ÷ between those number to build a complete, correct equation. For instance, the sequence [2, 3, 8, 4, 22] can be made into an equation by putting the symbols in the following places:
2 + 3 × 8 − 4 = 22
Note how the order of operations is followed. Write a program that will build such a number sentence, given the list of numbers. An ideal solution would allow the numbers to be specified on the command line, but prompting the user for a list is also acceptable. If no true sentence can be found, print such a message to the user. Assume only one = will be used (allowing for multiple equal signs makes the assignment a lot harder, but is fun!)
You may present the sentence using prefix, infix, or postfix operators.
Sample Output
Note that some of these sequences could form multiple sentences. Only one need be printed.
$ assignment -4 1 2 3 4
1 - 2 = 3 - 4
$ assignment -4 1 1 1
1 / 1 = 1
$ assignment -4 0 18 1 2 1 1
0 / 18 = 1 - 2 + 1 * 1
$ assignment -4 2 2 2
No equation found

String similarity: how exactly does Bitap work?

I'm trying to wrap my head around the Bitap algorithm, but am having trouble understanding the reasons behind the steps of the algorithm.
I understand the basic premise of the algorithm, which is (correct me if i'm wrong):
Two strings: PATTERN (the desired string)
TEXT (the String to be perused for the presence of PATTERN)
Two indices: i (currently processing index in PATTERN), 1 <= i < PATTERN.SIZE
j (arbitrary index in TEXT)
Match state S(x): S(PATTERN(i)) = S(PATTERN(i-1)) && PATTERN[i] == TEXT[j], S(0) = 1
In english terms, PATTERN.substring(0,i) matches a substring of TEXT if the previous substring PATTERN.substring(0, i-1) was successfully matched and the character at PATTERN[i] is the same as the character at TEXT[j].
What I don't understand is the bit-shifting implementation of this. The official paper detailing this algorithm basically lays it out, but I can't seem to visualize what's supposed to go on. The algorithm specification is only the first 2 pages of the paper, but I'll highlight the important parts:
Here is the bit-shifting version of the concept:
Here is T[text] for a sample search string:
And here is a trace of the algorithm.
Specifically, I don't understand what the T table signifies, and the reason behind ORing an entry in it with the current state.
I'd be grateful if anyone can help me understand what exactly is going on
T is slightly confusing because you would normally number positions in the
pattern from left to right:
0 1 2 3 4
a b a b c
...whereas bits are normally numbered from right to left.
But writing the
pattern backwards above the bits makes it clear:
bit: 4 3 2 1 0
c b a b a
T[a] = 1 1 0 1 0
c b a b a
T[b] = 1 0 1 0 1
c b a b a
T[c] = 0 1 1 1 1
c b a b a
T[d] = 1 1 1 1 1
Bit n of T[x] is 0 if x appears in position n, or 1 if it does not.
Equivalently, you can think of this as saying that if the current character
in the input string is x, and you see a 0 in position n of T[x], then you
can only possibly be matching the pattern if the match started n characters
previously.
Now to the matching procedure. A 0 in bit n of the state means that we started matching the pattern n characters ago (where 0 is the current character). Initially, nothing matches.
[start]
1 1 1 1 1
As we consume characters trying to match, the state is shifted left (which shifts a zero in
to the bottom bit, bit 0) and OR-ed with the table entry for the current character. The first character is a; shifting left and OR-ing in T[a] gives:
a
1 1 1 1 0
The 0 bit that was shifted in is preserved, because a current character of a can
begin a match of the pattern. For any other character, the bit would be have been set to
1.
The fact that bit 0 of the state is now 0 means that we started matching the pattern on
the current character; continuing, we get:
a b
1 1 1 0 1
...because the 0 bit has been shifted left - think of it as saying that we started matching the pattern 1 character ago - and T[b] has a 0 in the same position, telling
us that a seeing a b in the current position is good if we started matching 1 character
ago.
a b d
1 1 1 1 1
d can't match anywhere; all the bits get set back to 1.
a b d a
1 1 1 1 0
As before.
a b d a b
1 1 1 0 1
As before.
b d a b a
1 1 0 1 0
a is good if the match started either 2 characters ago or on the current character.
d a b a b
1 0 1 0 1
b is good if the match started either 1 or 3 characters ago. The 0 in bit 3 means
that we've almost matched the whole pattern...
a b a b a
1 1 0 1 0
...but the next character is a, which is no good if the match started 4 characters
ago. However, shorter matches might still be good.
b a b a b
1 0 1 0 1
Still looking good.
a b a b c
0 1 1 1 1
Finally, c is good if the match started 4 characters before. The fact that
a 0 has made it all the way to the top bit means that we have a match.
Sorry for not allowing anyone else to answer, but I'm pretty sure I've figured it out now.
The concept essential for groking the algorithm is the representation of match states (defined in the original post) in binary. The article in the original post explains it formally; I'll try my hand at doing so colloquially:
Let's have STR, which is a String created with characters from a given alphabet.
Let's represent STR with a set of binary digits: STR_BINARY. The algorithm requires for this representation to be backwards (so, the first letter corresponds to the last digit, second letter with the second-to-last digit, etc.).
Let's assume RANDOM refers to a String with random characters from the same alphabet STR is created from.
In STR_BINARY, a 0 at a given index indicates that, RANDOM matches STR from STR[0] to
STR[(index of letter in STR that the 0 in STR_BINARY corresponds to)]. Empty spaces count as matches. A 1 indicates that RANDOM does not match STR in inside those same boundaries.
The algorithm becomes simpler to learn once this is understood.

Resources