import java.util.*; /** This class represents fractions of form n/d where n and d are long integer * numbers. Basic operations and arithmetics for fractions are provided. */ public class Lfraction implements Comparable { /** Main method. Different tests. */ public static void main (String[] param) { // TODO!!! Your debugging tests here } private long nu; private long de; /** Constructor. * @param a numerator * @param b denominator > 0 */ public Lfraction (long a, long b) { if (b < 1) { throw new RuntimeException("Denominator can't be 0 or less"); } this.nu = a; this.de = b; } /** Public method to access the numerator field. * @return numerator */ public long getNumerator() { return this.nu; } /** Public method to access the denominator field. * @return denominator */ public long getDenominator() { return this.de; } /** Conversion to string. * @return string representation of the fraction */ @Override public String toString() { return ""+Long.toString(this.nu)+"/"+Long.toString(this.de); } /** Equality test. * @param m second fraction * @return true if fractions this and m are equal */ @Override public boolean equals (Object m) { Lfraction other = (Lfraction) m; if (other.de == this.de) { return this.nu == other.nu; } else { double dif; if (other.de > this.de) { dif = other.de / this.de; } else { dif = this.de / other.de; } return (this.nu*dif) == other.nu; } } /** Hashcode has to be equal for equal fractions. * @return hashcode */ @Override public int hashCode() { return Objects.hash(this.nu, this.de); } /** Reduce the fraction * @return reduced Lfraction */ public Lfraction reduce() { long common; if (this.nu == this.de) { common = this.nu; } else { long de1; long de2; if (this.nu > this.de) { de1 = this.nu; de2 = this.de; } else { de1 = this.de; de2 = this.nu; } long f; while (de2 != 0) { f = de2; de2 = de1 % de2; de1 = f; } common = de1; } return new Lfraction(this.nu / common, this.de / common); } /** Sum of fractions. * @param m second addend * @return this+m */ public Lfraction plus (Lfraction m) { if (this.de == m.de) { return new Lfraction(this.nu + m.nu, this.de); } else { return new Lfraction((m.nu*this.de)+(this.nu*m.de), (m.de*this.de)); } } /** Multiplication of fractions. * @param m second factor * @return this*m */ public Lfraction times (Lfraction m) { return new Lfraction(this.nu * m.nu, this.de * m.de).reduce(); } /** Inverse of the fraction. n/d becomes d/n. * @return inverse of this fraction: 1/this */ public Lfraction inverse() { if (this.nu < 1) { return new Lfraction(-this.de, -this.nu); } else { return new Lfraction(this.de, this.nu); } } /** Opposite of the fraction. n/d becomes -n/d. * @return opposite of this fraction: -this */ public Lfraction opposite() { return new Lfraction(-this.nu, this.de); } /** Difference of fractions. * @param m subtrahend * @return this-m */ public Lfraction minus (Lfraction m) { if (this.de == m.de) { return new Lfraction(this.nu - m.nu, this.de); } else { return new Lfraction((this.nu*m.de)-(m.nu*this.de), (m.de*this.de)).reduce(); } } /** Quotient of fractions. * @param m divisor * @return this/m */ public Lfraction divideBy (Lfraction m) { long nu = Math.abs(this.nu * m.de); long de = Math.abs(this.de * m.nu); return new Lfraction(nu, de).reduce(); } /** Comparision of fractions. * @param m second fraction * @return -1 if this < m; 0 if this==m; 1 if this > m */ @Override public int compareTo (Lfraction m) { if (this.equals(m)) { return 0; } else if (this.nu * m.de < m.nu * this.de) { return -1; } else { return 1; } } /** Clone of the fraction. * @return new fraction equal to this */ @Override public Object clone() throws CloneNotSupportedException { return new Lfraction(this.nu, this.de); } /** Integer part of the (improper) fraction. * @return integer part of this fraction */ public long integerPart() { return this.nu/this.de; } /** Extract fraction part of the (improper) fraction * (a proper fraction without the integer part). * @return fraction part of this fraction */ public Lfraction fractionPart() { if (this.nu >= this.de || -this.nu >= this.de) { return new Lfraction(this.nu % this.de, this.de); } else { return new Lfraction(this.nu, this.de); } } /** Approximate value of the fraction. * @return numeric value of this fraction */ public double toDouble() { return (double)this.nu/this.de; } /** Double value f presented as a fraction with denominator d > 0. * @param f real number * @param d positive denominator for the result * @return f as an approximate fraction of form n/d */ public static Lfraction toLfraction (double f, long d) { return new Lfraction(Math.round(f * d), d); } /** Conversion from string to the fraction. Accepts strings of form * that is defined by the toString method. * @param s string form (as produced by toString) of the fraction * @return fraction represented by s */ public static Lfraction valueOf (String s) { String[] parts = s.split("/"); return new Lfraction(Long.parseLong(parts[0]), Long.parseLong(parts[1])); } }