--- Comment #14 from 2012-01-29 12:53:57 PST ---
Another example of the usefulness of maxs/mins:
> Define an ordered word as a word in which the letters of the word appear
> in alphabetic order. Examples include 'abbey' and 'dirt'. The task is to 
> find and display all the ordered words in this dictionary that have the
> longest word length.

A D2 solution:

import std.stdio, std.algorithm, std.range, std.file;
void main() {
    auto ws = filter!isSorted(readText("unixdict.txt").split());
    immutable maxl = reduce!max(map!walkLength(ws));
    writeln(filter!(w => w.length == maxl)(ws));

With a maxs the code becomes shorter, simpler, more readable and it needs to
scan the items only once, instead of two as the reduce-max + filter. When the
items are many scanning them only once speeds up the code, and it's usable with
InputRanges too that allow only a single scan of the items:

import std.stdio, std.algorithm, std.range, std.file;
void main() {
    auto ws = filter!sorted?(readText("unixdict.txt").split());

Another hint of the usefulness of the maxs (and mins) function comes from
looking at the Haskell solution, that contains the keepLongest function that
essentially is a maxs!length (but it returns the items in reverse order, for
efficiency because it uses a list):

isOrdered wws@(_ : ws) = and $ zipWith (<=) wws ws

keepLongest _ acc [] = acc
keepLongest max acc (w : ws) =
  let len = length w in 
  case compare len max of
    LT -> keepLongest max acc ws
    EQ -> keepLongest max (w : acc) ws
    GT -> keepLongest len [w] ws

longestOrderedWords = reverse . keepLongest 0 [] . filter isOrdered

main = do
  str <- getContents
  let ws = longestOrderedWords $ words str
  mapM_ putStrLn ws

Configure issuemail:
------- You are receiving this mail because: -------

Reply via email to