# artemkorsakov's solution

## to Wordy in the C# Track

Published at Apr 21 2019 · 0 comments
Instructions
Test suite
Solution

Parse and evaluate simple math word problems returning the answer as an integer.

## Iteration 0 — Numbers

Problems with no operations simply evaluate to the number given.

What is 5?

Evaluates to 5.

## Iteration 1 — Addition

Add two numbers together.

What is 5 plus 13?

Evaluates to 18.

Handle large numbers and negative numbers.

## Iteration 2 — Subtraction, Multiplication and Division

Now, perform the other three operations.

What is 7 minus 5?

2

What is 6 multiplied by 4?

24

What is 25 divided by 5?

5

## Iteration 3 — Multiple Operations

Handle a set of operations, in sequence.

Since these are verbal word problems, evaluate the expression from left-to-right, ignoring the typical order of operations.

What is 5 plus 13 plus 6?

24

What is 3 plus 2 multiplied by 3?

15 (i.e. not 9)

## Iteration 4 — Errors

The parser should reject:

• Unsupported operations ("What is 52 cubed?")
• Non-math questions ("Who is the President of the United States")
• Word problems with invalid syntax ("What is 1 plus plus 2?")

## Bonus — Exponentials

If you'd like, handle exponentials.

What is 2 raised to the 5th power?

32

## Hints

• To parse the text, you could try to use the Sprache library. You can also find a good tutorial here.

## Running the tests

To run the tests, run the command `dotnet test` from within the exercise directory.

Initially, only the first test will be enabled. This is to encourage you to solve the exercise one step at a time. Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing. Once none of the tests are skipped and they are all passing, you can submit your solution using `exercism submit Wordy.cs`

## Further information

For more detailed information about the C# track, including how to get help if you're having trouble, please visit the exercism.io C# language page.

## Source

Inspired by one of the generated questions in the Extreme Startup game. https://github.com/rchatley/extreme_startup

### WordyTest.cs

``````// This file was auto-generated based on version 1.5.0 of the canonical data.

using System;
using Xunit;

public class WordyTest
{
[Fact]
public void Just_a_number()
{
Assert.Equal(5, Wordy.Answer("What is 5?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(2, Wordy.Answer("What is 1 plus 1?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(55, Wordy.Answer("What is 53 plus 2?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(-11, Wordy.Answer("What is -1 plus -10?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(45801, Wordy.Answer("What is 123 plus 45678?"));
}

[Fact(Skip = "Remove to run test")]
public void Subtraction()
{
Assert.Equal(16, Wordy.Answer("What is 4 minus -12?"));
}

[Fact(Skip = "Remove to run test")]
public void Multiplication()
{
Assert.Equal(-75, Wordy.Answer("What is -3 multiplied by 25?"));
}

[Fact(Skip = "Remove to run test")]
public void Division()
{
Assert.Equal(-11, Wordy.Answer("What is 33 divided by -3?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(3, Wordy.Answer("What is 1 plus 1 plus 1?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(8, Wordy.Answer("What is 1 plus 5 minus -2?"));
}

[Fact(Skip = "Remove to run test")]
public void Multiple_subtraction()
{
Assert.Equal(3, Wordy.Answer("What is 20 minus 4 minus 13?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(14, Wordy.Answer("What is 17 minus 6 plus 3?"));
}

[Fact(Skip = "Remove to run test")]
public void Multiple_multiplication()
{
Assert.Equal(-12, Wordy.Answer("What is 2 multiplied by -2 multiplied by 3?"));
}

[Fact(Skip = "Remove to run test")]
{
Assert.Equal(-8, Wordy.Answer("What is -3 plus 7 multiplied by -2?"));
}

[Fact(Skip = "Remove to run test")]
public void Multiple_division()
{
Assert.Equal(2, Wordy.Answer("What is -12 divided by 2 divided by -3?"));
}

[Fact(Skip = "Remove to run test")]
public void Unknown_operation()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is 52 cubed?"));
}

[Fact(Skip = "Remove to run test")]
public void Non_math_question()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("Who is the President of the United States?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_problem_missing_an_operand()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is 1 plus?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_problem_with_no_operands_or_operators()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_two_operations_in_a_row()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is 1 plus plus 2?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_two_numbers_in_a_row()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is 1 plus 2 1?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_postfix_notation()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is 1 2 plus?"));
}

[Fact(Skip = "Remove to run test")]
public void Reject_prefix_notation()
{
Assert.Throws<ArgumentException>(() => Wordy.Answer("What is plus 1 2?"));
}
}``````
``````using System;
using System.Text.RegularExpressions;

public static class Wordy
{
private static readonly Regex regexNumber = new Regex("-?\\d+");
private static readonly Regex regexInitialNumber = new Regex("What is " + regexNumber);
private static readonly Regex regexAddition = new Regex(" plus " + regexNumber);
private static readonly Regex regexSubtraction = new Regex(" minus " + regexNumber);
private static readonly Regex regexMultiplication = new Regex(" multiplied by " + regexNumber);
private static readonly Regex regexDivision = new Regex(" divided by " + regexNumber);
private static readonly Regex regexPower = new Regex(" raised to the \\d+[a-z]{2} power");
private static readonly Regex regexMembers = new Regex("(" + regexAddition + "|" + regexSubtraction + "|" + regexMultiplication + "|" + regexDivision + "|" + regexPower + ")");
private static readonly Regex regexAll = new Regex("^" + regexInitialNumber + regexMembers + "*\\?\$");

public static int Answer(string question)
{
if (!regexAll.IsMatch(question))
{
throw new ArgumentException("I'm sorry, I don't understand the question!");
}

int result = GetInitial(question);
foreach (Match match in regexMembers.Matches(question))
{
result = result.Solve(match.Value);
}
return result;
}

private static int GetInitial(string input) => GetNumber(regexInitialNumber.Match(input).Value);

private static int Solve(this int result, string input) => regexAddition.IsMatch(input)
? result + GetNumber(regexAddition.Match(input).Value)
: regexSubtraction.IsMatch(input)
? result - GetNumber(regexSubtraction.Match(input).Value)
: regexMultiplication.IsMatch(input)
? result * GetNumber(regexMultiplication.Match(input).Value)
: regexDivision.IsMatch(input)
? result / GetNumber(regexDivision.Match(input).Value)
: regexPower.IsMatch(input)
? (int)Math.Pow(result, GetNumber(regexPower.Match(input).Value))
: result;

private static int GetNumber(string input) => int.Parse(regexNumber.Match(input).Value);
}``````