 # calebpollman's solution

## to Wordy in the TypeScript Track

Published at Aug 25 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.

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

## Setup

Go through the setup instructions for TypeScript to install the necessary dependencies:

https://exercism.io/tracks/typescript/installation

## Requirements

Install assignment dependencies:

``````\$ yarn install
``````

## Making the test suite pass

Execute the tests with:

``````\$ yarn test
``````

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by changing `xit` to `it`.

## Source

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

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### wordy.test.ts

``````import { WordProblem, ArgumentError } from './wordy'

describe('Word Problem', () => {

const question = 'What is 1 plus 1?'
})

const question = 'What is 53 plus 2?'
})

xit('add negative numbers', () => {
const question = 'What is -1 plus -10?'
})

xit('add more digits', () => {
const question = 'What is 123 plus 45678?'
})

xit('subtract', () => {
const question = 'What is 4 minus -12?'
})

xit('multiply', () => {
const question = 'What is -3 multiplied by 25?'
})

xit('divide', () => {
const question = 'What is 33 divided by -3?'
})

const question = 'What is 1 plus 1 plus 1?'
})

xit('add then subtract', () => {
const question = 'What is 1 plus 5 minus -2?'
})

xit('subtract twice', () => {
const question = 'What is 20 minus 4 minus 13?'
})

xit('subtract then add', () => {
const question = 'What is 17 minus 6 plus 3?'
})

xit('multiply twice', () => {
const question = 'What is 2 multiplied by -2 multiplied by 3?'
})

xit('add then multiply', () => {
const question = 'What is -3 plus 7 multiplied by -2?'
})

xit('divide twice', () => {
const question = 'What is -12 divided by 2 divided by -3?'
})

const question = 'What is 53 cubed?'
const problem  = new WordProblem(question)

})

xit('irrelevant', () => {
const question = 'Who is the president of the United States?'
const problem  = new WordProblem(question)

})

})``````
``````enum OperationType {
Divided = 'divided',
Minus = 'minus',
Multiplied = 'multiplied',
Plus = 'plus',
}

type Operation = (initialValue: number, parameter: number) => number;

const operationsKey: { [key: string]: Operation } = Object.freeze({
[OperationType.Divided]: (initialValue, parameter) => (initialValue /= parameter),
[OperationType.Minus]: (initialValue, parameter) => (initialValue -= parameter),
[OperationType.Multiplied]: (initialValue, parameter) => (initialValue *= parameter),
[OperationType.Plus]: (initialValue, parameter) => (initialValue += parameter),
});

const OPERATIONS = [OperationType.Divided, OperationType.Minus, OperationType.Multiplied, OperationType.Plus];

export class ArgumentError {}

export class WordProblem {
private operators: string[] = [];
private parameters: number[] = [];
private total: number;

constructor(input: string) {
const words = input.split(' ');
words.forEach(word => {
const parameter = parseInt(word, 10);
if (parameter) {
this.parameters.push(parameter);
return;
}
const hasOperator = OPERATIONS.some(operator => operator === word);
if (hasOperator) {
this.operators.push(word);
}
});

// initialize total
this.total = this.parameters.shift() || 0;
}

if (!this.operators.length) {
throw new ArgumentError();
}
this.operators.forEach((operator: string, index: number) => {
const parameter = this.parameters[index];
const operation = operationsKey[operator];
this.total = operation(this.total, parameter);
});
return this.total;
}
}``````