module Main (main) where
import Data.Bits
import Data.Word
import Data.List
import qualified Data.IntSet as S
import System.IO
import Control.Monad
import Control.Concurrent
import Control.Exception.Base (evaluate)
pairs' :: Int -> Word64 -> Int
pairs' n s = fromIntegral $ foldl' (.|.) 0 $ map mk [1..n]
where mk d = let mask = 1 `shiftL` d - 1
pc = popCount $! xor (s `shiftR` (n - d)) (s .&. mask)
in if pc <= 1
then mask + 1
else 0
mkSet :: Int -> Word64 -> Word64 -> S.IntSet
mkSet n a b = S.fromList $ map (pairs' n) [a .. b]
f :: Int -> IO Int
f n
| n < 4 = return $ S.size $ mkSet n 0 mxbound
| otherwise = do
mvs <- replicateM 4 newEmptyMVar
forM_ (zip mvs cpairs) $ \(mv,(mi,ma)) -> forkIO $ do
evaluate (mkSet n mi ma) >>= putMVar mv
set <- foldl' S.union S.empty <$> mapM readMVar mvs
return $! S.size set
where
mxbound = 1 `shiftL` (n - 1)
bounds = [0,1 `shiftL` (n - 3) .. mxbound]
cpairs = zip bounds (drop 1 bounds)
main :: IO()
main = do
hSetBuffering stdout LineBuffering
mapM_ (f >=> print) [1..]
module Main (main) where
import Data.Bits
import Data.Word
import Data.List
import qualified Data.IntSet as S
import System.IO
import Control.Monad
import Control.Concurrent
import Control.Exception.Base (evaluate)
pairs' :: Int -> Word64 -> Int
pairs' n s = fromIntegral $ foldl' (.|.) 0 $ map mk [1..n]
where mk d = let mask = 1 `shiftL` d - 1
pc = popCount $! xor (s `shiftR` (n - d)) (s .&. mask)
in if pc <= 1
then mask + 1
else 0
mkSet :: Int -> Word64 -> Word64 -> S.IntSet
mkSet n a b = S.fromList $ map (pairs' n) [a .. b]
f :: Int -> IO Int
f n
| n < 4 = return $ S.size $ mkSet n 0 mxbound
| otherwise = do
mvs <- replicateM 4 newEmptyMVar
forM_ (zip mvs cpairs) $ \(mv,(mi,ma)) -> forkIO $ do
evaluate (mkSet n mi ma) >>= putMVar mv
set <- foldl' S.union S.empty <$> mapM readMVar mvs
return $! S.size set
where
mxbound = 1 `shiftL` (n - 1)
bounds = [0,1 `shiftL` (n - 3) .. mxbound]
cpairs = zip bounds (drop 1 bounds)
main :: IO()
main = do
hSetBuffering stdout LineBuffering
mapM_ (f >=> print) [1..]