Question: Elixir Given a string input representing a math expression, we want to convert it into its lexical tokens. We're not going to process the string,
Elixir
Given a string input representing a math expression, we want to convert it into its lexical tokens. We're not going to process the string, this challenge is only concerned with converting the string into a series of tokens.
Example
Given the string:
3x + sin(y + 2.4)
We want convert this into a set of lexical tokens, represented as a nested array of strings, like so:
[ ['Literal', '3'], ['Operator', '*'], ['Variable', 'x'], ['Operator', '+'], ['Function', 'sin'], ['Left Parenthesis', '('], ['Variable', 'y'], ['Operator', '+'], ['Literal', '2.4'], ['Right Parenthesis', ')'], ] Rules
Support the following tokens:
Literal Any integer or decimal number, such as 5 or 3.14159
Operator Any one of +, -, *, /, ^. There's also the implicit multiplication operator, see below
Variable A single-letter variable, a-z, or A-Z
Function A one-or-more letter string that is immediately followed by a left parenthesis ((), such as sin()
Left Parenthesis and Right Parenthesis Used to group arguments or denote a function, these should be broken out on their own in all cases.
Tokens can be separated by any white space. Whitespace is always ignored.
Implicit Multiplication: A Literal can be followed by a Variable, Function, or Left Parenthesis. In this scenario, an implicit Operator of type * is automatically inserted into the output tokens. Note: whitespace is still ignored
For example, 5x is interpreted as 5*x. Other valid forms include 4sin(x) (= 4*sin(x)) or 3 (y+2) (= 3*(y+2)).
Specification
tokenize(expression)
Separates a math expression and converts it to its lexical token
Parameters
expression: String - Mathematical expression
Return Value
Array
Examples
| expression | Return Value |
|---|---|
| "3sin(x)" | [["Literal","3"],["Operator","*"],["Function","sin"],["Left Parenthesis","("],["Variable","x"],["Right Parenthesis",")"]] |
| "3x + sin(y + 2.4)" | [["Literal","3"],["Operator","*"],["Variable","x"],["Operator","+"],["Function","sin"],["Left Parenthesis","("],["Variable","y"],["Operator","+"],["Literal","2.4"],["Right Parenthesis",")"]] |
TEST
defmodule TestSolution do use ExUnit.Case import Challenge, only: [tokenize: 1]
test "should handle an integer literal" do assert tokenize("3") == [["Literal","3"]] end test "should handle a single variable" do assert tokenize("x") == [["Variable","x"]] end test "should handle a decimal literal" do assert tokenize("3.14159") == [["Literal","3.14159"]] end test "should handle a simple expression" do assert tokenize("2+x") == [["Literal","2"],["Operator","+"],["Variable","x"]] end test "should handle the example" do assert tokenize("3x + sin(y + 2.4)") == [["Literal","3"],["Operator","*"],["Variable","x"],["Operator","+"],["Function","sin"],["Left Parenthesis","("],["Variable","y"],["Operator","+"],["Literal","2.4"],["Right Parenthesis",")"]] end end
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
