confusion about conversion answer infix to postfix - data-structures

I am trying to learn about Infix to Postfix Conversion from the internet
I have come across 2 sources following which I get different answers to the same infix expression:
a/b^c+d*e/f-g+h
I am wondering which algorithm is correct
source 1 : https://youtu.be/IAxCAbcqQFA?t=803 as you can see here the answer is
abc^/de*+f/g-h+
source 2 : https://raj457036.github.io/Simple-Tools/prefixAndPostfixConvertor.html
answer is
abc^/de*+f/gh+-

If you want to check the output, you can evaluate the expression yourself. Just open an editor and use a line as a stack:
Answer 1: abc^/de*+f/g-h+
a: a
b: a b
c: a b c
^: a b^c
/: a/b^c
d: a/b^c d
e: a/b^c d e
*: a/b^c d*e
+: a/b^c+d*e
f: a/b^c+d*e f
/: (a/b^c+d*e)/f
g: (a/b^c+d*e)/f g
-: (a/b^c+d*e)/f-g
h: (a/b^c+d*e)/f-g h
+: (a/b^c+d*e)/f-g+h
Looks like that one's wrong.
You can do the second one yourself. It's also wrong.
Conversion from infix to postfix is also easy to do manually. You just do the operators in the proper order, changing arg op arg op arg... to arg arg op arg op... Here I use [] to hold the already-converted subexpressions:
a/b^c+d*e/f-g+h
a/[bc^]+d*e/f-g+h
[abc^/]+[de*f/]-g+h
[abc^/de*f/+g-h+]

Related

How are 'bind' and 'in' different?

Take the following code which creates a context:
c: context [a: 2]
You can see it creates a context c, and that a is not bound in the global context:
>> ?? c
c: make object! [
a: 2
]
>> a
** Script Error: a has no value
** Near: a
Now if you use bind 'a c, it returns the value of the word in the context it was bound:
>> get bind 'a c
== 2
Which is also the same as in c 'a:
>> (get bind 'a c) = (get in c 'a)
== true
Looks like in is a version of bind with flipped arguments
So, how is in different?
There are some obvious feature additions in bind, like having a refinement /copy for efficiency, and also accepting a block! instead of a single word for its words argument.
In which case, the question becomes, why in?
Note
This was initially motivated by comments in this question, when I didn't quite understood what bind does, and a discussion on gitter prompted me to post this
The big difference is that BIND can propagate the context of a word:
>> q: func [/local a b][a: 1 b: 2 return 'a]
>> get bind 'b q
== 2
>> get in q 'b
** Script Error: in expected object argument of type: object port
** Near: get in q 'b
Rebol 2 only of course.

Mixing mathematical expression with control flow

I would like to know, how expressions are parsed when are mixed with control flow.
Let's assume such syntax:
case
when a == Method() + 1
then Something(1)
when a == Other() - 2
then 1
else 0
end
We've got here two conditional expressions, Method() + 1, Something(1) and 0. Each can be translated to postfix by Shunting-yard algorithm and then easily translated into AST. But is it possible to extend this algorithm to handle control - flow also? Or are there other approaches to solve such mixing of expressions and control flows?
another example:
a == b ? 1 : 2
also how can I classify such expression: a between b and c, can I say that between is three arguments function? Or is there any special name for such expressions?
You can certainly parse the ternary operator with an operator-precedence grammar. In
expr ? expr : expr
the binary "operator" here is ? expr :, which conveniently starts and ends with an operator token (albeit different ones). To adapt shunting yard to that, assign the right-precedence of ? and the left-precedence of : to the precedence of the ?: operator. The left-precedence of ? and the right-precedence of : are ±∞, just like parentheses (which, in effect, they are).
Since the case statement is basically repeated application of the ternary operator, using slightly different spellings for the tokens, and yields to a similar solution. (Here case when and end are purely parenthetic, while then and the remaining whens correspond to ? and :.)
Having said that, it really is simpler to use an LALR(1) parser generator, and there is almost certainly one available for whatever language you are writing in.
It's clear that both the ternary operator and OP's case statement are operator grammars:
Ternary operator:
ternary-expr: non-ternary-expr
| non-ternary-expr '?' expr ':' ternary-expr
Normally, the ternary operator will be lower precedence from any other operator and associate to the right, which is how the above is written. In C and other languages ternary expressions have the same precedence as assignment expressions, which is straightforward to add. That results in the relationships
X ·> ?
? <· X
? ·=· :
X ·> :
: <· X
Case statement (one of many possible formulations):
case_statement: 'case' case_body 'else' expr 'end'
case_body: 'when' expr 'then' expr
| case_body 'when' expr 'then' expr
Here are the precedence relationships for the above grammar:
case <· when
case ·=· else
when <· X (see below)
when ·=· then
then ·> when
then ·> else
else <· X
else ·=· end
X ·> then
X ·> when
X ·> end
X in the above relations refers to any binary or unary operator, any value terminal, ( and ).
It's straightforward to find left- and right-precedence functions for all of those terminals; the pattern will be similar to that of parentheses in a standard algebraic grammar.
The Shunting-yard algorithm is for expressions with unary and binary operators. You need something more powerful such as LL(1) or LALR(1) to parse control flow statements, and once you have that it will also handle expressions as well. No need for the Shunting-yard algorithm at all.

A list of variables used by Wolfram Mathematica function

Is there a way to get a list of variables used by a function?
For example:
a=1;
b=2;
f[x_]:= 2a*x+b;
Needed:
SomeFunction[f]
Output:
{{x},{a,b}}
The parameters of the function ({x}) are not really mandatory.
Thanks.
To get all the symbols (not necessarily variables) you could start with something like this:
DownValues[f]
which yields:
{HoldPattern[f[x_]] :> 2 a x + b}
The problem is then processing this in a way that you don't let Mathematica do the substitution. This is done with Hold:
held=(Hold //# DownValues[f][[1]])[[1, 2]]
which yields:
Hold[Hold[Hold[2] Hold[a] Hold[x]] + Hold[b]]
You can extract all the stuff that looks like a symbol with:
Cases[held, Hold[_Symbol], Infinity]
and you get:
{Hold[a], Hold[x], Hold[b]}
To make this a little nicer:
Union[Flatten[Hold ## Cases[held, Hold[_Symbol], Infinity]]]
which gives you:
Hold[a, b, x]
You still need the Hold, because as soon as you lose it Mathematica will evaluate a and b and you'll lose them as symbols.
If you notice, it's considering x a symbol, which you may not want because it's a parameter. You can tease the parameters out of the left side of the DownValues[f][[1]] RuleDelayed (:>) expression, and extract them, but I'll leave this detail to you.

Setting the rank of a user-defined verb in J

Here's a function to calculate the digital sum of a number in J:
digitalSum =: +/#:("."0)#":
If I use b. to query the rank of this verb, I get _ 1 _, i.e., infinite. (We can ignore the dyadic case since digitalSum is not dyadic.)
I would like the monadic rank of this verb to be 0, as reported by b.. The only way I know of to do this is to use a "shim", e.g.,
ds =: +/#:("."0)#":
digitalSum =: ds"0
This works great, but I want to know whether it's the only way to do this, or if there's something else I'm missing.
Clarification
I just discovered how to change the rank of a verb that's defined thus:
digits =: 3 : 0 "0
"."0#": y
)
Notice the "0 after the declaring 3 : 0. You can put any adverb or conjunction you wish, and it will be applied to the verb as a whole. Pretty cool stuff!
digitalSum =: (+/#:("."0)#":)"0 is how I would define it as well. Using " to change rank is pretty standard and works on parenthesized tacit trains.

ruby interview question

I got this question in a previous interview and couldnt do it , any idea?
What does this do:
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,#%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
This is Perl code that prints out "Just another Perl hacker."
While most of the $_, $=, etc. variables are available in Ruby as well, the presence of statements such as $,++ indicate Perl, which actually has pre- and post-increment operators, unlike Ruby.
I went in with Vim and replaced all the symbols with their English equivalent. I munged something up since the output is now "Just another Per hacker" (missing the L on Perl), but here's what I came up with:
use English;
`$FORMAT_LINES_PER_PAGE`;
$ARG=\%!;($ARG)=/(.)/;$FORMAT_LINES_PER_PAGE=++$OUTPUT_AUTOFLUSH;
($INPUT_LINE_NUMBER,$/,$OUTPUT_FIELD_SEPARATOR,$OUTPUT_RECORD_SEPARATOR,$LIST_SEPARATOR,$SUBSCRIPT_SEPARATOR,$FORMAT_TOP_NAME,$OFMT,$FORMAT_NAME,$MULTILINE_MATCHING,$FORMAT_LINE_BREAK_CHARACTERS,#%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$LIST_SEPARATOR),$FORMAT_LINES_PER_PAGE++;
$INPUT_LINE_NUMBER++;
$INPUT_LINE_NUMBER++; $ARG++;$ARG++;
($ARG,$OUTPUT_RECORD_SEPARATOR,$OUTPUT_FIELD_SEPARATOR)=($FORMAT_NAME.$LIST_SEPARATOR."$SUBSCRIPT_SEPARATOR$/$FORMAT_PAGE_NUMBER[$CHILD_ERROR]$ARG$OUTPUT_RECORD_SEPARATOR$OUTPUT_FIELD_SEPARATOR$FORMAT_LINE_BREAK_CHARACTERS$FORMAT_PAGE_NUMBER[$CHILD_ERROR]",$LIST_SEPARATOR&$FORMAT_NAME,$OFMT,);
$OUTPUT_FIELD_SEPARATOR++ ;
$OUTPUT_FIELD_SEPARATOR++;
$FORMAT_TOP_NAME|=$LIST_SEPARATOR;
`$ARG$OUTPUT_RECORD_SEPARATOR$OUTPUT_FIELD_SEPARATOR$/$FORMAT_LINE_BREAK_CHARACTERS$SUBSCRIPT_SEPARATOR$FORMAT_NAME$MULTILINE_MATCHING$FORMAT_PAGE_NUMBER[$CHILD_ERROR]$INPUT_LINE_NUMBER$FORMAT_NAME$MULTILINE_MATCHING${#}$FORMAT_PAGE_NUMBER[$CHILD_ERROR]$SUBSCRIPT_SEPARATOR$OUTPUT_RECORD_SEPARATOR$LIST_SEPARATOR$FORMAT_TOP_NAME$FORMAT_NAME$MULTILINE_MATCHING.>&$FORMAT_LINES_PER_PAGE`
Here, I changed all the special Ruby globals into single-letter variables and inserted some whitespace:
`a`
n = \%!
(n) = /(.)/
a = ++o
(b, c, d, f, e, g, h, i, j, k, l, #%) = (m =~ /(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/, e), a++
b++
b++
n++
n++
(n, f, d) = (j . e . "gcp[q]nfdlp[q]", e & j, i,)
d++
d++
h |= e
`nfdclgjkp[q]bjk${#}p[q]gfehjk.>&a`
Whoever wrote this doesn't understand Ruby. There's no increment operator in Ruby. Tokens like \%! and #% mean nothing in Ruby. You can't interpolate variables, even global variables, in strings or backquoted commands, as in "$=". The dot . is not a concatenation operator in Ruby. I don't think this is Ruby. It's like a hybrid of languages.
I am not a Ruby expert by any means by the first step should be make it into a format you can read. I broke it down by line.
`$=`;
$_=\%!;
($_)=/(.)/;
$==++$|;
($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,#%)=($!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;
$_++;
($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);
$,++;
$,++;
$^|=$";
`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
I cheated and tried to run it, and it doesn't work. I get an unexpected null error.
Don't feel bad if you can't do this. This seems pointless. Programming questions should try to test your skills not test you on something that if somebody is really using it would mean there application would be really bad.
This looks closer to Perl, to be honest, but in any case pretty nonsensical.
Not related to Ruby I think, above encoded message is given at https://en.wikipedia.org/wiki/Just_another_Perl_hacker with the help of only punctuation. Another one is also provided there.
''=~('(?{'.('-)#.)#_*([]#!#/)(#)#-#),#(##+#)'
^'][)#]`}`]()`#.#]#%[`}%[#`#!##%[').',"})')

Resources