Advertisement
jules0707

Rational.kt

Oct 7th, 2021 (edited)
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 4.48 KB | None | 0 0
  1. package rationals
  2.  
  3. import java.math.BigInteger
  4. import java.math.BigInteger.ZERO
  5. import kotlin.math.sign
  6.  
  7. class Rational(num: BigInteger, den: BigInteger) {
  8.     val n: BigInteger
  9.     val d: BigInteger
  10.  
  11.     init {
  12.         require(den != ZERO) { "denominator cannot be zero" }
  13.         val s = (num * den).signum().toBigInteger()
  14.         val g = num.gcd(den)
  15.         this.n = num.abs() / g * s
  16.         this.d = den.abs() / g
  17.     }
  18.  
  19.     constructor(nd: String) : this(
  20.         nd.trim('[').trim(']').toBigInteger(), 1.toBigInteger()
  21.     )
  22.  
  23.     override fun toString(): String {
  24.         return if (d.toInt() != 1) {
  25.             "$n/$d"
  26.         } else this.n.toString()
  27.     }
  28.  
  29.     override fun equals(other: Any?): Boolean {
  30.         if (this === other) return true
  31.         if (javaClass != other?.javaClass) return false
  32.         other as Rational
  33.         if (n != other.n) return false
  34.         if (d != other.d) return false
  35.         return true
  36.     }
  37.  
  38.     override fun hashCode(): Int {
  39.         var result = n.hashCode()
  40.         result = 31 * result + d.hashCode()
  41.         return result
  42.     }
  43. }
  44.  
  45. infix fun Number.divBy(that: Number): Rational {
  46.     val n = this.toString().toBigInteger()
  47.     val d = that.toString().toBigInteger()
  48.     return Rational(n , d )
  49. }
  50.  
  51. class RationalRange(val start:Rational, val end:Rational) {
  52. }
  53.  
  54. operator fun Rational.rangeTo(that: Rational): RationalRange {
  55.     return RationalRange(this.n.divBy(this.d), that.n.divBy(that.d))
  56. }
  57.  
  58. infix operator fun RationalRange.contains(that: Rational): Boolean {
  59.     val a = this.start.n
  60.     val b = this.start.d
  61.     val c = this.end.n
  62.     val d = this.end.d
  63.     val e = that.n
  64.     val f = that.d
  65.     val sn = a * d * f
  66.     val en = c * b * f
  67.     return (e * b * d) in sn..en
  68. }
  69.  
  70. fun String.toRational(): Rational {
  71.     val nd = this.split("/", ignoreCase = true, limit = 0)
  72.     return if (nd.size > 1) {
  73.         val n = nd.first().toBigInteger()
  74.         val d = nd.last().toBigInteger()
  75.         val g = n.gcd(d)
  76.         val s = (n * d).signum()
  77.         val a = s.toBigInteger() * n.abs()
  78.         val b = d.abs()
  79.         Rational(a / g, b / g)
  80.     } else Rational(nd.toString())
  81. }
  82.  
  83. operator fun Rational.plus(that: Rational): Rational {
  84.     val a = this.d
  85.     val b = that.d
  86.     val g = a.gcd(b)
  87.     val l = (a * b) / g
  88.     return Rational(((this.n * that.d) + (that.n * this.d)) / g, l)
  89. }
  90.  
  91. operator fun Rational.minus(that: Rational): Rational {
  92.     val a = this.d
  93.     val b = that.d
  94.     val g = a.gcd(b)
  95.     val l = a * b / g
  96.     return Rational(((this.n * that.d) - (that.n * this.d)) / g, l)
  97. }
  98.  
  99. operator fun Rational.times(that: Rational): Rational {
  100.     val n = this.n.times(that.n)
  101.     val d = this.d.times(that.d)
  102.     val g = n.gcd(d)
  103.     return Rational(n / g, d / g)
  104. }
  105.  
  106. operator fun Rational.div(that: Rational): Rational {
  107.     return Rational(this.n.times(that.d), this.d.times(that.n))
  108. }
  109.  
  110. operator fun Rational.unaryMinus(): Rational {
  111.     return Rational(this.n.times((-1).toBigInteger()), this.d)
  112. }
  113.  
  114. infix operator fun Rational.compareTo(that: Rational): Int {
  115.     val a = this.n
  116.     val b = this.d
  117.     val s1 = (a * b).signum()
  118.     val c = that.n
  119.     val d = that.d
  120.     val s2 = (c * d).signum()
  121.     val s = (s1 * s2).sign
  122.     return if (s > 0) {
  123.         (a * d).compareTo(c * b)
  124.     } else s1.compareTo(s2)
  125. }
  126.  
  127. fun main() {
  128.     val half = 1 divBy 2
  129.     val third = 1 divBy 3
  130.  
  131.     val sum: Rational = half + third
  132.     println(5 divBy 6 == sum)
  133.  
  134.     val difference: Rational = half - third
  135.     println(1 divBy 6 == difference)
  136.  
  137.     val product: Rational = half * third
  138.     println(1 divBy 6 == product)
  139.  
  140.     val quotient: Rational = half / third
  141.     println(3 divBy 2 == quotient)
  142.  
  143.     val negation: Rational = -half
  144.     println(-1 divBy 2 == negation)
  145.  
  146.     println((2 divBy 1).toString() == "2")
  147.     println((-2 divBy -4).toString() == "1/2")
  148.     println("117/1098".toRational().toString() == "13/122")
  149.  
  150.     val twoThirds = 2 divBy 3
  151.     println(half > -twoThirds)
  152.  
  153.     val gdnb1 = Rational("20325830850349869048604856908")
  154.     val gdnb2 = Rational("-9192901948302584358938698")
  155.     println(gdnb1 > gdnb2)
  156.  
  157.     println(half in third..twoThirds)
  158.     println(2000000000L divBy 4000000000L == 1 divBy 2)
  159.  
  160.     println(half in third..twoThirds)
  161.     println(2000000000L divBy 4000000000L == 1 divBy 2)
  162.     println("912016490186296920119201192141970416029".toBigInteger() divBy
  163.             "1824032980372593840238402384283940832058".toBigInteger() == 1 divBy 2)
  164.  
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement