summaryrefslogtreecommitdiff
path: root/2019/SmallIntSet.hs
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2019-12-20 11:46:45 +0100
committertomsmeding <tom.smeding@gmail.com>2019-12-20 12:02:44 +0100
commit94ddb362ced51bd750cc01532ba50139e0abe739 (patch)
tree604cd66491549fe9f97f5e8d265ad6f13ee005b2 /2019/SmallIntSet.hs
parentd0576f00602278449f53ebd9d05d44692c594a84 (diff)
Day 18 part 1
Diffstat (limited to '2019/SmallIntSet.hs')
-rw-r--r--2019/SmallIntSet.hs54
1 files changed, 54 insertions, 0 deletions
diff --git a/2019/SmallIntSet.hs b/2019/SmallIntSet.hs
new file mode 100644
index 0000000..182b850
--- /dev/null
+++ b/2019/SmallIntSet.hs
@@ -0,0 +1,54 @@
+module SmallIntSet (
+ SmallIntSet,
+ toList, fromList, size, empty, singleton, insert, member, notMember, union, (\\)
+) where
+
+import Data.Bits
+import Data.List (intercalate)
+
+
+nBits :: Int
+nBits = finiteBitSize (undefined :: Int)
+
+newtype SmallIntSet = SmallIntSet Int
+ deriving (Eq, Ord)
+
+instance Show SmallIntSet where
+ show set = "{" ++ intercalate "," (map show (toList set)) ++ "}"
+
+instance Semigroup SmallIntSet where
+ s1 <> s2 = union s1 s2
+
+toList :: SmallIntSet -> [Int]
+toList (SmallIntSet bm) = [n | n <- [0..nBits-1], testBit bm n]
+
+fromList :: [Int] -> SmallIntSet
+fromList = foldr insert empty
+
+size :: SmallIntSet -> Int
+size (SmallIntSet bm) = popCount bm
+
+empty :: SmallIntSet
+empty = SmallIntSet 0
+
+singleton :: Int -> SmallIntSet
+singleton n = checkValid n `seq` SmallIntSet (1 `shiftL` n)
+
+insert :: Int -> SmallIntSet -> SmallIntSet
+insert n (SmallIntSet bm) = checkValid n `seq` SmallIntSet (bm .|. (1 `shiftL` n))
+
+member :: Int -> SmallIntSet -> Bool
+member n (SmallIntSet bm) = checkValid n `seq` (bm .&. (1 `shiftL` n)) /= 0
+
+notMember :: Int -> SmallIntSet -> Bool
+notMember n (SmallIntSet bm) = checkValid n `seq` (bm .&. (1 `shiftL` n)) == 0
+
+union :: SmallIntSet -> SmallIntSet -> SmallIntSet
+union (SmallIntSet b1) (SmallIntSet b2) = SmallIntSet (b1 .|. b2)
+
+(\\) :: SmallIntSet -> SmallIntSet -> SmallIntSet
+SmallIntSet b1 \\ SmallIntSet b2 = SmallIntSet (b1 .&. complement b2)
+
+checkValid :: Int -> Bool
+checkValid n | 0 <= n, n < nBits = True
+ | otherwise = error $ "SmallIntSet bounds violated with " ++ show n