Polynomial long division: Difference between revisions

Content added Content deleted
(→‎{{header|Kotlin}}: remove unnecessary package declaration)
(→‎{{header|Kotlin}}: Restored original version as Swift and Wren entries are translations of it.)
Line 2,388: Line 2,388:


=={{header|Kotlin}}==
=={{header|Kotlin}}==
===Version 1===
<lang kotlin>class Polynom(private vararg val factors: Double) {
<lang scala>// version 1.1.51
typealias IAE = IllegalArgumentException
data class Solution(val quotient: DoubleArray, val remainder: DoubleArray)
fun polyDegree(p: DoubleArray): Int {
for (i in p.size - 1 downTo 0) {
if (p[i] != 0.0) return i
}
return Int.MIN_VALUE
}
fun polyShiftRight(p: DoubleArray, places: Int): DoubleArray {
if (places <= 0) return p
val pd = polyDegree(p)
if (pd + places >= p.size) {
throw IAE("The number of places to be shifted is too large")
}
val d = p.copyOf()
for (i in pd downTo 0) {
d[i + places] = d[i]
d[i] = 0.0
}
return d
}
fun polyMultiply(p: DoubleArray, m: Double) {
for (i in 0 until p.size) p[i] *= m
}
fun polySubtract(p: DoubleArray, s: DoubleArray) {
for (i in 0 until p.size) p[i] -= s[i]
}
fun polyLongDiv(n: DoubleArray, d: DoubleArray): Solution {
if (n.size != d.size) {
throw IAE("Numerator and denominator vectors must have the same size")
}
var nd = polyDegree(n)
val dd = polyDegree(d)
if (dd < 0) {
throw IAE("Divisor must have at least one one-zero coefficient")
}
if (nd < dd) {
throw IAE("The degree of the divisor cannot exceed that of the numerator")
}
val n2 = n.copyOf()
val q = DoubleArray(n.size) // all elements zero by default
while (nd >= dd) {
val d2 = polyShiftRight(d, nd - dd)
q[nd - dd] = n2[nd] / d2[nd]
polyMultiply(d2, q[nd - dd])
polySubtract(n2, d2)
nd = polyDegree(n2)
}
return Solution(q, n2)
}
fun polyShow(p: DoubleArray) {
val pd = polyDegree(p)
for (i in pd downTo 0) {
val coeff = p[i]
if (coeff == 0.0) continue
print (when {
coeff == 1.0 -> if (i < pd) " + " else ""
coeff == -1.0 -> if (i < pd) " - " else "-"
coeff < 0.0 -> if (i < pd) " - ${-coeff}" else "$coeff"
else -> if (i < pd) " + $coeff" else "$coeff"
})
if (i > 1) print("x^$i")
else if (i == 1) print("x")
}
println()
}
fun main(args: Array<String>) {
val n = doubleArrayOf(-42.0, 0.0, -12.0, 1.0)
val d = doubleArrayOf( -3.0, 1.0, 0.0, 0.0)
print("Numerator : ")
polyShow(n)
print("Denominator : ")
polyShow(d)
println("-------------------------------------")
val (q, r) = polyLongDiv(n, d)
print("Quotient : ")
polyShow(q)
print("Remainder : ")
polyShow(r)
}</lang>

{{out}}
<pre>
Output:

Numerator : x^3 - 12.0x^2 - 42.0
Denominator : x - 3.0
-------------------------------------
Quotient : x^2 - 9.0x - 27.0
Remainder : -123.0
</pre>
<br>
===Version 2===
More succinct version that provides an easy-to-use API.
<lang scala>class Polynom(private vararg val factors: Double) {


operator fun div(divisor: Polynom): Pair<Polynom, Polynom> {
operator fun div(divisor: Polynom): Pair<Polynom, Polynom> {