import Data.Set (Set) import qualified Data.Set as Set makesMaximalTable :: (Integer -> Integer -> Integer) -> Integer -> Set Integer -> Set Integer -> Bool makesMaximalTable f n principalValues table = sizeMatches && Set.disjoint newRow table where newRow = proposedRow f n principalValues sizeMatches = Set.size newRow - 1 == Set.size principalValues proposedRow :: (Integer -> Integer -> Integer) -> Integer -> Set Integer -> Set Integer proposedRow f n principalValues = Set.insert (f n n) $ Set.map (f n) principalValues inA337946 n principalValues table = isAdd && isMult && isDisjoint where isAdd = makesMaximalTable (+) n principalValues table isMult = makesMaximalTable (*) n principalValues table isDisjoint = Set.disjoint addRow multRow where addRow = proposedRow (+) n principalValues multRow = proposedRow (*) n principalValues a33794x_lists = (1,Set.fromList [1, 2]) : recurse 1 (Set.fromList [1, 2]) where recurse n table = (nextValue, table') : recurse (n + 1) table' where nextValue = head $ filter (\i -> inA337946 i l table) [Set.findMax l + 1..] table' = foldr1 Set.union [table, Set.map (*nextValue) l, Set.map (+nextValue) l, Set.fromList [2*nextValue, nextValue^2]] l = Set.fromList $ take n a337946_list a337947_list = concatMap Set.toAscList $ recurse 0 a33794x_lists where recurse x ((an, nSet):remaining) = Set.difference (Set.fromList [x+1..an-1]) nSet : recurse an remaining a337946_list = map fst a33794x_lists