module Numeric.Search.Integer (
search, searchFrom, searchTo,
search2) where
import Data.Maybe (fromMaybe)
search :: (Integer -> Bool) -> Integer
search :: (Integer -> Bool) -> Integer
search Integer -> Bool
p = Integer -> Maybe Integer -> Integer
forall a. a -> Maybe a -> a
fromMaybe ((Integer -> Bool) -> Integer -> Integer
searchFrom Integer -> Bool
p Integer
1) ((Integer -> Bool) -> Integer -> Maybe Integer
searchTo Integer -> Bool
p Integer
0)
searchFrom :: (Integer -> Bool) -> Integer -> Integer
searchFrom :: (Integer -> Bool) -> Integer -> Integer
searchFrom Integer -> Bool
p = Integer -> Integer -> Integer
search_from Integer
1
where search_from :: Integer -> Integer -> Integer
search_from Integer
step Integer
l
| Integer -> Bool
p Integer
l' = (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange Integer -> Bool
p Integer
l (Integer
l'Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
| Bool
otherwise = Integer -> Integer -> Integer
search_from (Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
step) (Integer
l'Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1)
where l' :: Integer
l' = Integer
l Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
step
searchTo :: (Integer -> Bool) -> Integer -> Maybe Integer
searchTo :: (Integer -> Bool) -> Integer -> Maybe Integer
searchTo Integer -> Bool
p Integer
h0
| Integer -> Bool
p Integer
h0 = Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Integer -> Integer
search_to Integer
1 Integer
h0)
| Bool
otherwise = Maybe Integer
forall a. Maybe a
Nothing
where search_to :: Integer -> Integer -> Integer
search_to Integer
step Integer
h
| Integer -> Bool
p Integer
h' = Integer -> Integer -> Integer
search_to (Integer
2Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
step) Integer
h'
| Bool
otherwise = (Integer -> Bool) -> Integer -> Integer -> Integer
searchSafeRange Integer -> Bool
p (Integer
h'Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) Integer
h
where h' :: Integer
h' = Integer
h Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
step
search2 :: (Integer -> Integer -> Bool) -> [(Integer,Integer)]
search2 :: (Integer -> Integer -> Bool) -> [(Integer, Integer)]
search2 Integer -> Integer -> Bool
p = (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p Integer
0 Integer
0 Integer
hx Integer
hy []
where
hx :: Integer
hx = (Integer -> Bool) -> Integer -> Integer
searchFrom (\ Integer
x -> Integer -> Integer -> Bool
p Integer
x Integer
0) Integer
0
hy :: Integer
hy = (Integer -> Bool) -> Integer -> Integer
searchFrom (\ Integer
y -> Integer -> Integer -> Bool
p Integer
0 Integer
y) Integer
0
search2Rect :: (Integer -> Integer -> Bool) ->
Integer -> Integer -> Integer -> Integer ->
[(Integer,Integer)] -> [(Integer,Integer)]
search2Rect :: (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p Integer
lx Integer
ly Integer
hx Integer
hy
| Integer
lx Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
hx Bool -> Bool -> Bool
|| Integer
ly Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
hy = [(Integer, Integer)] -> [(Integer, Integer)]
forall a. a -> a
id
| Integer
lx Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
hx Bool -> Bool -> Bool
&& Integer
ly Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
hy = if Integer -> Integer -> Bool
p Integer
lx Integer
ly then ((Integer
lx, Integer
ly) (Integer, Integer) -> [(Integer, Integer)] -> [(Integer, Integer)]
forall a. a -> [a] -> [a]
:) else [(Integer, Integer)] -> [(Integer, Integer)]
forall a. a -> a
id
| Integer
hxInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
lx Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
hyInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
ly =
let mx :: Integer
mx = (Integer
lxInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
hx) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
2
my :: Integer
my = (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange (\ Integer
y -> Integer -> Integer -> Bool
p Integer
mx Integer
y) Integer
ly Integer
hy
in (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p Integer
lx Integer
my Integer
mx Integer
hy ([(Integer, Integer)] -> [(Integer, Integer)])
-> ([(Integer, Integer)] -> [(Integer, Integer)])
-> [(Integer, Integer)]
-> [(Integer, Integer)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p (Integer
mxInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) Integer
ly Integer
hx (Integer
myInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
| Bool
otherwise =
let mx :: Integer
mx = (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange (\ Integer
x -> Integer -> Integer -> Bool
p Integer
x Integer
my) Integer
lx Integer
hx
my :: Integer
my = (Integer
lyInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
hy) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
2
in (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p Integer
lx (Integer
myInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) (Integer
mxInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1) Integer
hy ([(Integer, Integer)] -> [(Integer, Integer)])
-> ([(Integer, Integer)] -> [(Integer, Integer)])
-> [(Integer, Integer)]
-> [(Integer, Integer)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Bool)
-> Integer
-> Integer
-> Integer
-> Integer
-> [(Integer, Integer)]
-> [(Integer, Integer)]
search2Rect Integer -> Integer -> Bool
p Integer
mx Integer
ly Integer
hx Integer
my
searchIntegerRange :: (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange :: (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange Integer -> Bool
p Integer
l Integer
h
| Integer
h Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
l = Integer
hInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1
| Integer -> Bool
p Integer
m = (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange Integer -> Bool
p Integer
l (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
-Integer
1)
| Bool
otherwise = (Integer -> Bool) -> Integer -> Integer -> Integer
searchIntegerRange Integer -> Bool
p (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) Integer
h
where m :: Integer
m = (Integer
lInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
h) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
2
searchSafeRange :: (Integer -> Bool) -> Integer -> Integer -> Integer
searchSafeRange :: (Integer -> Bool) -> Integer -> Integer -> Integer
searchSafeRange Integer -> Bool
p Integer
l Integer
h
| Integer
l Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
h = Integer
l
| Integer -> Bool
p Integer
m = (Integer -> Bool) -> Integer -> Integer -> Integer
searchSafeRange Integer -> Bool
p Integer
l Integer
m
| Bool
otherwise = (Integer -> Bool) -> Integer -> Integer -> Integer
searchSafeRange Integer -> Bool
p (Integer
mInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
+Integer
1) Integer
h
where m :: Integer
m = (Integer
l Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
h) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
2