module Combinatorics.Battleship.Count.Estimate (
overlapping,
occupying,
) where
import qualified Combinatorics.Battleship.Fleet as Fleet
import qualified Data.NonEmpty as NonEmpty
overlapping :: (Int,Int) -> Fleet.T -> Integer
overlapping (width,height) =
product .
map
(\(size,count) ->
(fromIntegral height * fromIntegral (max 0 (widthsize+1)) +
fromIntegral width * fromIntegral (max 0 (heightsize+1)))
^ count) .
Fleet.toList
occupying :: (Int,Int) -> Fleet.T -> Integer
occupying (width,height) fleet =
let sizes = reverse $ Fleet.toSizes fleet
in product $ map toInteger $
zipWith (flip $ maxPositionsInArea (width+1,height+1)) sizes $
scanl () ((width+1)*(height+1)) $
map (\size -> 2*(fromIntegral size + 1)) sizes
maxPositionsInArea :: (Int,Int) -> Int -> Int -> Int
maxPositionsInArea (maxWidth,maxHeight) area size =
NonEmpty.maximum $ NonEmpty.cons 0 $
concatMap
(\(width,height) -> [(widthsize)*(height1), (width1)*(heightsize)]) $
filter
(\(width,height) ->
width<=maxWidth && height<=maxHeight
||
height<=maxWidth && width<=maxHeight) $
rectangles area
rectangles :: Int -> [(Int,Int)]
rectangles area =
takeWhile (uncurry (<=)) $ map (\a -> (a, divUp area a)) [2..]
divUp :: (Integral a) => a -> a -> a
divUp n m = div (n) m