Skip to content

Instantly share code, notes, and snippets.

@phi16
Created May 30, 2015 17:01
Show Gist options
  • Save phi16/8e4b0346f3f0ab65ddbe to your computer and use it in GitHub Desktop.
Save phi16/8e4b0346f3f0ab65ddbe to your computer and use it in GitHub Desktop.
line :: Proc String -- same as getLine
solveB :: Proc String
solveB = do
[nS,vS,xS] <- words <$> line
let
n = read nS :: Int
[v,x] = map read [vS,xS] :: [Double]
ss <- map (map read . words) <$> replicateM n line
let
minS = map (\xs -> (sum $ map fst xs, snd $ head xs)) $ groupBy ((==)`on`snd) $ map (\[r,c] -> (r,c)) $ sortBy (compare`on`(!!1)) ss
maxS = reverse minS
maxT = (*2) $ v / (minimum $ map fst minS) + 0.1
temp :: [(Double,Double)] -> Double -> Maybe Double
temp xs t = toMaybe $ foldl f (Left (0,0)) xs where
f (Right x) _ = Right x
f (Left (p,c)) (u,y)
| p + t*u < v = Left (p+t*u, c+u*y*t)
| otherwise = Right $ c/v+(1-p/v)*y
toMaybe (Left (p,c)) = Nothing
toMaybe (Right x) = Just x
check :: Double -> Bool
check t = let
nT = temp minS t
xT = temp maxS t
in case (nT,xT) of
(Just p, Just q) -> p <= x && x <= q
_ -> False
bSearch :: (Double,Double) -> Double
bSearch (l,r)
| abs (r-l) < 1e-8 = (l+r)/2
| otherwise = let t = (l+r)/2 in case check t of
True -> bSearch (l,t)
False -> bSearch (t,r)
return $ case check maxT of
True -> show $ bSearch (0,maxT)
False -> "IMPOSSIBLE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment