module Helpers.BraxtonHelper (allSequences, SymmetricRelation(..), ReflexiveRelation(..)) where data SymmetricRelation = Symmetric | NonSymmetric deriving (Eq) data ReflexiveRelation = Reflexive | NonReflexive deriving (Eq) allSequences :: ReflexiveRelation -> SymmetricRelation -> Int -> Int -> [[Int]] allSequences reflexivity symmetry upperBound maxLength = f [[]] maxLength where f knownSequences 0 = knownSequences f knownSequences stepCount = f newSequences (stepCount - 1) where newSequences = concatMap (childSequences reflexivity symmetry upperBound) knownSequences childSequences :: ReflexiveRelation -> SymmetricRelation -> Int -> [Int] -> [[Int]] childSequences reflexivity symmetry upperBound as = map (:as) validTerms where validTerms = filter (isValidExtension reflexivity symmetry as) [1..upperBound] isValidExtension :: ReflexiveRelation -> SymmetricRelation -> [Int] -> Int -> Bool isValidExtension _ _ [] _ = True isValidExtension reflexivity symmetry as@(a:t) c = checkSymmetric && checkReflexive where checkSymmetric = (symmetry == NonSymmetric) || a /= c checkReflexive = (all meetsSymmetricCondition $ zip as t) where meetsSymmetricCondition pair = pair /= (c, a) && (reflexivity == NonReflexive || pair /= (a, c)) a282193 :: Int -> Integer a282193 n = minimum $ map product theSequences where theSequences = map (map fromIntegral) $ allSequences Reflexive NonSymmetric n n