0
votes

In Haskell I have this main function:

combinations pre suf letters = prefixed ++ suffixed
  where
    perms = permutation letters
    prefixed = map (\x -> pre ++ x)  $ perms
    suffixed = map (\x -> x ++ suf)  $ perms

main = do
        ls1 <- fmap lines (readFile "dictionary.txt")
        let ls2 = combinations "Apple" "Citrus" "Banana"

How can I combine ls1 and ls2 and print out the double ones? The double ones has to be non case sensitive. So if I have Banana and banana it have to print 1 of the ones.

Edit:

ls1 is a list of lines from dictionary.txt

ls2 is a list of different combinations from an other function called combinations

I want to combine/merge/concat ls1 and ls2. To a list like ls3. This list will have all lines from dictionary.txt and alle combinations from ls2 and the combinations function.

Then it must print alle the double elements in ls3 as output.

Edit 2:

The structure of dictionary.txt (Just a random list with a lot of words in it. ) is like:

Apple
Strawberry
Clown
.....

The combinations function (see edit in my code): Makes from a input like:

combinations "a" "b" "ded"

Output:

["acd","adc","cdb","dcb"]

Background: Application is for a game like scrabble: "pre" and "suf" are the characters on the board. And "letters" are the letters of the player.

Example values:

ls1

["Apple","Strawberry","Clown".....]

ls2

["Clwno","Clonw","Clown"..]

ls3

["Apple","Strawberry","Clown","Clwno","Clonw","Clown"]

In ls3 now you see 2 times the word "Clown". As output I want:

["Clown"]

This is what I mean with double words in ls3.

1
It's hard to understand what exactly you want, please add an example. Also, please indent your code properly.leftaroundabout
@leftaroundabout edited!user2502169
Still completely unclear. We don't know what's in "dictionary.txt", we don't know what combination does, and we can only guess what you mean by "double elements". Just give example values for ls1 and ls2, and what you expect to find in ls3.user824425
@Rhymoid I made a new edit. And I add the combination function in the codeuser2502169

1 Answers

1
votes

To keep to the way you outline in your question – well, this "combining" of two lists is just appending, so use ls1 ++ ls2. Then, provided you're ok if the order is changed, the obvious thing is to sort the list so equivalent elements are next to each other. You can do this with sortBy, you just need to provide a function that compares a case-normalised version of two strings. The easiest way to do that is with the combinators from Data.Function:

import Data.List
import Data.Function
import Data.Char

compareCaseInsensitiv :: String -> String -> Ordering
compareCaseInsensitiv = compare `on` map toUpper

With "duplicates" then being adjacent, you can then extract them with a simple recursive function. You can again use compareCaseInsensitiv for that, matching on EQ.

Note, however, that the whole approach is rather suboptimal. The combining step isn't a natural thing to do, after all the list of permutations of the available characters has a completely different meaning from the dictionary list. Sorting (an O (n log n) operation) is quite ridiculous and ineffective since the dictionary is probably already sorted. It's much better to recurse through the two lists, each sorted seperately, "in parallel", in a merge-sort like fashion.