diff --git a/subsequence-repetition/SubsequenceRepetition.hs b/subsequence-repetition/SubsequenceRepetition.hs index 9f2424d..2e3f9ea 100644 --- a/subsequence-repetition/SubsequenceRepetition.hs +++ b/subsequence-repetition/SubsequenceRepetition.hs @@ -1,3 +1,4 @@ +-- | Module to find and print all repetitions of substrings in a given string. module Main where import Control.Monad (forM_) @@ -6,6 +7,7 @@ import Data.List (sortOn) import Data.Map qualified as Map import Data.Set qualified as Set +-- | Creates a sliding window of a given size over a list. slidingWindow :: Int -> [a] -> [[a]] slidingWindow size list | size > 0 && length list >= size = @@ -29,6 +31,7 @@ pairwiseComparison xs = [(x1, i, j) | (i, x1) <- ixs, (j, x2) <- ixs, x1 == x2, allPairwiseComparisons :: (Eq a) => [a] -> [[([a], Int, Int)]] allPairwiseComparisons xs = map (\n -> pairwiseComparison (slidingWindow n xs)) [0 .. length xs] +-- | Finds all repetitions of substrings of a given list. allRepetitions :: (Ord a) => [a] -> [Map.Map [a] (Set.Set Int)] allRepetitions xs = map (\n -> findRepetitions (slidingWindow n xs)) $ reverse [0 .. length xs] @@ -40,11 +43,15 @@ printAllRepetitions str substrRepetitions = do zipWith (const $ \x -> if x then '*' else ' ') str - [i `elem` concatMap (\x -> [x .. x + length key - 1]) (Set.toList value) | i <- [0 ..]] + (isInRange (length key) (Set.toList value)) putStrLn $ "\t" ++ show key where score (substring, occurrences) = negate $ length substring ^ 2 * Set.size occurrences + isInRange len indices = [i `elem` concatMap (\x -> [x .. x + len - 1]) indices | i <- [0 ..]] +-- | Prints a pairwise comparison of the substrings in a grid format. +-- The grid will have 'x' for matching pairs and '_' for non-matching pairs. +-- The first row and column will show the indices of the substrings. printPairwiseComparison :: [(Int, Int)] -> IO () printPairwiseComparison [] = return () printPairwiseComparison xys = @@ -64,6 +71,7 @@ printPairwiseComparison xys = putChar '\n' putChar '\n' +main :: IO () main = do let str = map toLower $ (" " ++) $ "nachts im dichten fichtendickicht da sind dicke fichten wichtig" printAllRepetitions str (allRepetitions str)