-
Notifications
You must be signed in to change notification settings - Fork 0
/
hackerland_radio_transmitters.hs
70 lines (59 loc) · 2.35 KB
/
hackerland_radio_transmitters.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import qualified Data.Vector as V
import Debug.Trace
import Data.Maybe
import Data.List
indixate :: V.Vector Int -> V.Vector (Int, Int)
indixate xs = V.zip (V.fromList [0..(V.length xs)]) xs
lowerBound :: Int -> V.Vector (Int, Int) -> Maybe Int
lowerBound k xs = fst <$> (lowerBoundHelper k xs)
lowerBoundHelper :: Int -> V.Vector (Int, Int) -> Maybe (Int, Int)
lowerBoundHelper k xs
| V.length xs == 1 = if k < snd (V.head xs)
then Nothing
else Just (V.head xs)
| V.length xs == 0 = Nothing
| otherwise =
let (ls, rs) = V.splitAt (V.length xs `div` 2) xs
mid = V.head rs
in if (snd mid <= k)
then lowerBoundHelper k rs
else lowerBoundHelper k ls
strictUpperBound :: Int -> V.Vector (Int, Int) -> Maybe Int
strictUpperBound k xs =
fst <$> strictUpperBoundHelper k xs
strictUpperBoundHelper :: Int -> V.Vector (Int, Int) -> Maybe (Int, Int)
strictUpperBoundHelper k xs
| V.length xs == 1= if k >= (snd (V.head xs))
then Nothing
else Just $ V.head xs
| otherwise =
let (ls, rs) = V.splitAt (length xs `div` 2) xs
mid = snd $ V.head rs
in if mid <= k
then strictUpperBoundHelper k rs
else case strictUpperBoundHelper k ls of
Nothing -> strictUpperBoundHelper k rs
x -> x
coverLeft :: Int -> V.Vector (Int, Int) -> V.Vector (Int, Int)
coverLeft k xs = let
offset = fst $ V.head xs
transmitterIdx = fromJust $ lowerBound (snd (V.head xs) + k) xs
transmitter = snd (xs V.! (transmitterIdx - offset))
rightEdge = strictUpperBound (transmitter + k) xs
in case rightEdge of
Just re -> snd (V.splitAt (re - offset) xs)
Nothing -> V.fromList []
solve :: Int -> [Int] -> Int
solve k xs =
let nxs = indixate (V.fromList $ sort xs)
covers = V.unfoldr (\rs ->
let nxt = coverLeft k rs
in if V.length nxt == 0
then Nothing
else Just (nxt, nxt)
) nxs
in 1 + V.length covers
main = do
n : k : [] <- map read <$> words <$> getLine
xs <- take n <$> map read <$> words <$> getLine :: IO [Int]
putStrLn $ show $ solve k xs