[Haskell-beginners] Code help requested
David Frey
dpfrey at shaw.ca
Mon Jan 11 21:43:58 EST 2010
On January 11, 2010 5:22:49 pm Joe Van Dyk wrote:
> I've written two versions of the same program, one in ruby and one in
> haskell. Given words on stdin, find all the anagrams in those words.
> For nicer display, we're only going to display the top 3 results.
>
> I'm obviously new to haskell. The ruby version runs about 5x as fast
> on a large file. How can I improve the haskell version?
>
> http://gist.github.com/274774
>
> # Ruby version
> input = STDIN.read.split("\n")
> result = Hash.new([])
> input.each do |word|
> sorted_word = word.split('').sort.join
> result[sorted_word] += [word]
> end
> values = result.values.sort { |a, b| b.size <=> a.size }
> p values[0..3]
>
> # Haskell version
> import List
> import qualified Data.Map as Map
>
> -- Given as stdin
> -- presents
> -- serpents
> -- no
> -- on
> -- whatever
> -- Expected Output:
> -- [["serpents","presents"],["on","no"]]
>
> -- This version only displays words that have more than one
> -- match in the list, and sorts by the words that got the most matches.
>
> -- Can we do the map bit better?
>
> main = do
> input <- getContents
> print $ anagrams $ lines input
>
> anagrams words =
> sorted_anagrams
> where
> sorted_anagrams = sortBy sorter filtered_anagrams
> sorter a b = compare (length b) (length a)
> filtered_anagrams = Map.elems $ Map.filter filter_function all_anagrams
> filter_function words = length words > 1
> all_anagrams = do_anagrams words Map.empty
> do_anagrams [] result = result
> do_anagrams words result = do_anagrams
> (tail words)
> (Map.unionWith
> (++)
> (Map.fromList
> [(sorted_current_word, [current_word])])
> result)
> where
> current_word = head words
> sorted_current_word = sort current_word
>
Can you provide a link to the data you are using as input? I ran your program
over a list of 15000 words and it finished in 0.4 seconds.
More information about the Beginners
mailing list