Problem:
かぐや

いよいよ今月末に「はやぶさ２」が打ち上げられます。４年前に「はやぶさ」が帰ってきたときは、日本中が盛り上がったのを覚えている人も多いと思います。７年前には、「かぐや」が打ち上げられ、月の周りを回りながらたくさんの鮮明な画像を地球に送ってくれました。

上の図は、地球を原点とした空間座標（z軸は紙面から垂直に下から上に向いているものとします）に、月の軌道といくつかの月の位置、月の周りを回るかぐやの軌道を描いたものです。月の軌道は、x軸とy軸を通る平面上にある、原点を中心とする円とします。月の周りを回るかぐやの軌道は、x軸とz軸を通る平面に平行な平面上にある円とし、その中心は月の中心と一致します。月は、その軌道に沿って描かれた矢印の方向に回っているものとします。

右の図で、月の位置はＡ，Ｂ，Ｃの３つが描かれています。月を横切る直線がかぐやの軌道です。かぐやは月の周りを回っているので軌道は円ですが、z軸の正の方向から見ているので、図のx軸に平行な直線に見えます（月の位置が変わっても、つねにx軸に平行であることに注意してください）。かぐやは、その軌道上に描かれた矢印の方向に回っているものとします。

かぐやが地球から見て月の裏側に隠れてしまうと、地球と直接通信ができなくなります。かぐやの管制を担当するあなたは、かぐやが月の裏側に隠れる時間が、与えられた時間の中でどれだけになるかをプログラムで求めようとしています。

月の地球に対する位置と分単位での時間tが与えられたとき、その位置から始めてt分後までの間に、かぐやが月の裏側に隠れる時間を求めるプログラムを作成してください。ただし、地球とかぐやは点、月は半径 1800 km の球と考えます。月は半径 380000 km の軌道を 2500000 秒で一周し、かぐやは月の表面から高度 100 km の円上を２時間で一周するものとします。かぐやの最初の位置は、かぐやの軌道がz座標で最大の値をとる位置とします。

入力

入力は以下の形式で与えられる。

m t

m (0 ≤ m < 360) は月の位置を上の図のx軸の正の部分からy軸の正の部分に向かって反時計回りに測った角度を整数で表したものである。t (1 ≤ t ≤ 10000) は分で測った時間を表す整数である。

出力

はじめの位置から t 分経過するまでの間に、かぐやが月の裏側に隠れる時間（分）を実数で出力する。ただし、誤差がプラスマイナス 1.0 分を超えてはならない。この条件を満たせば小数点以下何桁表示してもよい。

入出力例

入力例１

90 10

出力例１

0.0

入力例２

0 120

出力例２

47.73

Solution in Kotlin (judge verdict: Accepted)

import java.lang.Math.*

fun main(args:Array<String>):Unit {
    val moonRadius:Double = 1800.0
    val moonApoapsis:Double = 380000.0
    val kaguya = Orbit(Point(0.0, 0.0, 100 + moonRadius), 2 * PI / 7200, Vector(.0, 1.0, .0))
    val (m, t) = readLine()!!.trim().split(' ').map(String::toInt)
    val moon = Orbit(Point(cos(m * PI / 180) * moonApoapsis, sin(m * PI / 180) * moonApoapsis, .0), 2 * PI / 2500000, Vector(.0, .0, -1.0))
    var shadowingTime = 0
    val moonSize = sqrt(moonApoapsis * moonApoapsis - moonRadius * moonRadius) / moonApoapsis
    for (time in 0 .. 60 * t){
        val moonPos = moon.positionAt(time)//
        val kaguyaVector = (kaguya.positionAt(time) + moonPos).toVector()
        val moonVector = moonPos.toVector()
        //if (time % 3600 == 0) println(kaguyaVector)
        if (kaguyaVector.length >= moonSize * moonApoapsis && kaguyaVector.cos(moonVector) > moonSize) {
            ++shadowingTime
        }
    }
    println(shadowingTime / 60.0)
}
class Orbit(startPosition:Point, private val mVelocity:Double, private val mAxis:Vector){
    private val mStartPosition = startPosition.toQuaternion()
    fun positionAt(currentSecond:Int):Point {
        val q = Quaternion.screwLeft(mAxis, mVelocity * currentSecond)
        return (q * mStartPosition * conjugate(q)).toPoint()
    }
}
data class Point(val x:Double, val y:Double, val z:Double){
    constructor(x:Int, y:Int, z:Int):this(x.toDouble(), y.toDouble(), z.toDouble())
    operator fun plus(that:Point):Point = Point(x + that.x, y + that.y, z + that.z)
    operator fun minus(that:Point):Point = Point(x - that.x, y - that.y, z - that.z)
}
fun Quaternion.toPoint():Point{
    return Point(this.i, this.j, this.k)
}
fun Point.toQuaternion():Quaternion{
    return Quaternion(0e0, this.x, this.y, this.z)
}
data class Vector(val x:Double, val y:Double, val z:Double){
    val length:Double = sqrt(x * x + y * y + z * z)
    private fun map(transformer:(Double) -> Double):Vector = Vector(transformer(x), transformer(y), transformer(z))
    operator fun times(other:Double):Vector = map{it * other}
    operator fun div(other:Double):Vector = map{it / other}
    fun dot(that:Vector):Double = x * that.x + y * that.y + z * that.z
    fun cos(that:Vector):Double = dot(that) / length / that.length
}

fun Vector.toQuaternion():Quaternion {
    return Quaternion(0e0, this.x, this.y, this.z)
}
fun Point.toVector():Vector{
    return Vector(this.x, this.y, this.z)
}
data class Quaternion(val real:Double, val i:Double, val j:Double, val k:Double){
    operator fun plus(that:Quaternion):Quaternion = Quaternion(real + that.real, i + that.i, j + that.j, k + that.k)
    operator fun times(that:Quaternion):Quaternion {
        return timesR(that.real) + timesI(that.i) + timesJ(that.j) + timesK(that.k)
    }
    operator fun minus(that:Quaternion):Quaternion = Quaternion(real - that.real, i - that.i, j - that.j, k - that.k)
    private fun timesI(value:Double):Quaternion = Quaternion(-i * value, real * value, -k * value, j * value)
    private fun timesJ(value:Double):Quaternion = Quaternion(-j * value, k * value, real * value, -i * value)
    private fun timesK(value:Double):Quaternion = Quaternion(-k * value, -j * value, i * value, real * value)
    private fun timesR(value:Double):Quaternion = Quaternion(real * value, i * value, j * value, k * value)
    companion object {
        fun screwLeft(axis:Vector, radian:Double):Quaternion {
            val normalizedAxis = axis / axis.length * sin(radian / 2)
            return Quaternion(cos(radian / 2), normalizedAxis.x, normalizedAxis.y, normalizedAxis.z)
        }
    }
}
fun conjugate(quaternion: Quaternion):Quaternion {
    return Quaternion(quaternion.real, -quaternion.i, -quaternion.j, -quaternion.k)
}