16
1
In prefix notation, the operator comes before the arguments, so you can kind of imagine that the operator calls next()
which is recursively called. In infix notation, the operator goes between the arguments, so you can imagine it simply as a parse tree. In postfix notation, the operator comes after the arguments, so you can just imagine it as stack-based.
In anyfix notation, the operator can go anywhere*. If an operator shows up and there aren't enough arguments, then the operator waits until there are enough arguments. For this challenge, you are to implement a very basic anyfix evaluator. (Note that anyfix is a recreational language that I abandoned that you can play around with here or check out here)
You will need to support the following commands:
(Arity 1)
- duplicate
- negative
(Arity 2)
- addition
- multiplication
- equality: returns
0
or1
.
You may choose to use any five non-whitespace symbols for these commands. For demonstrational purposes, I will use "
as duplicate, ×
as multiplication, and +
as addition.
For literals, you only need to support non-negative integers, but your interpreter must be able to contain all integers (within your language's (reasonable) integer range).
Let's take a look at an example: 10+5
. The storage should behave as a stack, not a queue. So first, the stack starts at []
, and the queued operator list starts at []
. Then, the literal 10
is evaluated which makes the stack [10]
. Next, the operator +
is evaluated, which requires two arguments. However, there is only one argument on the stack, so the queued operator list becomes ['+']
. Then, the literal 5
is evaluated which makes the stack [10, 5]
. At this point, the operator '+'
can be evaluated so it is, making the stack [15]
and the queue []
.
The final result should be [15]
for + 10 5
, 10 + 5
, and 10 5 +
.
Let's take a look at a harder example: 10+"
. The stack and queue start as []
and []
. 10
is evaluated first which makes the stack [10]
. Next, +
is evaluated, which doesn't change the stack (because there are not enough arguments) and makes the queue ['+']
. Then, "
is evaluated. This can run immediately so it is, making the stack [10, 10]
. +
can now be evaluated so the stack becomes [20]
and the queue []
. The final result is [20]
.
What about order of operations?
Let's take a look at ×+"10 10
. The stack and queue start both as []
:
×
: The stack is unchanged and the queue becomes['×']
.+
: The stack is unchanged and the queue becomes['×', '+']
."
: The stack is unchanged and the queue becomes['×', '+', '"']
.10
: The stack becomes[10]
. Even though×
should be the first operator to be evaluated since it appears first,"
can run immediately and none of the operators before it can, so it is evaluated. The stack becomes[10, 10]
and the queue['×', '+']
.×
can now be evaluated, which makes the stack[100]
and the queue['+']
.10
: The stack becomes[100, 10]
, which allows+
to be evaluated. The stack becomes[110]
and the queue[]
.
The final result is [110]
.
The commands used in these demonstrations are consistent with that of the anyfix language; however, the last example will not work due to a bug in my interpreter. (Disclaimer: Your submissions will not be used in the anyfix interpreter)
Challenge
Select a set of 5 non-whitespace non-digit characters and create an anyfix interpreter according to the specifications above. Your program can either output the singular array or the value contained by it; it is guaranteed that the stack of values will only contain a single value at the end of execution and that the queue of operators will be empty at the end of execution.
This is code-golf so the shortest code in bytes wins.
Test Cases
For these test cases, duplicate is "
, negative is -
, addition is +
, multiplication is ×
, and equality is =
.
Input -> Output
1+2×3 -> 9
1"+"+ -> 4
2"××" -> 16
3"×+" -> 18
3"+×" -> 36
123"= -> 1 ("= always gives 1)
1+2=3 -> 1
1"=2+ -> 3
1-2-+ -> -3
-1-2+ -> 3 (hehe, the `-1` becomes `+1` at the `-` rather than making the `2` a `-1`)
+×"10 10 -> 200 (after the 10 is duplicated (duplication is delayed), 10 + 10 is performed and then 20 * 10, giving 200)
Rules
- Standard Loopholes Apply
- You may take the anyfix official interpreter and golf it if you would like. Expect to lose horribly.
Input will be given as a string and output as an array, a single integer, out the string representation of either. You may assume that the input will only contain spaces, digits, and the 5 characters you choose.
* not actually
2Go anywhere*™. – Jonathan Allan – 2017-09-06T14:39:01.280
What's the result of the equality operator?
0
and1
? – Felix Palmen – 2017-09-06T14:40:00.643@JonathanAllan lol – HyperNeutrino – 2017-09-06T14:40:03.973
@FelixPalmen Yes, sorry, I forgot to specify that. It's
0/1
. – HyperNeutrino – 2017-09-06T14:40:18.777@geokavel whoops I removed subtraction – HyperNeutrino – 2017-09-06T15:45:09.200
1@JonathanAllan see above; I removed a command rip – HyperNeutrino – 2017-09-06T15:45:19.450
What is the input format? Can I take a list of tokens? Can I take a string and require each number and operator be separated by a space? Ultimately, I'm trying to not special case multi-digit integer input. – Brian J – 2017-09-06T17:21:14.090
@BrianJ Input is as a string. Tokenization is part of the challenge. – HyperNeutrino – 2017-09-06T18:33:13.847
@HyperNeutrino May we assume that the input contains only digits, whitespace, and our 5 characters? – L3viathan – 2017-09-06T18:43:16.407
@BrianJ Input is as a string. Tokenization is part of the challenge. – HyperNeutrino – 2017-09-06T18:47:40.117
@L3viathan Yes you may, thanks. – HyperNeutrino – 2017-09-06T18:51:22.753
1@RickHitchcock Sure. – HyperNeutrino – 2017-09-06T21:23:47.890
1You probably should include
×+"10 10
in the test cases, or any other examples that are 1) using a whitespace and 2) delaying the use of the duplicate operator (two things that I missed entirely). – Arnauld – 2017-09-07T06:41:18.800@Arnauld Yup, I'll include that, thanks. – HyperNeutrino – 2017-09-07T13:40:39.680