-- Jonathan Frech, 23rd and 26th of November 2019
mappings :: Eq a => [a] -> [b] -> [a -> b]
mappings [] _ = [undefined]
mappings (x:xs) ys = [\z -> if z == x then y else f z
| y <- ys, f <- mappings xs ys]
operations :: Eq a => [a] -> [b] -> [a -> a -> b]
operations xs = mappings xs . mappings xs
isCommutative :: Eq b => [a] -> (a -> a -> b) -> Bool
isCommutative xs (!) = and [x ! x' == x' ! x | x <- xs, x' <- xs]
isAssociative :: Eq a => [a] -> (a -> a -> a) -> Bool
isAssociative xs (!) = and [x ! (x' ! x'') == (x ! x') ! x''
| x <- xs, x' <- xs, x'' <- xs]
a079195 n = let ns = [0..n-1] in length . filter (not . isAssociative ns)
. filter (isCommutative ns) $ operations ns ns
a079198 n = let ns = [0..n-1] in length . filter (isAssociative ns)
. filter (not . isCommutative ns) $ operations ns ns
b079195 = take 4 $ a079195 <$> [0..]
b079198 = take 4 $ a079198 <$> [0..]