Problem:
Problem E: The Number of the Real Roots of a Cubic Equation

Description

3次方程式： が与えられるので，その正の実数根の個数，負の実数根の個数をそれぞれ調べて欲しい．

根の個数は，重根も含めて数えるものとする．

Input

入力は複数のテストケースからなり，1行目にはその個数が記される．

2行目以降はa b c dの形式で3次方程式の係数が記される．aは0ではなく，またそれぞれの数は-100から100までの整数値である．

Output

与えられた3次方程式に対し，正の実数根の個数，負の実数根の個数をスペースで区切って出力せよ．

Sample Input

2
1 3 3 1
-10 0 0 0

Output for Sample Input

0 3
0 0

Solution in Kotlin (judge verdict: Wrong Answer)

import jdk.nashorn.internal.objects.NativeEvalError
import java.lang.Math.sqrt

fun main(args:Array<String>):Unit {
    repeat(readLine()!!.toInt()){
        val (a, b, c, d) = readLine()!!.split(' ').map(String::toDouble)
        val cubic = CubicEquation(a, b, c, d)
        var positive = 0
        var negative = 0
        val dec = decideType(cubic)
        when(dec){
            is Type.Increment -> {
                if (cubic(0) > 0) ++negative
                else if (cubic(0) < 0) ++positive
            }
            is Type.Decrement -> {
                if (cubic(0) > 0) ++positive
                else if (cubic(0) < 0) ++negative
            }
            is Type.Up -> {
                if (cubic(dec.left) < 0 || cubic(dec.right) > 0) {
                    if (cubic(0) > 0) ++negative
                    else if(cubic(0) < 0) ++positive
                }else{//解3つ
                    if (dec.left > 0) {
                        if (cubic(0) > 0){
                            negative = 1
                            positive = 2
                        }else if (cubic(0) < 0){
                            positive = 3
                        }else{
                            positive = 2
                        }
                    }else if (dec.right < 0){
                        if (cubic(0) > 0){
                            negative = 3
                        }else if(cubic(0) < 0){
                            positive = 1
                            negative = 2
                        }else {
                            negative = 2
                        }
                    }else {
                        if (cubic(0) > 0){
                            negative = 1
                            positive = 2
                        }else if (cubic(0) < 0){
                            positive = 1
                            negative = 2
                        }else {
                            positive = 1
                            negative = 1
                        }
                    }
                }

            }
            is Type.Down -> {
                if (cubic(dec.right) < 0 || cubic(dec.left) > 0){
                    if (cubic(0) > 0) ++positive
                    else if (cubic(0) < 0) ++negative
                }else {
                    if (dec.left > 0){
                        if (cubic(0) > 0) positive = 3
                        else if(cubic(0) < 0) {
                            positive = 2
                            negative = 1
                        }else{
                            positive = 2
                        }
                    }else if (dec.right < 0){
                        if (cubic(0) > 0){
                            positive = 1
                            negative = 2
                        }else if(cubic(0) < 0) negative = 3
                        else {
                            negative = 2
                        }
                    }else{
                        if (cubic(0) > 0){
                            positive = 1
                            negative = 2
                        }else if (cubic(0) < 0){
                            positive = 2
                            negative = 1
                        }else {
                            positive = 1
                            negative = 1
                        }
                    }
                }
            }
            is Type.Triple -> {
                if (dec.root != .0){
                    if (cubic(dec.root) == .0){
                        if (dec.root > 0) positive = 3
                        else if (dec.root < 0) negative = 3
                    }
                }
            }
        }
        println("$positive $negative")
    }
}
class CubicEquation(val a:Double, val b:Double, val c:Double, val d:Double){
    operator fun invoke(x:Int):Double = a * x * x * x + b * x * x + c * x + d
    operator fun invoke(x:Double):Double = a * x * x * x + b * x * x + c * x + d
}
class SquareEquation(val a:Double, val b:Double, val c:Double){
    fun axis():Double {
        return -b / a / 2
    }
    operator fun invoke(x:Double):Double = a * x * x + b * x + c * x
    fun decide():Double = b * b - 4 * a * c
    fun zeroRoot():Pair<Double, Double> {
        val d = sqrt(b * b - 4 * a * c) / a / 2
        return Pair(-b / a / 2 - d, -b / a / 2 + d)
    }
}
fun decideType(cubicEquation: CubicEquation):Type {
    val square = SquareEquation(3 * cubicEquation.a, 2 * cubicEquation.b, cubicEquation.c)
    return if (square.decide() > 0){
        val (left, right) = square.zeroRoot()
        if (cubicEquation.a > 0) Type.Up(left, right)
        else Type.Down(left, right)
    }else if (square.decide() < 0){
        if (cubicEquation.a > 0) Type.Increment
        else Type.Decrement
    }else {
        Type.Triple(square.axis())
    }
}
sealed class Type{
    object Increment:Type()
    object Decrement:Type()
    class Up(val left:Double, val right:Double):Type()
    class Down(val left:Double, val right:Double):Type()
    class Triple(val root:Double):Type()
}