## Preamble

A rational number is defined as the quotient of two integers `a` and `b`, called the numerator and denominator, respectively, where `b != 0`.

• The absolute value `|r|` of the rational number `r = a/b` is equal to `|a|/|b|`.
• The sum of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 + r2 = a1/b1 + a2/b2 = (a1 * b2 + a2 * b1) / (b1 * b2)`.
• The difference of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 - r2 = a1/b1 - a2/b2 = (a1 * b2 - a2 * b1) / (b1 * b2)`.
• The product (multiplication) of two rational numbers `r1 = a1/b1` and `r2 = a2/b2` is `r1 * r2 = (a1 * a2) / (b1 * b2)`.
• Dividing a rational number `r1 = a1/b1` by another `r2 = a2/b2` is `r1 / r2 = (a1 * b2) / (a2 * b1)` if `a2 * b1` is not zero.
• Exponentiation of a rational number `r = a/b` to a non-negative integer power `n` is `r^n = (a^n)/(b^n)`.
• Exponentiation of a rational number `r = a/b` to a negative integer power `n` is `r^n = (b^m)/(a^m)`, where `m = |n|`.
• Exponentiation of a rational number `r = a/b` to a real (floating-point) number `x` is the quotient `(a^x)/(b^x)`, which is a real number.
• Exponentiation of a real number `x` to a rational number `r = a/b` is `x^(a/b) = root(x^a, b)`, where `root(p, q)` is the `q`th root of `p`.

## Requirements

Implement the following operations on Rational Numbers:

• addition, subtraction, multiplication, and division of two rational numbers,
• absolute value of a given rational number,
• exponentiation of a given rational number to an integer power,
• exponentiation of a given rational number to a real (floating-point) power,
• exponentiation of a real number to a rational number, and
• display as `n/d`, where `n` is the numerator and `d` is the denominator.

Your implementation should meet the following conditions:

• All rational numbers should be immutable; that is, there should be no external mechanism to change the components of the number after it has been created; most of your methods will simply return a new rational number.
• The denominator may not be zero.
• The denominator should never be negative.
(You may provide a negative number for the denominator via the constructor when you create the rational, but a negative rational should be represented internally with a negative numerator and a positive denominator.)
• Zero should be represented as `0/1`.
• Always be reduced to lowest terms.
For example, `4/4` should reduce to `1/1`, `30/60` should reduce to `1/2`, `12/8` should reduce to `3/2`, etc.
To reduce a rational number `r = a/b`, divide `a` and `b` by the greatest common divisor (gcd) of `a` and `b`.
For example, the `gcd(12, 8) = 4`, therefore `r = 12/8` can be reduced to `(12/4)/(8/4) = 3/2`.
• Use (at least) one additional [extension method][extension].
• Utilise [operator overloading methods][overload] for the `+`, `-`, `*`, and `/` operators.

Assume that the programming language you are using does not have an implementation of rational numbers.

## The code

• You are provided with some skeletal code for both for the `Rational` entity and its tests.
• You are required to complete the code.
• You should not assume the provided code is correct — check it thoroughly.
• In particular you should remember to add initial tests as the provided tests are “minimal”.
• Your goal in writing the tests for the `Rational` class is too test for every possible condition, including that the correct exceptions are thrown (where appropriate).

## Testing

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 to pass remove the `Skip` property from the next test, and continue to work on getting that test to pass (and the previous test(s)) - repeat until all the tests pass.

## Resources

Percentage Criteria
40% For functionality, including testing, using the facilities of the language if possible, and that your program works according to the specification!
40% For coding in the idiomatic style of the programming language (i.e., `C#`).
20% For adequate comments, proper formatting, indentation, choosing proper names, following naming conventions, and for correct submission.

## Important Information

• Need to write in C#
• Need to write clean code
• Premature Optimisation, as described by one of the current programming Gurus — Martin Fowler (“Yet Another Optimisation Article“), is frowned upon.
• Code needs to be well structured
• Need to write comments each line to explain what it does
• Need to have proper formatting, indentation, choosing proper names, and following naming conventions.
• Need to have clear identifier names and abbreviations
• Code don’t contain inappropriate hard-coded values
• Code need to be easily maintainable
• Need to write testing, using the facilities of C# language