Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show a list of words repeated in haskell

I need to be able to write a function that shows repeated words from a string and return a list of strings in order of its occurrence and ignore non-letters

e.g at hugs prompt

repetitions :: String -> [String]

repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name  name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]
like image 508
SeanHill Avatar asked Dec 23 '22 13:12

SeanHill


2 Answers

To split a string into words, use the words function (in the Prelude). To eliminate non-word characters, filter with Data.Char.isAlphaNum. Zip the list together with its tail to get adjacent pairs (x, y). Fold the list, consing a new list that contains all x where x == y.

Someting like:

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
  where l = map (filter isAlphaNum) (words s)

I'm not sure that works, but it should give you a rough idea.

like image 123
Apocalisp Avatar answered Dec 25 '22 01:12

Apocalisp


I am new to this language so my solution could be a kind of ugly in the eyes of an Haskell veteran, but anyway:

let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') x)))))

This part will remove all non letters and non spaces from a string s:

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') s

This one will split a string s to words and group the same words to lists returning list of lists:

List.group (words s)

When this part will remove all lists with less than two elements:

filter (\x -> (length x) > 1) s

After what we will concatenate all lists to one removing one element from them though

concat (map tail s)
like image 28
Alexander Prokofyev Avatar answered Dec 25 '22 02:12

Alexander Prokofyev