{-# LANGUAGE BangPatterns, NoImplicitPrelude #-}

module UnitFractionsDecomposition2 where

import GHC.Base
import GHC.Num ((+),(-),(*),abs)
import GHC.List (null)
import Data.List (minimumBy)
import GHC.Real (infinity,fromRational,round,fromIntegral,(/),truncate)

setOfSolutions :: Double -> Double -> [(Double, Double)]
setOfSolutions :: Double -> Double -> [(Double, Double)]
setOfSolutions Double
k Double
n 
 | Double
0 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
k Bool -> Bool -> Bool
&& Double
k Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1 Bool -> Bool -> Bool
&& Double
n Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double -> Double
minProportion Double
k = [(Double
x, Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/(Double
kDouble -> Double -> Double
forall a. Num a => a -> a -> a
*Double
x Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
1)) | Double
x <- [Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
1.0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
k)) Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
1.0..Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
2.0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
k))]]
 | Bool
otherwise = []
{-# INLINE setOfSolutions #-}

suitable2 :: Double -> Double -> (Double,Double)
suitable2 :: Double -> Double -> (Double, Double)
suitable2 Double
k Double
n
 | [(Double, Double)] -> Bool
forall a. [a] -> Bool
null [(Double, Double)]
xs = (Double
forall a. HasCallStack => a
undefined, Double
forall a. HasCallStack => a
undefined)
 | Bool
otherwise = ((Double, Double) -> (Double, Double) -> Ordering)
-> [(Double, Double)] -> (Double, Double)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (\(Double
_, Double
y1) (Double
_, Double
y2) -> Double -> Double -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Double -> Double
forall a. Num a => a -> a
abs (Double
y1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
y1))) (Double -> Double
forall a. Num a => a -> a
abs (Double
y2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
y2)))) [(Double, Double)]
xs
      where !xs :: [(Double, Double)]
xs = Double -> Double -> [(Double, Double)]
setOfSolutions Double
k Double
n
{-# INLINE suitable2 #-}

suitable21 :: Double -> Double -> ([Double],Double)
suitable21 :: Double -> Double -> ([Double], Double)
suitable21 Double
k Double
n 
 | [(Double, Double)] -> Bool
forall a. [a] -> Bool
null [(Double, Double)]
xs = ([],Double
forall a. HasCallStack => a
undefined)
 | Bool
otherwise = let (!Double
a,!Double
b) = ((Double, Double) -> (Double, Double) -> Ordering)
-> [(Double, Double)] -> (Double, Double)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (\(Double
_, Double
y1) (Double
_, Double
y2) -> Double -> Double -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Double -> Double
forall a. Num a => a -> a
abs (Double
y1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
y1))) (Double -> Double
forall a. Num a => a -> a
abs (Double
y2 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
y2)))) [(Double, Double)]
xs
    in ([Double
a,Double
b],Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- (Double
1.0Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
a Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
1.0Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
round Double
b)))
      where !xs :: [(Double, Double)]
xs = Double -> Double -> [(Double, Double)]
setOfSolutions Double
k Double
n
{-# INLINE suitable21 #-}

minProportion :: Double -> Double
minProportion :: Double -> Double
minProportion Double
k 
 | Double
0 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
k Bool -> Bool -> Bool
&& Double
k Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
1 = Double
1.0 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Double -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Double
2.0Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
k)) Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
k Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
1.0)
 | Bool
otherwise = Rational -> Double
forall a. Fractional a => Rational -> a
fromRational Rational
infinity
{-# INLINE minProportion #-}