{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Constrained.SumList where
import Data.Either (partitionEithers)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NE
import Data.Semigroup (sconcat)
import System.Random (Random (..))
import Test.QuickCheck (Gen, choose, shuffle, vectorOf)
data Solution t = Yes (NonEmpty [t]) | No [String]
deriving (Solution t -> Solution t -> Bool
forall t. Eq t => Solution t -> Solution t -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Solution t -> Solution t -> Bool
$c/= :: forall t. Eq t => Solution t -> Solution t -> Bool
== :: Solution t -> Solution t -> Bool
$c== :: forall t. Eq t => Solution t -> Solution t -> Bool
Eq)
instance Show t => Show (Solution t) where
show :: Solution t -> String
show (No [String]
xs) = String
"No" forall a. [a] -> [a] -> [a]
++ String
"\n" forall a. [a] -> [a] -> [a]
++ [String] -> String
unlines [String]
xs
show (Yes NonEmpty [t]
xs) = String
"Yes " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show NonEmpty [t]
xs
concatSolution :: Show t => t -> String -> t -> Int -> [Solution t] -> Solution t
concatSolution :: forall t.
Show t =>
t -> String -> t -> Int -> [Solution t] -> Solution t
concatSolution t
smallest String
pName t
total Int
count [Solution t]
sols =
case forall a b. [Either a b] -> ([a], [b])
partitionEithers (forall a b. (a -> b) -> [a] -> [b]
map (\case Yes NonEmpty [t]
x -> forall a b. a -> Either a b
Left NonEmpty [t]
x; No [String]
x -> forall a b. b -> Either a b
Right [String]
x) [Solution t]
sols) of
([], [String]
n : [[String]]
_) -> forall t. [String] -> Solution t
No [String]
n
(NonEmpty [t]
y : [NonEmpty [t]]
ys, [[String]]
_) -> forall t. NonEmpty [t] -> Solution t
Yes forall a b. (a -> b) -> a -> b
$ forall a. Semigroup a => NonEmpty a -> a
sconcat (NonEmpty [t]
y forall a. a -> [a] -> NonEmpty a
:| [NonEmpty [t]]
ys)
([], []) ->
forall t. [String] -> Solution t
No
[ String
"The sample in pickAll was empty"
, String
"smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
"pred = " forall a. [a] -> [a] -> [a]
++ String
pName
, String
"total = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total
, String
"count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
count
]
newtype Cost = Cost Int deriving (Cost -> Cost -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Cost -> Cost -> Bool
$c/= :: Cost -> Cost -> Bool
== :: Cost -> Cost -> Bool
$c== :: Cost -> Cost -> Bool
Eq, Int -> Cost -> ShowS
[Cost] -> ShowS
Cost -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Cost] -> ShowS
$cshowList :: [Cost] -> ShowS
show :: Cost -> String
$cshow :: Cost -> String
showsPrec :: Int -> Cost -> ShowS
$cshowsPrec :: Int -> Cost -> ShowS
Show, Integer -> Cost
Cost -> Cost
Cost -> Cost -> Cost
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> Cost
$cfromInteger :: Integer -> Cost
signum :: Cost -> Cost
$csignum :: Cost -> Cost
abs :: Cost -> Cost
$cabs :: Cost -> Cost
negate :: Cost -> Cost
$cnegate :: Cost -> Cost
* :: Cost -> Cost -> Cost
$c* :: Cost -> Cost -> Cost
- :: Cost -> Cost -> Cost
$c- :: Cost -> Cost -> Cost
+ :: Cost -> Cost -> Cost
$c+ :: Cost -> Cost -> Cost
Num, Eq Cost
Cost -> Cost -> Bool
Cost -> Cost -> Ordering
Cost -> Cost -> Cost
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Cost -> Cost -> Cost
$cmin :: Cost -> Cost -> Cost
max :: Cost -> Cost -> Cost
$cmax :: Cost -> Cost -> Cost
>= :: Cost -> Cost -> Bool
$c>= :: Cost -> Cost -> Bool
> :: Cost -> Cost -> Bool
$c> :: Cost -> Cost -> Bool
<= :: Cost -> Cost -> Bool
$c<= :: Cost -> Cost -> Bool
< :: Cost -> Cost -> Bool
$c< :: Cost -> Cost -> Bool
compare :: Cost -> Cost -> Ordering
$ccompare :: Cost -> Cost -> Ordering
Ord)
firstYesG ::
Monad m => Solution t -> (x -> Cost -> m (Cost, Solution t)) -> [x] -> Cost -> m (Cost, Solution t)
firstYesG :: forall (m :: * -> *) t x.
Monad m =>
Solution t
-> (x -> Cost -> m (Cost, Solution t))
-> [x]
-> Cost
-> m (Cost, Solution t)
firstYesG Solution t
nullSolution x -> Cost -> m (Cost, Solution t)
f [x]
xs Cost
c = [x] -> Cost -> m (Cost, Solution t)
go [x]
xs Cost
c
where
go :: [x] -> Cost -> m (Cost, Solution t)
go [] Cost
cost = forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cost
cost, Solution t
nullSolution)
go [x
x] Cost
cost = x -> Cost -> m (Cost, Solution t)
f x
x (Cost
cost forall a. Num a => a -> a -> a
+ Cost
1)
go (x
x : [x]
more) Cost
cost = do
(Cost, Solution t)
ans <- x -> Cost -> m (Cost, Solution t)
f x
x (Cost
cost forall a. Num a => a -> a -> a
+ Cost
1)
case (Cost, Solution t)
ans of
(Cost
cost1, No [String]
_) -> [x] -> Cost -> m (Cost, Solution t)
go [x]
more Cost
cost1
(Cost, Solution t)
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cost, Solution t)
ans
noChoices :: Show t => Cost -> String -> t -> t -> t -> Int -> [(t, t)] -> Solution t
noChoices :: forall t.
Show t =>
Cost -> String -> t -> t -> t -> Int -> [(t, t)] -> Solution t
noChoices Cost
cost String
p t
smallest t
largest t
total Int
count [(t, t)]
samp =
forall t. [String] -> Solution t
No
[ String
"No legal choice can be found, where"
, String
" predicate = " forall a. [a] -> [a] -> [a]
++ String
p
, String
" smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
" largest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
largest
, String
" total = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total
, String
" count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
count
, String
" cost = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Cost
cost
, String
"Small sample of what was explored"
, forall a. Show a => a -> String
show [(t, t)]
samp
]
splitsOf :: Integral b => b -> [(b, b)]
splitsOf :: forall b. Integral b => b -> [(b, b)]
splitsOf b
count = [(b
i, b
j) | b
i <- [b
1 .. forall a. Integral a => a -> a -> a
div b
count b
2], let j :: b
j = b
count forall a. Num a => a -> a -> a
- b
i]
{-# SPECIALIZE splitsOf :: Int -> [(Int, Int)] #-}
pickAll ::
forall t.
(Show t, Integral t, Random t) =>
t -> t -> (String, t -> Bool) -> t -> Int -> Cost -> Gen (Cost, Solution t)
pickAll :: forall t.
(Show t, Integral t, Random t) =>
t
-> t
-> (String, t -> Bool)
-> t
-> Int
-> Cost
-> Gen (Cost, Solution t)
pickAll t
smallest t
largest (String
pName, t -> Bool
_) t
total Int
count Cost
cost
| Cost
cost forall a. Ord a => a -> a -> Bool
> Cost
1000 =
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
( Cost
cost
, forall t. [String] -> Solution t
No
[ String
"pickAll exceeds cost limit " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Cost
cost
, String
" predicate = " forall a. [a] -> [a] -> [a]
++ String
pName
, String
" smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
" largest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
largest
, String
" total = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total
, String
" count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
count
]
)
pickAll t
smallest t
largest (String
pName, t -> Bool
p) t
total Int
1 Cost
cost =
if t -> Bool
p t
total
then forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cost
cost, forall t. NonEmpty [t] -> Solution t
Yes forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure [t
total])
else forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cost
cost, forall t.
Show t =>
Cost -> String -> t -> t -> t -> Int -> [(t, t)] -> Solution t
noChoices Cost
cost String
pName t
smallest t
largest t
total Int
1 [(t
total, t
0)])
pickAll t
smallest t
largest (String
pName, t -> Bool
_) t
total Int
count Cost
cost
| t
smallest forall a. Ord a => a -> a -> Bool
> t
largest =
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
( Cost
cost
, forall t. [String] -> Solution t
No
[ String
"The feasible range to pickAll [" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest forall a. [a] -> [a] -> [a]
++ String
" .. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Integral a => a -> a -> a
div t
total t
2) forall a. [a] -> [a] -> [a]
++ String
"] was empty"
, String
" predicate = " forall a. [a] -> [a] -> [a]
++ String
pName
, String
" smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
" largest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
largest
, String
" total = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total
, String
" count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
count
, String
" cost = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Cost
cost
]
)
pickAll t
smallest t
largest (String
pName, t -> Bool
p) t
total Int
2 Cost
cost = do
[(t, t)]
choices <- forall t.
(Random t, Integral t) =>
t -> t -> t -> t -> Int -> Gen [(t, t)]
smallSample t
smallest t
largest t
total t
1000 Int
100
case forall a. (a -> Bool) -> [a] -> [a]
filter (\(t
x, t
y) -> t -> Bool
p t
x Bool -> Bool -> Bool
&& t -> Bool
p t
y) [(t, t)]
choices of
[] -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (Cost
cost forall a. Num a => a -> a -> a
+ Cost
1, forall t.
Show t =>
Cost -> String -> t -> t -> t -> Int -> [(t, t)] -> Solution t
noChoices Cost
cost String
pName t
smallest t
largest t
total Int
2 (forall a. Int -> [a] -> [a]
take Int
10 [(t, t)]
choices))
[(t, t)]
zs -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (Cost
cost forall a. Num a => a -> a -> a
+ Cost
1, forall t. NonEmpty [t] -> Solution t
Yes forall a b. (a -> b) -> a -> b
$ forall a. [a] -> NonEmpty a
NE.fromList (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(t
x, t
y) -> [t
x, t
y]) [(t, t)]
zs))
pickAll t
smallest t
largest (String
pName, t -> Bool
p) t
total Int
count Cost
cost = do
[(t, t)]
choices <- forall t.
(Random t, Integral t) =>
t -> t -> t -> t -> Int -> Gen [(t, t)]
smallSample t
smallest t
largest t
total t
1000 Int
20
[(Int, Int)]
splits <-
if Int
count forall a. Ord a => a -> a -> Bool
>= Int
20
then forall a. [a] -> Gen [a]
shuffle forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take Int
10 (forall b. Integral b => b -> [(b, b)]
splitsOf Int
count)
else
if t
total forall a. Ord a => a -> a -> Bool
> forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
count
then forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. [a] -> [a]
reverse (forall b. Integral b => b -> [(b, b)]
splitsOf Int
count))
else forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall b. Integral b => b -> [(b, b)]
splitsOf Int
count)
forall (m :: * -> *) t x.
Monad m =>
Solution t
-> (x -> Cost -> m (Cost, Solution t))
-> [x]
-> Cost
-> m (Cost, Solution t)
firstYesG
(forall t. [String] -> Solution t
No [String
"No split has a solution", String
"cost = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Cost
cost])
(forall t.
(Random t, Show t, Integral t) =>
t
-> t
-> (String, t -> Bool)
-> t
-> [(t, t)]
-> (Int, Int)
-> Cost
-> Gen (Cost, Solution t)
doSplit t
smallest t
largest (String
pName, t -> Bool
p) t
total [(t, t)]
choices)
[(Int, Int)]
splits
Cost
cost
doSplit ::
(Random t, Show t, Integral t) =>
t ->
t ->
(String, t -> Bool) ->
t ->
[(t, t)] ->
(Int, Int) ->
Cost ->
Gen (Cost, Solution t)
doSplit :: forall t.
(Random t, Show t, Integral t) =>
t
-> t
-> (String, t -> Bool)
-> t
-> [(t, t)]
-> (Int, Int)
-> Cost
-> Gen (Cost, Solution t)
doSplit t
smallest t
largest (String
pName, t -> Bool
p) t
total [(t, t)]
sample (Int
i, Int
j) Cost
c = [(t, t)] -> Cost -> Gen (Cost, Solution t)
go [(t, t)]
sample Cost
c
where
go :: [(t, t)] -> Cost -> Gen (Cost, Solution t)
go ((t
x, t
y) : [(t, t)]
more) Cost
cost0 = do
(Cost
cost1, Solution t
ans1) <- forall t.
(Show t, Integral t, Random t) =>
t
-> t
-> (String, t -> Bool)
-> t
-> Int
-> Cost
-> Gen (Cost, Solution t)
pickAll t
smallest t
largest (String
pName, t -> Bool
p) t
x Int
i Cost
cost0
(Cost
cost2, Solution t
ans2) <- forall t.
(Show t, Integral t, Random t) =>
t
-> t
-> (String, t -> Bool)
-> t
-> Int
-> Cost
-> Gen (Cost, Solution t)
pickAll t
smallest t
largest (String
pName, t -> Bool
p) t
y Int
j Cost
cost1
case (Solution t
ans1, Solution t
ans2) of
(Yes NonEmpty [t]
ys, Yes NonEmpty [t]
zs) -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (Cost
cost2, forall t. NonEmpty [t] -> Solution t
Yes (forall a. [a] -> NonEmpty a
NE.fromList [[t]
a forall a. Semigroup a => a -> a -> a
<> [t]
b | [t]
a <- forall a. NonEmpty a -> [a]
NE.toList NonEmpty [t]
ys, [t]
b <- forall a. NonEmpty a -> [a]
NE.toList NonEmpty [t]
zs]))
(Solution t, Solution t)
_ -> [(t, t)] -> Cost -> Gen (Cost, Solution t)
go [(t, t)]
more Cost
cost2
go [] Cost
cost =
case [(t, t)]
sample of
[] ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
( Cost
cost
, forall t. [String] -> Solution t
No
[ String
"The sample passed to doSplit [" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest forall a. [a] -> [a] -> [a]
++ String
" .. " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Integral a => a -> a -> a
div t
total t
2) forall a. [a] -> [a] -> [a]
++ String
"] was empty"
, String
" predicate = " forall a. [a] -> [a] -> [a]
++ String
pName
, String
" smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
" total " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total
, String
" count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
i forall a. Num a => a -> a -> a
+ Int
j)
, String
" split of count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
i, Int
j)
]
)
((t
left, t
right) : [(t, t)]
_) ->
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
( Cost
cost
, forall t. [String] -> Solution t
No
[ String
"All choices in (genSizedList " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
i forall a. Num a => a -> a -> a
+ Int
j) forall a. [a] -> [a] -> [a]
++ String
" 'p' " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total forall a. [a] -> [a] -> [a]
++ String
") have failed."
, String
"Here is 1 example failure."
, String
" smallest = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
smallest
, String
" total " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
total forall a. [a] -> [a] -> [a]
++ String
" = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
left forall a. [a] -> [a] -> [a]
++ String
" + " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
right
, String
" count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
i forall a. Num a => a -> a -> a
+ Int
j) forall a. [a] -> [a] -> [a]
++ String
", split of count = " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Int
i, Int
j)
, String
"We are trying to solve sub-problems like:"
, String
" split " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
left forall a. [a] -> [a] -> [a]
++ String
" into " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i forall a. [a] -> [a] -> [a]
++ String
" parts, where all parts meet 'p'"
, String
" split " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show t
right forall a. [a] -> [a] -> [a]
++ String
" into " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
j forall a. [a] -> [a] -> [a]
++ String
" parts, where all parts meet 'p'"
, String
"predicate 'p' = " forall a. [a] -> [a] -> [a]
++ String
pName
, String
"prefix of the sample"
, [String] -> String
unlines (forall a b. (a -> b) -> [a] -> [b]
map forall a. Show a => a -> String
show (forall a. Int -> [a] -> [a]
take Int
10 [(t, t)]
sample))
]
)
{-# INLINE doSplit #-}
smallSample :: (Random t, Integral t) => t -> t -> t -> t -> Int -> Gen [(t, t)]
smallSample :: forall t.
(Random t, Integral t) =>
t -> t -> t -> t -> Int -> Gen [(t, t)]
smallSample t
smallest t
largest t
total t
bound Int
size
| t
largest forall a. Num a => a -> a -> a
- t
smallest forall a. Ord a => a -> a -> Bool
<= t
bound = do
forall a. [a] -> Gen [a]
shuffle forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
takeWhile (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Ord a => a -> a -> Bool
(<=)) [(t
x, t
total forall a. Num a => a -> a -> a
- t
x) | t
x <- [t
smallest .. t
total]]
| Bool
otherwise = do
[t]
choices <- forall a.
(Random a, Integral a) =>
a -> a -> Int -> Int -> Bool -> Gen [a]
fair t
smallest t
largest Int
size Int
5 Bool
True
forall a. [a] -> Gen [a]
shuffle [(t
x, t
total forall a. Num a => a -> a -> a
- t
x) | t
x <- [t]
choices]
{-# INLINE smallSample #-}
fair :: (Random a, Integral a) => a -> a -> Int -> Int -> Bool -> Gen [a]
fair :: forall a.
(Random a, Integral a) =>
a -> a -> Int -> Int -> Bool -> Gen [a]
fair a
smallest a
largest Int
size Int
precision Bool
isLarge =
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {a}. Random a => (a, a) -> Gen [a]
oneRange (if Bool
isLarge then [(a, a)]
largePrecision else [(a, a)]
smallPrecision)
where
raw :: [(a, a)]
raw = forall a b. (a -> b) -> [a] -> [b]
map forall a. Integral a => a -> (a, a)
logRange [forall t. Integral t => t -> t
logish a
smallest .. forall t. Integral t => t -> t
logish a
largest]
fixEnds :: (a, a) -> (a, a)
fixEnds (a
x, a
y) = (forall a. Ord a => a -> a -> a
max a
smallest a
x, forall a. Ord a => a -> a -> a
min a
largest a
y)
ranges :: [(a, a)]
ranges = forall a b. (a -> b) -> [a] -> [b]
map (a, a) -> (a, a)
fixEnds [(a, a)]
raw
count :: Int
count = forall a. Integral a => a -> a -> a
div Int
size Int
precision
largePrecision :: [(a, a)]
largePrecision = forall a. Int -> [a] -> [a]
take Int
precision (forall a. [a] -> [a]
reverse [(a, a)]
ranges)
smallPrecision :: [(a, a)]
smallPrecision = forall a. Int -> [a] -> [a]
take Int
precision [(a, a)]
ranges
oneRange :: (a, a) -> Gen [a]
oneRange (a
x, a
y) = forall a. Int -> Gen a -> Gen [a]
vectorOf Int
count (forall a. Random a => (a, a) -> Gen a
choose (a
x, a
y))
logRange :: Integral a => a -> (a, a)
logRange :: forall a. Integral a => a -> (a, a)
logRange a
1 = (a
10, a
99)
logRange (-1) = (-a
9, -a
1)
logRange a
n = case forall a. Ord a => a -> a -> Ordering
compare a
n a
0 of
Ordering
EQ -> (a
0, a
9)
Ordering
LT -> (forall a. Num a => a -> a
negate (forall a. Integral a => a -> a -> a
div a
b a
10), forall a. Num a => a -> a
negate (forall a. Integral a => a -> a -> a
div a
a a
10))
Ordering
GT -> (a
10 forall a b. (Num a, Integral b) => a -> b -> a
^ a
n, a
10 forall a b. (Num a, Integral b) => a -> b -> a
^ (a
n forall a. Num a => a -> a -> a
+ a
1) forall a. Num a => a -> a -> a
- a
1)
where
(a
a, a
b) = forall a. Integral a => a -> (a, a)
logRange (forall a. Num a => a -> a
negate a
n)
logish :: Integral t => t -> t
logish :: forall t. Integral t => t -> t
logish t
n
| t
0 forall a. Ord a => a -> a -> Bool
<= t
n Bool -> Bool -> Bool
&& t
n forall a. Ord a => a -> a -> Bool
<= t
9 = t
0
| t
n forall a. Ord a => a -> a -> Bool
> t
9 = t
1 forall a. Num a => a -> a -> a
+ forall t. Integral t => t -> t
logish (t
n forall a. Integral a => a -> a -> a
`div` t
10)
| (-t
9) forall a. Ord a => a -> a -> Bool
<= t
n Bool -> Bool -> Bool
&& t
n forall a. Ord a => a -> a -> Bool
<= (-t
1) = -t
1
| Bool
True = forall a. Num a => a -> a
negate (t
1 forall a. Num a => a -> a -> a
+ forall t. Integral t => t -> t
logish (forall a. Num a => a -> a
negate t
n))