
/**
 * Rational is a class which can store a rational number of the form n/d
 * where n and d are integers, n is the numerator, and d is the denominator
 */
public class Rational
{
    private int _numerator;
    private int _denominator;

    /**
     * This default constructor creates a Rational with value 0
     */
    public Rational()
    {
        this(0, 1);
    }

    /**
     * This constructor creates a Rational with value numerator/denominator
     * @param numerator the numerator of the Rational
     * @param denominator the denominator of the Rational
     */
    public Rational(int numerator, int denominator)
    {
        _numerator = numerator;
        _denominator = denominator;
        reduce();
    }

    /**
     * add adds this Rational to another
     * @param other the Rational to add to this one
     * @return the result of the addition
     */
    public Rational add(Rational other)
    {
        return new Rational(_numerator * other._denominator +
                                other._numerator * _denominator,
                            _denominator * other._denominator);
    }

    /**
     * subtract subtracts another Rational from this one
     * @param other the other Rational to subtract from this one
     * @return the result of the subtraction
     */
    public Rational subtract(Rational other)
    {
        return new Rational(_numerator * other._denominator -
                                other._numerator * _denominator,
                            _denominator * other._denominator);
    }

    /**
     * multiply multiplies this Rational with another
     * @param other the other Rational to multiply with this one
     * @return the result of the multiplication
     */
    public Rational multiply(Rational other)
    {
        return new Rational(_numerator * other._numerator,
                            _denominator * other._denominator);
    }

    /**
     * divide divides another Rational into this one
     * @param other the other Rational to divide into this one
     * @return the result of the division
     */
    public Rational divide(Rational other)
    {
        return new Rational(_numerator * other._denominator,
                            _denominator * other._numerator);
    }

    /**
     * gcd calculates the greatest common divisor between the
     * numerator and the denominator
     * @return the greatest common divisor
     */
    private int gcd()
    {
        int m = _numerator;
        int n = _denominator;
        int r;
        while (n != 0)
        {
            r = m % n;
            m = n;
            n = r;
        }
        return m;
    }

    /**
     * reduce reduces the Rational to simplest terms using the gcd
     * @return itself
     */
    public Rational reduce()
    {
        int thegcd = gcd();
        _numerator = _numerator / thegcd;
        _denominator = _denominator / thegcd;
        return this;
    }
    
    /**
     * toString returns a string representation of the Rational in n/m form
     * @return a string representation of the Rational in n/m form
     */
    public String toString()
    {
        return _numerator + (_denominator == 1 ? "" : "/" + _denominator);
    }
}
