summaryrefslogtreecommitdiff
path: root/src/Data
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-02-01 03:21:52 -0500
committerjoe <joe@jerkface.net>2017-02-01 03:21:52 -0500
commitc51e64666b672637843a04c2f279d7d0c9eed01c (patch)
treed6f50018659ac3c5c3d72ee9bde3824514bd9f6a /src/Data
parent0d1de683de78a70ce9c054b444bb6f19c39d112c (diff)
New improved iterative search algorithm.
Diffstat (limited to 'src/Data')
-rw-r--r--src/Data/MinMaxPSQ.hs64
-rw-r--r--src/Data/Wrapper/PSQ.hs6
2 files changed, 69 insertions, 1 deletions
diff --git a/src/Data/MinMaxPSQ.hs b/src/Data/MinMaxPSQ.hs
new file mode 100644
index 00000000..96937604
--- /dev/null
+++ b/src/Data/MinMaxPSQ.hs
@@ -0,0 +1,64 @@
1{-# LANGUAGE BangPatterns #-}
2module Data.MinMaxPSQ where
3
4import Data.Ord
5import qualified Data.Wrapper.PSQ as PSQ
6 ;import Data.Wrapper.PSQ as PSQ hiding (insert, null, size)
7import Prelude hiding (null, take)
8
9data MinMaxPSQ k p = MinMaxPSQ !(PSQ k p) !(PSQ k (Down p))
10
11empty :: MinMaxPSQ k p
12empty = MinMaxPSQ PSQ.empty PSQ.empty
13
14null :: MinMaxPSQ k p -> Bool
15null (MinMaxPSQ nq xq) = PSQ.null nq
16
17size :: MinMaxPSQ k p -> Int
18size (MinMaxPSQ nq xq) = PSQ.size nq
19
20toList :: (Ord k, Ord p) => MinMaxPSQ k p -> [Binding k p]
21toList (MinMaxPSQ nq xq) = PSQ.toList nq
22
23fromList :: (Ord k, Ord p) => [Binding k p] -> MinMaxPSQ k p
24fromList kps = MinMaxPSQ (PSQ.fromList kps)
25 (PSQ.fromList $ map (\(k :-> p) -> (k :-> Down p)) kps)
26
27findMin :: (Ord k, Ord p) => MinMaxPSQ k p -> Maybe (Binding k p)
28findMin (MinMaxPSQ nq xq) = PSQ.findMin nq
29
30findMax :: (Ord k, Ord p) => MinMaxPSQ k p -> Maybe (Binding k p)
31findMax (MinMaxPSQ nq xq) = fmap (\(k :-> Down p) -> k :-> p) $ PSQ.findMin xq
32
33insert :: (Ord k, Ord p) => k -> p -> MinMaxPSQ k p -> MinMaxPSQ k p
34insert k p (MinMaxPSQ nq xq) = MinMaxPSQ (PSQ.insert k p nq)
35 (PSQ.insert k (Down p) xq)
36
37delete :: (Ord k, Ord p) => k -> MinMaxPSQ k p -> MinMaxPSQ k p
38delete k (MinMaxPSQ nq xq) = MinMaxPSQ (PSQ.delete k nq) (PSQ.delete k xq)
39
40deleteMin :: (Ord k, Ord p) => MinMaxPSQ k p -> MinMaxPSQ k p
41deleteMin (MinMaxPSQ nq xq) = case PSQ.minView nq of
42 Just (k :-> _, nq') -> MinMaxPSQ nq' (PSQ.delete k xq)
43 Nothing -> MinMaxPSQ nq xq
44
45deleteMax :: (Ord k, Ord p) => MinMaxPSQ k p -> MinMaxPSQ k p
46deleteMax (MinMaxPSQ nq xq) = case PSQ.minView xq of
47 Just (k :-> _, xq') -> MinMaxPSQ (PSQ.delete k nq) xq'
48 Nothing -> MinMaxPSQ nq xq
49
50minView :: (Ord k, Ord p) => MinMaxPSQ k p -> Maybe (Binding k p, MinMaxPSQ k p)
51minView (MinMaxPSQ nq xq) = fmap (\(k :-> p, nq') -> (k :-> p, MinMaxPSQ nq' (PSQ.delete k xq)))
52 $ PSQ.minView nq
53
54maxView :: (Ord k, Ord p) => MinMaxPSQ k p -> Maybe (Binding k p, MinMaxPSQ k p)
55maxView (MinMaxPSQ nq xq) = fmap (\(k :-> Down p, xq') -> (k :-> p, MinMaxPSQ (PSQ.delete k nq) xq'))
56 $ PSQ.minView xq
57
58insertTake :: (Ord k, Ord p) => Int -> k -> p -> MinMaxPSQ k p -> MinMaxPSQ k p
59insertTake n k p q = take n $ insert k p q
60
61take :: (Ord k, Ord p) => Int -> MinMaxPSQ k p -> MinMaxPSQ k p
62take !n !q | (size q <= n) = q
63 | null q = q
64 | otherwise = take n $ deleteMax q
diff --git a/src/Data/Wrapper/PSQ.hs b/src/Data/Wrapper/PSQ.hs
index e8fa2d98..2c08011b 100644
--- a/src/Data/Wrapper/PSQ.hs
+++ b/src/Data/Wrapper/PSQ.hs
@@ -15,10 +15,14 @@ type Binding k p = (k,p,())
15pattern (:->) :: k -> p -> Binding k p 15pattern (:->) :: k -> p -> Binding k p
16pattern k :-> p <- (k,p,()) where k :-> p = (k,p,()) 16pattern k :-> p <- (k,p,()) where k :-> p = (k,p,())
17 17
18key :: Binding k v -> k 18key :: Binding k p -> k
19key (k,p,v) = k 19key (k,p,v) = k
20{-# INLINE key #-} 20{-# INLINE key #-}
21 21
22prio :: Binding k p -> p
23prio (k,p,v) = p
24{-# INLINE prio #-}
25
22insert :: (Ord k, Ord p) => k -> p -> PSQ k p -> PSQ k p 26insert :: (Ord k, Ord p) => k -> p -> PSQ k p -> PSQ k p
23insert k p q = OrdPSQ.insert k p () q 27insert k p q = OrdPSQ.insert k p () q
24{-# INLINE insert #-} 28{-# INLINE insert #-}