Dougal Stanton wrote: > The following is a slap-dash program for generating a list of pairs of > words which differ by, at most, one letter. It's quite verbose at the > moment, because (a) that was the way I wrote it, a snippet at a time, > and (b) I lack the wit to make it shorter. > > Can anyone recommend ways to make this program more > efficient/neat/elegant? It runs in decent time on my machine, but it's > not exceedingly pretty and I'm sure it can be made shorter too.
I like it for its elegant point-free style :) > -- Number of letters difference between two words. > difference :: Pair -> Int > difference = length . filter (==False) . uncurry (zipWith (==)) Apparently, difference can only detect character replacements but not character insertion or deletion, but that's probably not your use case. > -- Pairs of words of equal length, sorted to reduce > -- duplicates of (a,b), (b,a) type. They shouldn't > -- be completely eradicated because part of the game > -- is to spot when they;re the same word. > listPairs :: WordSet -> PairSet > listPairs ws = [ (w, w') | w <- ws, w' <- ws, length w == length w', w > <= w' ] You can avoid generating the superfluous half of the pairs by using tails listPairs ws = [ (head ws', w') | ws' <- tails ws, w' <- ws' , let w = head ws', length w == length w'] Of course, grouping words by length first and pairing the resulting groups is more efficient than filtering out all the pairs where length w /= length w'. But you restrict fingerspell to a fixed word length anyway, so it doesn't matter. Regards, apfelmus _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe