Ordered words

From Rosetta Code
Jump to: navigation, search
Task
Ordered words
You are encouraged to solve this task according to the task description, using any language you may know.

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. (Examples that access the dictionary file locally assume that you have downloaded this file yourself.) The display needs to be shown on this page.

Contents

[edit] Ada

with Ada.Containers.Indefinite_Vectors;
with Ada.Text_IO;
procedure Ordered_Words is
package Word_Vectors is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive, Element_Type => String);
 
function Is_Ordered (The_Word : String) return Boolean is
Highest_Character : Character := 'a';
begin
for I in The_Word'Range loop
if The_Word(I) not in 'a' .. 'z' then
return False;
end if;
if The_Word(I) < Highest_Character then
return False;
end if;
Highest_Character := The_Word(I);
end loop;
return True;
end Is_Ordered;
 
procedure Print_Word (Position : Word_Vectors.Cursor) is
begin
Ada.Text_IO.Put_Line (Word_Vectors.Element (Position));
end Print_Word;
 
File : Ada.Text_IO.File_Type;
Ordered_Words : Word_Vectors.Vector;
Max_Length : Positive := 1;
begin
Ada.Text_IO.Open (File, Ada.Text_IO.In_File, "unixdict.txt");
while not Ada.Text_IO.End_Of_File (File) loop
declare
Next_Word : String := Ada.Text_IO.Get_Line (File);
begin
if Is_Ordered (Next_Word) then
if Next_Word'Length > Max_Length then
Max_Length := Next_Word'Length;
Word_Vectors.Clear (Ordered_Words);
Word_Vectors.Append (Ordered_Words, Next_Word);
elsif Next_Word'Length = Max_Length then
Word_Vectors.Append (Ordered_Words, Next_Word);
end if;
end if;
end;
end loop;
Word_Vectors.Iterate (Ordered_Words, Print_Word'Access);
end Ordered_Words;

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Aime

integer
ordered(text s)
{
integer a, i, l;
 
a = 1;
 
l = length(s);
if (l) {
l -= 1;
i = 0;
while (i < l) {
if (character(s, i + 1) < character(s, i)) {
a = 0;
break;
}
i += 1;
}
}
 
return a;
}
 
integer
main(void)
{
integer l, m;
file f;
list w;
text s;
 
f_affix(f, "unixdict.txt");
 
m = 0;
 
while ((l = f_line(f, s)) != -1) {
if (m <= l) {
if (ordered(s)) {
if (m < l) {
m = l;
l_clear(w);
}
l_append(w, s);
}
}
}
 
l = l_length(w);
m = 0;
while (m < l) {
o_text(l_q_text(w, m));
o_byte('\n');
m += 1;
}
 
return 0;
}
Output:
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] AutoHotkey

This script uses the ASCII value of each letter to determine its place in the alphabet. Given a dictionary not all in the same case, StringLower could be used. This script assumes a locally downloaded copy of the dictionary, but UrlDownloadToFile could be used. The purpose of the GUI is simply to display a field where the user can copy the list. MsgBox could be used, or FileAppend.

 
MaxLen=0
Loop, Read, UnixDict.txt ; Assigns A_LoopReadLine to each line of the file
{
thisword := A_LoopReadLine ; Just for readability
blSort := isSorted(thisWord) ; reduce calls to IsSorted to improve performance
ThisLen := StrLen(ThisWord) ; reduce calls to StrLen to improve performance
If (blSort = true and ThisLen = maxlen)
list .= ", " . thisword
Else If (blSort = true and ThisLen > maxlen)
{
list := thisword
maxlen := ThisLen
}
}
 
IsSorted(word){ ; This function uses the ASCII value of the letter to determine its place in the alphabet.
; Thankfully, the dictionary is in all lowercase
lastchar=0
Loop, parse, word
{
if ( Asc(A_LoopField) < lastchar )
return false
lastchar := Asc(A_loopField)
}
return true
}
 
GUI, Add, Edit, w300 ReadOnly, %list%
GUI, Show
return ; End Auto-Execute Section
 
GUIClose:
ExitApp
 

Output:

abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty

[edit] AWK

BEGIN {
abc = "abcdefghijklmnopqrstuvwxyz"
}
 
{
# Check if this line is an ordered word.
ordered = 1 # true
left = -1
for (i = 1; i <= length($0); i++) {
right = index(abc, substr($0, i, 1))
if (right == 0 || left > right) {
ordered = 0 # false
break
}
left = right
}
 
if (ordered) {
score = length($0)
if (score > best["score"]) {
# Reset the list of best ordered words.
best["score"] = score
best["count"] = 1
best[1] = $0
} else if (score == best["score"]) {
# Add this word to the list.
best[++best["count"]] = $0
}
}
}
 
END {
# Print the list of best ordered words.
for (i = 1; i <= best["count"]; i++)
print best[i]
}

You must provide unixdict.txt as input.

$ awk -f ordered-words.awk unixdict.txt                                        
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] BBC BASIC

An optimisation is that the word isn't checked for being ordered unless it is at least as long as the current maximum.

      dict% = OPENIN("unixdict.txt")
IF dict%=0 ERROR 100, "Failed to open dictionary file"
 
max% = 2
REPEAT
A$ = GET$#dict%
IF LENA$ >= max% THEN
i% = 0
REPEAT i% += 1
UNTIL ASCMID$(A$,i%) > ASCMID$(A$,i%+1)
IF i% = LENA$ THEN
IF i% > max% max% = i% : list$ = ""
list$ += A$ + CHR$13 + CHR$10
ENDIF
ENDIF
UNTIL EOF#dict%
CLOSE #dict%
PRINT list$
END

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Bracmat

  ( orderedWords
= bow result longestLength word character
. 0:?bow
& :?result
& 0:?longestLength
& @( get$(!arg,STR)
 :  ?
( [!bow %?word \n [?bow ?
& @( !word
 : ( ? %@?character <%@!character ?
|  ?
( [!longestLength
& !word !result:?result
| [>!longestLength:[?longestLength
& !word:?result
|
)
)
)
& ~`
)
)
| !result
)
& orderedWords$"unixdict.txt"
  knotty
  glossy
  floppy
  effort
  choppy
  choosy
  chilly
  biopsy
  billow
  bellow
  almost
  accost
  access
  accept
  accent
  abbott

[edit] Burlesque

This example does not show the output mentioned in the task description on this page (or a page linked to from here). Please ensure that it meets all task requirements and remove this message.
Note that phrases in task descriptions such as "print and display" and "print and show" for example, indicate that (reasonable length) output be a part of a language's solution.


 
ln{so}f[^^{L[}>mL[bx(==)[+(L[)+]f[uN
 

[edit] C

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
 
 
#define MAXLEN 100
typedef char TWord[MAXLEN];
 
 
typedef struct Node {
TWord word;
struct Node *next;
} Node;
 
 
int is_ordered_word(const TWord word) {
assert(word != NULL);
int i;
 
for (i = 0; word[i] != '\0'; i++)
if (word[i] > word[i + 1] && word[i + 1] != '\0')
return 0;
 
return 1;
}
 
 
Node* list_prepend(Node* words_list, const TWord new_word) {
assert(new_word != NULL);
Node *new_node = malloc(sizeof(Node));
if (new_node == NULL)
exit(EXIT_FAILURE);
 
strcpy(new_node->word, new_word);
new_node->next = words_list;
return new_node;
}
 
 
Node* list_destroy(Node *words_list) {
while (words_list != NULL) {
Node *temp = words_list;
words_list = words_list->next;
free(temp);
}
 
return words_list;
}
 
 
void list_print(Node *words_list) {
while (words_list != NULL) {
printf("\n%s", words_list->word);
words_list = words_list->next;
}
}
 
 
int main() {
FILE *fp = fopen("unixdict.txt", "r");
if (fp == NULL)
return EXIT_FAILURE;
 
Node *words = NULL;
TWord line;
unsigned int max_len = 0;
 
while (fscanf(fp, "%99s\n", line) != EOF) {
if (strlen(line) > max_len && is_ordered_word(line)) {
max_len = strlen(line);
words = list_destroy(words);
words = list_prepend(words, line);
} else if (strlen(line) == max_len && is_ordered_word(line)) {
words = list_prepend(words, line);
}
}
 
fclose(fp);
list_print(words);
 
return EXIT_SUCCESS;
}

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

Alternative version with dynamic array:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
 
 
#define MAXLEN 100
typedef char TWord[MAXLEN];
 
 
typedef struct WordsArray {
TWord *words;
size_t len;
} WordsArray;
 
 
int is_ordered_word(const TWord word) {
assert(word != NULL);
int i;
 
for (i = 0; word[i] != '\0'; i++)
if (word[i] > word[i + 1] && word[i + 1] != '\0')
return 0;
 
return 1;
}
 
 
void array_append(WordsArray *words_array, const TWord new_word) {
assert(words_array != NULL);
assert(new_word != NULL);
assert((words_array->len == 0) == (words_array->words == NULL));
 
words_array->len++;
words_array->words = realloc(words_array->words,
words_array->len * sizeof(words_array->words[0]));
if (words_array->words == NULL)
exit(EXIT_FAILURE);
strcpy(words_array->words[words_array->len-1], new_word);
}
 
 
void array_free(WordsArray *words_array) {
assert(words_array != NULL);
free(words_array->words);
words_array->words = NULL;
words_array->len = 0;
}
 
 
void list_print(WordsArray *words_array) {
assert(words_array != NULL);
size_t i;
for (i = 0; i < words_array->len; i++)
printf("\n%s", words_array->words[i]);
}
 
 
int main() {
FILE *fp = fopen("unixdict.txt", "r");
if (fp == NULL)
return EXIT_FAILURE;
 
WordsArray words;
words.len = 0;
words.words = NULL;
 
TWord line;
line[0] = '\0';
unsigned int max_len = 0;
 
while (fscanf(fp, "%99s\n", line) != EOF) { // 99 = MAXLEN - 1
if (strlen(line) > max_len && is_ordered_word(line)) {
max_len = strlen(line);
array_free(&words);
array_append(&words, line);
} else if (strlen(line) == max_len && is_ordered_word(line)) {
array_append(&words, line);
}
}
 
fclose(fp);
list_print(&words);
array_free(&words);
 
return EXIT_SUCCESS;
}

[edit] Mmap

Shorter and potentially much faster version with mmap (2). No stinky malloc or scanf calls.

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <string.h>
 
int ordered(char *s, char **end)
{
int r = 1;
while (*++s != '\n' && *s != '\r' && *s != '\0')
if (s[0] < s[-1]) r = 0;
 
*end = s;
return r;
}
 
int main()
{
char *buf, *word, *end, *tail;
struct stat st;
int longest = 0, len, fd;
 
if ((fd = open("unixdict.txt", O_RDONLY)) == -1) err(1, "read error");
 
fstat(fd, &st);
if (!(buf = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)))
err(1, "mmap");
 
for (word = end = buf; end < buf + st.st_size; word = end) {
while (*word == '\r' || *word == '\n') word++;
if (!ordered(word, &end)) continue;
if ((len = end - word + 1) < longest) continue;
if (len > longest) {
tail = buf; /* longer words found; reset out buffer */
longest = len;
}
/* use the same mmap'd region to store output. because of MAP_PRIVATE,
* change will not go back to file. mmap is copy on write, and we are using
* only the head space to store output, so kernel doesn't need to copy more
* than the words we saved--in this case, one page tops.
*/

memcpy(tail, word, len);
tail += len;
*tail = '\0';
}
printf(buf);
 
munmap(buf, st.st_size);
close(fd);
return 0;
}

[edit] C++

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
 
bool ordered(const std::string &word)
{
return std::is_sorted(word.begin(), word.end()); // C++11
}
 
int main()
{
std::ifstream infile("unixdict.txt");
if (!infile) {
std::cerr << "Can't open word file\n";
return -1;
}
 
std::vector<std::string> words;
std::string word;
int longest = 0;
 
while (std::getline(infile, word)) {
int length = word.length();
if (length < longest) continue; // don't test short words
 
if (ordered(word)) {
if (longest < length) {
longest = length; // set new minimum length
words.clear(); // reset the container
}
words.push_back(word);
}
}
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] C#

using System;
using System.Linq;
using System.Net;
 
static class Program
{
static void Main(string[] args)
{
WebClient client = new WebClient();
string text = client.DownloadString("http://www.puzzlers.org/pub/wordlists/unixdict.txt");
string[] words = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
 
var query = from w in words
where IsOrderedWord(w)
group w by w.Length into ows
orderby ows.Key descending
select ows;
 
Console.WriteLine(string.Join(", ", query.First().ToArray()));
}
 
private static bool IsOrderedWord(string w)
{
for (int i = 1; i < w.Length; i++)
if (w[i] < w[i - 1])
return false;
 
return true;
}
}

Output:

abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty


[edit] Clojure

(defn is-sorted? [coll]
(not-any? pos? (map compare coll (next coll))))
 
(defn take-while-eqcount [coll]
(let [n (count (first coll))]
(take-while #(== n (count %)) coll)))
 
(with-open [rdr (clojure.java.io/reader "unixdict.txt")]
(->> rdr
line-seq
(filter is-sorted?)
(sort-by count >)
take-while-eqcount
(clojure.string/join ", ")
println))

Output

abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty

[edit] CoffeeScript

 
ordered_word = (word) ->
for i in [0...word.length - 1]
return false unless word[i] <= word[i+1]
true
 
show_longest_ordered_words = (candidates, dict_file_name) ->
words = ['']
for word in candidates
continue if word.length < words[0].length
if ordered_word word
words = [] if word.length > words[0].length
words.push word
return if words[0] == '' # we came up empty
console.log "Longest Ordered Words (source=#{dict_file_name}):"
for word in words
console.log word
 
dict_file_name = 'unixdict.txt'
file_content = require('fs').readFileSync dict_file_name
dict_words = file_content.toString().split '\n'
show_longest_ordered_words dict_words, dict_file_name
 

output

 
> coffee ordered_words.coffee
Longest Ordered Words (source=unixdict.txt):
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty
 

[edit] Common Lisp

(defun orderedp (word)
(reduce (lambda (prev curr)
(when (char> prev curr) (return-from orderedp nil))
curr)
word)
t)
 
(defun longest-ordered-words (filename)
(let ((result nil))
(with-open-file (s filename)
(loop
with greatest-length = 0
for word = (read-line s nil)
until (null word)
do (let ((length (length word)))
(when (and (>= length greatest-length)
(orderedp word))
(when (> length greatest-length)
(setf greatest-length length
result nil))
(push word result)))))
(nreverse result)))
 
CL-USER> (longest-ordered-words "unixdict.txt")
("abbott" "accent" "accept" "access" "accost" "almost" "bellow" "billow"
"biopsy" "chilly" "choosy" "choppy" "effort" "floppy" "glossy" "knotty")
 

[edit] D

[edit] Simple Procedural Version

import std.stdio, std.algorithm, std.range, std.string;
 
void main() {
string[] result;
size_t maxLen;
 
foreach (string word; File("unixdict.txt").lines()) {
word = word.chomp();
immutable len = walkLength(word);
if (len < maxLen || !isSorted(word))
continue;
if (len > maxLen) {
result = [word];
maxLen = len;
} else
result ~= word;
}
 
writeln(result.join("\n"));
}
Output:
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Faster Procedural Version

Faster, same output.

void main() {
import std.stdio, std.algorithm, std.file, std.range;
string[] result;
size_t maxWalkLen;
 
foreach (word; "unixdict.txt".readText.splitter) {
if (word.length >= maxWalkLen && word.isSorted) {
immutable wlen = word.walkLength;
if (wlen > maxWalkLen) {
result.length = 0;
maxWalkLen = wlen;
}
result ~= word.idup;
}
}
 
writefln("%-(%s\n%)", result);
}

[edit] Functional Version

Shorter, same output.

import std.stdio, std.algorithm, std.range, std.file, std.string;
 
void main() {
auto words = "unixdict.txt".readText.split.filter!isSorted;
immutable maxLen = words.map!q{a.length}.reduce!max;
writefln("%-(%s\n%)", words.filter!(w => w.length == maxLen));
}

[edit] Fastest Memory Mapped Version

Lower level, much faster with large input files (about as fast as the memory mapped C version). The output is the same. It works only with ASCII texts, but unlike the C entry works on both Posix and Windows.

Translation of: C
import std.stdio, core.stdc.string, std.mmfile, std.algorithm;
 
const(char)[] findWord(const char[] s) pure nothrow @safe {
// return s.takeWhile!(c => c !in "\n\r");
size_t wordEnd = 0;
while (wordEnd < s.length && s[wordEnd] != '\n'
&& s[wordEnd] != '\r')
wordEnd++;
return s[0 .. wordEnd];
}
 
void main() {
auto mmf = new MmFile("unixdict.txt",
MmFile.Mode.readCopyOnWrite, 0, null);
auto txt = cast(char[])(mmf[]);
size_t maxLen = 0, outStart = 0;
 
for (size_t wordStart = 0; wordStart < txt.length; ) {
while (wordStart < txt.length &&
(txt[wordStart] == '\r' || txt[wordStart] == '\n'))
wordStart++;
const word = findWord(txt[wordStart .. $]);
wordStart += word.length;
 
if (word.length < maxLen || !word.isSorted())
continue;
if (word.length > maxLen) {
// Longer ordered word found, reset the out buffer.
outStart = 0;
maxLen = word.length;
}
 
// Use the same mmap'd region to store output. Because of
// Mode.readCopyOnWrite, change will not go back to file.
// We are using only the head space to store output, so
// kernel doesn't need to copy more than the words we saved,
// in this case, one page tops.
memcpy(&txt[outStart], word.ptr, word.length);
outStart += word.length;
txt[outStart++] = '\n'; // Words separator in out buffer.
}
 
write(txt[0 .. outStart]);
}

[edit] Delphi

 
program POrderedWords;
 
{$APPTYPE CONSOLE}
 
uses
SysUtils, Classes, IdHTTP;
 
function IsOrdered(const s:string): Boolean;
var
I: Integer;
begin
Result := Length(s)<2; // empty or 1 char strings are ordered
for I := 2 to Length(s) do
if s[I]<s[I-1] then // can improve using case/localization to order...
Exit;
Result := True;
end;
 
function ProcessDictionary(const AUrl: string): string;
var
slInput: TStringList;
I, WordSize: Integer;
begin
slInput := TStringList.Create;
try
with TIdHTTP.Create(nil) do try
slInput.Text := Get(AUrl);
finally
Free;
end;
// or use slInput.LoadFromFile('yourfilename') to load from a local file
WordSize :=0;
for I := 0 to slInput.Count-1 do begin
if IsOrdered(slInput[I]) then
if (Length(slInput[I]) = WordSize) then
Result := Result + slInput[I] + ' '
else if (Length(slInput[I]) > WordSize) then begin
Result := slInput[I] + ' ';
WordSize := Length(slInput[I]);
end;
end;
finally
slInput.Free;
end;
end;
 
begin
try
WriteLn(ProcessDictionary('http://www.puzzlers.org/pub/wordlists/unixdict.txt'));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
 

Output: dictionary directly processed from the URL

 
abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty
 

[edit] E

Translation of: Python
pragma.enable("accumulator")
 
def words := <http://www.puzzlers.org/pub/wordlists/unixdict.txt>.getText().split("\n")
def ordered := accum [] for word ? (word.sort() <=> word) in words { _.with(word) }
def maxLen := accum 0 for word in ordered { _.max(word.size()) }
def maxOrderedWords := accum [] for word ? (word.size() <=> maxLen) in ordered { _.with(word) }
println(" ".rjoin(maxOrderedWords))

One-pass procedural algorithm which avoids keeping the entire data set in memory:

def best := [].diverge()
for `@word$\n` ? (word.sort() <=> word) in <http://www.puzzlers.org/pub/wordlists/unixdict.txt> {
if (best.size() == 0) {
best.push(word)
} else if (word.size() > best[0].size()) {
best(0) := [word] # replace all
} else if (word.size() <=> best[0].size()) {
best.push(word)
}
}
println(" ".rjoin(best.snapshot()))

Output: abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] Erlang

 
-module( ordered_words ).
 
-export( [is_ordered/1, task/0] ).
 
is_ordered( Word ) -> lists:sort( Word ) =:= Word.
 
task() ->
ok = find_unimplemented_tasks:init_http(),
Ordered_words = [X || X <- words(), is_ordered(X)],
Sorted_longest_length_first = lists:reverse( sort_with_length( Ordered_words ) ),
[{Max_length, _Word1} | _T] = Sorted_longest_length_first,
Longest_length_first = lists:takewhile( fun({Length, _Word2}) -> Length =:= Max_length end, Sorted_longest_length_first ),
[X || {_Length, X} <- Longest_length_first].
 
 
 
sort_with_length( Words ) ->
Words_with_length_first = [{erlang:length(X), X} || X <- Words],
lists:sort( Words_with_length_first ).
 
words() -> anagrams_deranged:words_from_url( "http://www.puzzlers.org/pub/wordlists/unixdict.txt" ).
 
Output:
2> ordered_words:task().
["knotty","glossy","floppy","effort","choppy","choosy",
 "chilly","biopsy","billow","bellow","almost","accost",
 "access","accept","accent","abbott"]

[edit] Euphoria

include misc.e
 
type ordered(sequence s)
for i = 1 to length(s)-1 do
-- assume all items in the sequence are atoms
if s[i]>s[i+1] then
return 0
end if
end for
return 1
end type
 
integer maxlen
sequence words
object word
constant fn = open("unixdict.txt","r")
maxlen = -1
 
while 1 do
word = gets(fn)
if atom(word) then
exit
end if
word = word[1..$-1] -- truncate new-line
if length(word) >= maxlen and ordered(word) then
if length(word) > maxlen then
maxlen = length(word)
words = {}
end if
words = append(words,word)
end if
end while
 
close(fn)
 
pretty_print(1,words,{2})

Output:

{
  "abbott",
  "accent",
  "accept",
  "access",
  "accost",
  "almost",
  "bellow",
  "billow",
  "biopsy",
  "chilly",
  "choosy",
  "choppy",
  "effort",
  "floppy",
  "glossy",
  "knotty"
}

[edit] F#

open System
open System.IO
 
let longestOrderedWords() =
let isOrdered = Seq.pairwise >> Seq.forall (fun (a,b) -> a <= b)
 
File.ReadLines("unixdict.txt")
|> Seq.filter isOrdered
|> Seq.groupBy (fun s -> s.Length)
|> Seq.sortBy (fst >> (~-))
|> Seq.head |> snd
 
longestOrderedWords() |> Seq.iter (printfn "%s")

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Factor

 
USING: grouping http.client io io.encodings.utf8 io.files
io.files.temp kernel math memoize sequences sequences.extras
unicode.case urls ;
IN: rosetta-code.ordered-words
 
MEMO: word-list ( -- seq )
"unixdict.txt" temp-file dup exists? [
URL" http://puzzlers.org/pub/wordlists/unixdict.txt"
over download-to
] unless utf8 file-lines ;
 
: ordered-word? ( word -- ? )
>lower [ <= ] monotonic? ;
 
: ordered-words-main ( -- )
word-list [ ordered-word? ] filter
all-longest [ print ] each ;
 
Output:
( scratchpad ) USING: ordered-words-main ;
( scratchpad ) main
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Fantom

 
class Main
{
public static Bool ordered (Str word)
{
word.chars.all |Int c, Int i -> Bool|
{
(i == (word.size-1) || c <= word.chars[i+1])
}
}
 
public static Void main ()
{
Str[] words := [,]
File(`unixdict.txt`).eachLine |Str word|
{
if (ordered(word))
{
if (words.isEmpty || words.first.size < word.size)
{ // reset the list
words = [word]
}
else if (words.size >= 1 && words.first.size == word.size)
{ // add word to existing ones
words.add (word)
}
}
}
echo (words.join (" "))
}
}
 

Output:

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] FBSL

Downloads the list from puzzlers.org.

#APPTYPE CONSOLE
 
FUNCTION RESTfulGET(url)
DIM %HTTP = CREATEOBJECT("WinHttp.WinHttpRequest.5.1")
CALLMETHOD(HTTP, ".open %s, %s, %d", "GET", url, FALSE)
CALLMETHOD(HTTP, ".send")
RETURN GETVALUE("%s", HTTP, ".ResponseText")
END FUNCTION
 
DIM $TEXT = RESTfulGET("http://www.puzzlers.org/pub/wordlists/unixdict.txt")
DIM dict[] = Split(TEXT, CHR(10))
DIM max AS INTEGER = UBOUND(dict)
DIM theword AS STRING
DIM words[]
FOR DIM i = 0 TO max
theWord = dict[i]
IF isOrdered(theWord) THEN
words[LEN(theWord)] = words[LEN(theWord)] & " " & theWord
END IF
NEXT
 
PRINT words[UBOUND(words)]
 
PAUSE
 
FUNCTION isOrdered(s)
FOR DIM i = 1 TO LEN(s) - 1
IF s{i} > s{i + 1} THEN
RETURN FALSE
END IF
NEXT
RETURN TRUE
END FUNCTION
 

Output

 abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

Press any key to continue...

[edit] Forth

Works with: 4tH version 3.61.2

This program uses a string stack, which means that all matching words are stored on a stack. The longest word ends up on the top of the stack.

 
include lib/stmstack.4th \ include string stack library
 
: check-word ( a n -- a n f)
2dup bl >r \ start off with a space
begin
dup \ when not end of word
while
over c@ r@ >= \ check character
while
r> drop over c@ >r chop \ chop character off
repeat r> drop nip 0= \ cleanup and set flag
;
 
: open-file ( -- h)
1 dup argn = abort" Usage: ordered infile"
args input open error? abort" Cannot open file"
dup use \ return and use the handle
;
 
: read-file ( --)
0 >r \ begin with zero length
begin
refill \ EOF detected?
while
0 parse dup r@ >= \ equal or longer string length?
if \ check the word and adjust length
check-word if r> drop dup >r >s else 2drop then
else \ if it checks out, put on the stack
2drop \ otherwise drop the word
then
repeat r> drop \ clean it up
;
 
: read-back ( --)
s> dup >r type cr \ longest string is on top of stack
begin s> dup r@ >= while type cr repeat
2drop r> drop \ keep printing until shorter word
; \ has been found
 
: ordered ( --)
open-file s.clear read-file read-back close
; \ open file, clear the stack, read file
\ read it back and close the file
ordered

Since the longest word is on top of the stack, the only thing to be done is to pop all words from the stack until a shorter word is encountered. Consequently, all words are listed in reverse order:

knotty
glossy
floppy
effort
choppy
choosy
chilly
biopsy
billow
bellow
almost
accost
access
accept
accent
abbott

[edit] Fortran

 
!***************************************************************************************
module ordered_module
!***************************************************************************************
implicit none
 
!the dictionary file:
integer,parameter :: file_unit = 1000
character(len=*),parameter :: filename = 'unixdict.txt'
 
!maximum number of characters in a word:
integer,parameter :: max_chars = 50
 
type word
character(len=max_chars) :: str !the word from the dictionary
integer :: n = 0 !length of this word
logical :: ordered = .false. !if it is an ordered word
end type word
 
!the dictionary structure:
type(word),dimension(:),allocatable :: dict
 
contains
!***************************************************************************************
 
!******************************************************************************
function count_lines_in_file(fid) result(n_lines)
!******************************************************************************
implicit none
 
integer :: n_lines
integer,intent(in) :: fid
character(len=1) :: tmp
integer :: i
integer :: ios
 
!the file is assumed to be open already.
 
rewind(fid) !rewind to beginning of the file
 
n_lines = 0
do !read each line until the end of the file.
read(fid,'(A1)',iostat=ios) tmp
if (ios < 0) exit !End of file
n_lines = n_lines + 1 !row counter
end do
 
rewind(fid) !rewind to beginning of the file
 
!******************************************************************************
end function count_lines_in_file
!******************************************************************************
 
!******************************************************************************
pure elemental function ordered_word(word) result(yn)
!******************************************************************************
! turns true if word is an ordered word, false if it is not.
!******************************************************************************
 
implicit none
character(len=*),intent(in) :: word
logical :: yn
 
integer :: i
 
yn = .true.
do i=1,len_trim(word)-1
if (ichar(word(i+1:i+1))<ichar(word(i:i))) then
yn = .false.
exit
end if
end do
 
!******************************************************************************
end function ordered_word
!******************************************************************************
 
!***************************************************************************************
end module ordered_module
!***************************************************************************************
 
!****************************************************
program main
!****************************************************
use ordered_module
implicit none
 
integer :: i,n,n_max
 
!open the dictionary and read in all the words:
open(unit=file_unit,file=filename) !open the file
n = count_lines_in_file(file_unit) !count lines in the file
allocate(dict(n)) !allocate dictionary structure
do i=1,n !
read(file_unit,'(A)') dict(i)%str !each line is a word in the dictionary
dict(i)%n = len_trim(dict(i)%str) !save word length
end do
close(file_unit) !close the file
 
!use elemental procedure to get ordered words:
dict%ordered = ordered_word(dict%str)
 
!max length of an ordered word:
n_max = maxval(dict%n, mask=dict%ordered)
 
!write the output:
do i=1,n
if (dict(i)%ordered .and. dict(i)%n==n_max) write(*,'(A,A)',advance='NO') trim(dict(i)%str),' '
end do
write(*,*) ''
 
!****************************************************
end program main
!****************************************************
 

Output

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty  

[edit] Go

Go has strings and Unicode and stuff, but with the dictionary all ASCII and lower case, strings and Unicode seem overkill. I just worked with byte slices here, only converting the final result to strings for easy output.

package main
 
import (
"bytes"
"fmt"
"io/ioutil"
)
 
func main() {
// read into memory in one chunk
b, err := ioutil.ReadFile("unixdict.txt")
if err != nil {
fmt.Println(err)
return
}
// split at line ends
bss := bytes.Split(b, []byte{'\n'})
 
// accumulate result
var longest int
var list [][]byte
for _, bs := range bss {
// don't bother with words shorter than
// our current longest ordered word
if len(bs) < longest {
continue
}
// check for ordered property
var lastLetter byte
for i := 0; ; i++ {
if i == len(bs) {
// end of word. it's an ordered word.
// save it and break from loop
if len(bs) > longest {
longest = len(bs)
list = list[:0]
}
list = append(list, bs)
break
}
// check next letter
b := bs[i]
if b < 'a' || b > 'z' {
continue // not a letter. ignore.
}
if b < lastLetter {
break // word not ordered.
}
// letter passes test
lastLetter = b
}
}
// print result
for _, bs := range list {
fmt.Println(string(bs))
}
}

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Groovy

Solution:

def isOrdered = { word -> def letters = word as List; letters == ([] + letters).sort() }
assert isOrdered('abbey')
assert !isOrdered('cat')
 
def dictUrl = new URL('http://www.puzzlers.org/pub/wordlists/unixdict.txt')
def orderedWords = dictUrl.readLines().findAll { isOrdered(it) }
def owMax = orderedWords*.size().max()
 
orderedWords.findAll { it.size() == owMax }.each { println it }

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Haskell

 
-- Words are read from the standard input. We keep in memory only the current
-- set of longest, ordered words.
--
-- Limitation: the locale's collation order is not take into consideration.
 
isOrdered wws@(_:ws) = and $ zipWith (<=) wws ws
 
longestOrderedWords = reverse . snd . foldl f (0,[]) . filter isOrdered
where f (max, acc) w =
let len = length w in
case compare len max of
LT -> (max, acc)
EQ -> (max, w:acc)
GT -> (len, [w])
 
main = do
str <- getContents
let ws = longestOrderedWords $ words str
mapM_ putStrLn ws
 

Output:

 
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty
 

Alternative version:

import Control.Monad (liftM)
 
isSorted wws@(_ : ws) = and $ zipWith (<=) wws ws
 
getLines = liftM lines . readFile
 
main = do
ls <- getLines "unixdict.txt"
let ow = filter isSorted ls
let maxl = foldr max 0 (map length ow)
print $ filter (\w -> (length w) == maxl) ow

[edit] Icon and Unicon

link strings
 
procedure main(A)
f := open(\A[1]) | stop("Give dictionary file name on command line")
every (maxLen := 0, maxLen <= *(w := !f), w == csort(w)) do {
if maxLen <:= *w then maxList := [] #discard any shorter sorted words
put(maxList, w)
}
every write(!\maxList)
end

strings provides csort which sorts the letters within a string

Output:

->ordered_words unixdict.txt
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty
->

[edit] J

   require'web/gethttp'
dict=: gethttp'http://www.puzzlers.org/pub/wordlists/unixdict.txt'
oWords=: (#~ ] = /:~L:0) <;._2 dict-.CR
 ;:inv (#~ (= >./)@:(#@>))oWords
abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

Recap:

  1. fetch dictionary (dict)
  2. break into words, one per line (<;._2 dict-.CR)
  3. find ordered words (oWords)
  4. select the longest ordered words ((#~ (= >./)@:(#@>))oWords)
  5. format for display (using ;:inv)

[edit] Java

Works with: Java version 1.5+

This example assumes there is a local copy of the dictionary whose path is given as the first argument to the program.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
 
public class Ordered {
 
private static boolean isOrderedWord(String word){
char[] sortedWord = word.toCharArray();
Arrays.sort(sortedWord);
return word.equals(new String(sortedWord));
}
 
public static void main(String[] args) throws IOException{
List<String> orderedWords = new LinkedList<String>();
BufferedReader in = new BufferedReader(new FileReader(args[0]));
while(in.ready()){
String word = in.readLine();
if(isOrderedWord(word)) orderedWords.add(word);
}
in.close();
 
Collections.<String>sort(orderedWords, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return new Integer(o2.length()).compareTo(o1.length());
}
});
 
int maxLen = orderedWords.get(0).length();
for(String word: orderedWords){
if(word.length() == maxLen){
System.out.println(word);
}else{
break;
}
}
}
}

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] JavaScript

Using node.js:

var fs = require('fs'), print = require('sys').print;
fs.readFile('./unixdict.txt', 'ascii', function (err, data) {
var is_ordered = function(word){return word.split('').sort().join('') === word;},
ordered_words = data.split('\n').filter(is_ordered).sort(function(a, b){return a.length - b.length}).reverse(),
longest = [], curr = len = ordered_words[0].length, lcv = 0;
while (curr === len){
longest.push(ordered_words[lcv]);
curr = ordered_words[++lcv].length;
};
print(longest.sort().join(', ') + '\n');
});

Output:

abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty

Alternative version (also using Node.js):

var http = require('http');
 
http.get({
host: 'www.puzzlers.org',
path: '/pub/wordlists/unixdict.txt'
}, function(res) {
var data = '';
res.on('data', function(chunk) {
data += chunk;
});
res.on('end', function() {
var words = data.split('\n');
var max = 0;
var ordered = [];
words.forEach(function(word) {
if (word.split('').sort().join('') != word) return;
if (word.length == max) {
ordered.push(word);
} else if (word.length > max) {
ordered = [word];
max = word.length;
}
});
console.log(ordered.join(', '));
});
});

[edit] K

    w@&d=|/d:#:'w:d@&&/'{~x<y}':'d:0:"unixdict.txt"
("abbott"
"accent"
"accept"
"access"
"accost"
"almost"
"bellow"
"billow"
"biopsy"
"chilly"
"choosy"
"choppy"
"effort"
"floppy"
"glossy"
"knotty")

[edit] Lang5

: >string-index
"" split
"&'0123456789abcdefghijklmnopqrstuvwxyz" "" split
swap index collapse ;
: chars "" split length swap drop ;
: cr "\n" . ;
: nip swap drop ;
: ordered?
dup grade subscript != '+ reduce if 0 else -1 then ;
 
: filtering
[] '_ set
0 do read
2dup chars
<=
if dup >string-index ordered?
if 2dup chars
<
if nip dup chars swap
[] '_ set
then
_ swap append '_ set
'. . # progress dot
else drop
then
else drop
then
eof if break then loop
 
cr _ . cr
 ;
 
: ordered-words
'< 'unixdict.txt open 'fh set
fh fin filtering fh close ;
 
ordered-words
Output:
[ abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty ]


[edit] Lasso

local(f = file('unixdict.txt'), words = array, ordered = array, maxleng = 0)
#f->dowithclose => {
#f->foreachLine => {
#words->insert(#1)
}
}
with w in #words
do => {
local(tosort = #w->asString->values)
#tosort->sort
if(#w->asString == #tosort->join('')) => {
#ordered->insert(#w->asString)
#w->asString->size > #maxleng ? #maxleng = #w->asString->size
}
}
with w in #ordered
where #w->size == #maxleng
do => {^ #w + '\r' ^}
Output:
abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] Liberty BASIC

 
'Ordered wordsFrom Rosetta Code
open "unixdict.txt" for input as #1
'this is not normal DOS/Windows file.
'It LF delimited, not CR LF
'So Line input would not work.
 
lf$=chr$(10)
curLen=0
wordList$=""
while not(eof(#1))
a$=inputto$(#1, lf$)
'now, check word
flag = 1
c$ = left$(a$,1)
for i = 2 to len(a$)
d$ = mid$(a$,i,1)
if c$>d$ then flag=0: exit for
c$=d$
next
'ckecked, proceed if ordered word
if flag then
if curLen=len(a$) then
wordList$=wordList$+" "+a$
else
if curLen<len(a$) then
curLen=len(a$)
wordList$=a$
end if
end if
end if
wend
close #1
print wordList$
 

Output:

abbott 
accent 
accept 
access 
accost 
almost 
bellow 
billow 
biopsy 
chilly 
choosy 
choppy 
effort 
floppy 
glossy 
knotty 

[edit] Lua

fp = io.open( "dictionary.txt" )
 
maxlen = 0
list = {}
 
for w in fp:lines() do
ordered = true
for l = 2, string.len(w) do
if string.byte( w, l-1 ) > string.byte( w, l ) then
ordered = false
break
end
end
if ordered then
if string.len(w) > maxlen then
list = {}
list[1] = w
maxlen = string.len(w)
elseif string.len(w) == maxlen then
list[#list+1] = w
end
end
end
 
for _, w in pairs(list) do
print( w )
end
 
fp:close()

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty


[edit] Mathematica

Module[{max, 
data = Select[Import["http://www.puzzlers.org/pub/wordlists/unixdict.txt", "List"],
OrderedQ[Characters[#]] &]},
max = Max[StringLength /@ data];
Select[data, StringLength[#] == max &]]
 

However Mathematica has built in dictionaries for many languages, so here is a more general version...

maxWords[language_String] :=  Module[{max,data = Select[DictionaryLookup[{language, "*"}],OrderedQ[Characters[#]] &]},
max = Max[StringLength /@ data];
Select[data, StringLength[#] == max &]]
 
findLargestOrderedWord["English"]
{"billowy"}

findLargestOrderedWord["French"]
{"accent", "afflux", "bijoux", "billot", "dehors", "effort"}

findLargestOrderedWord["Spanish"]
{"abenuz", "chillo"}

[edit] MATLAB / Octave

maxlen = 0; 
listlen= 0;
fid = fopen('unixdict.txt','r');
while ~feof(fid)
str = fgetl(fid);
if any(diff(abs(str))<0) continue; end;
 
if length(str)>maxlen,
list = {str};
maxlen = length(str);
elseif length(str)==maxlen,
list{end+1} = str;
end;
end
fclose(fid);
printf('%s\n',list{:});

Returns:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] NetRexx

/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
unixdict = 'unixdict.txt'
do
wmax = Integer.MIN_VALUE
dwords = ArrayList()
inrdr = BufferedReader(FileReader(File(unixdict)))
loop label ln while inrdr.ready
dword = Rexx(inrdr.readLine).strip
if isOrdered(dword) then do
dwords.add(dword)
if dword.length > wmax then
wmax = dword.length
end
end ln
inrdr.close
 
witerator = dwords.listIterator
loop label wd while witerator.hasNext
dword = Rexx witerator.next
if dword.length < wmax then do
witerator.remove
end
end wd
dwords.trimToSize
 
say dwords.toString
 
catch ex = IOException
ex.printStackTrace
end
 
return
 
method isOrdered(dword = String) inheritable static binary returns boolean
wchars = dword.toCharArray
Arrays.sort(wchars)
return dword.equalsIgnoreCase(String(wchars))
 
Output
[abbott, accent, accept, access, accost, almost, bellow, billow, biopsy, chilly, choosy, choppy, effort, floppy, glossy, knotty]

[edit] OCaml

let input_line_opt ic =
try Some(input_line ic)
with End_of_file -> None
 
(* load each line in a list *)
let read_lines ic =
let rec aux acc =
match input_line_opt ic with
| Some line -> aux (line :: acc)
| None -> (List.rev acc)
in
aux []
 
let char_list_of_string str =
let lst = ref [] in
String.iter (fun c -> lst := c :: !lst) str;
(List.rev !lst)
 
let is_ordered word =
let rec aux = function
| c1::c2::tl ->
if c1 <= c2
then aux (c2::tl)
else false
| c::[] -> true
| [] -> true (* should only occur with an empty string *)
in
aux (char_list_of_string word)
 
let longest_words words =
let res, _ =
List.fold_left
(fun (lst, n) word ->
let len = String.length word in
let comp = compare len n in
match lst, comp with
| lst, 0 -> ((word::lst), n) (* len = n *)
| lst, -1 -> (lst, n) (* len < n *)
| _, 1 -> ([word], len) (* len > n *)
| _ -> assert false
)
([""], 0) words
in
(List.rev res)
 
let () =
let ic = open_in "unixdict.txt" in
let words = read_lines ic in
let lower_words = List.map String.lowercase words in
let ordered_words = List.filter is_ordered lower_words in
let longest_ordered_words = longest_words ordered_words in
List.iter print_endline longest_ordered_words

Output:

$ ocaml ordered_words.ml 
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Perl

#!/usr/bin/perl
use strict;
use warnings;
 
open(FH, "<", "unixdict.txt") or die "Can't open file!\n";
my @words;
while (<FH>) {
chomp;
push @{$words[length]}, $_ if $_ eq join("", sort split(//));
}
close FH;
print "@{$words[-1]}\n";
 

Output:

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] Perl 6

Here we assume the dictionary is provided on standard input.

say .value given max :by(*.key), classify *.chars, grep { [le] .comb }, lines;

Output:

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] PicoLisp

(in "unixdict.txt"
(mapc prinl
(maxi '((L) (length (car L)))
(by length group
(filter '((S) (apply <= S))
(make (while (line) (link @))) ) ) ) ) )

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] PL/I

 
order: procedure options (main); /* 24/11/2011 */
declare word character (20) varying;
declare word_list character (20) varying controlled;
declare max_length fixed binary;
declare input file;
 
open file (input) title ('/ORDER.DAT,TYPE(TEXT),RECSIZE(100)');
 
on endfile (input) go to completed_search;
 
max_length = 0;
do forever;
get file (input) edit (word) (L);
if length(word) > max_length then
do;
if in_order(word) then
do;
/* Get rid of any stockpiled shorter words. */
do while (allocation(word_list) > 0);
free word_list;
end;
/* Add the eligible word to the stockpile. */
allocate word_list;
word_list = word;
max_length = length(word);
end;
end;
else if max_length = length(word) then
do; /* we have an eligle word of the same (i.e., maximum) length. */
if in_order(word) then
do; /* Add it to the stockpile. */
allocate word_list;
word_list = word;
end;
end;
end;
completed_search:
put skip list ('There are ' || trim(allocation(word_list)) ||
' eligible words of length ' || trim(length(word)) || ':');
do while (allocation(word_list) > 0);
put skip list (word_list);
free word_list;
end;
 
/* Check that the letters of the word are in non-decreasing order of rank. */
in_order: procedure (word) returns (bit(1));
declare word character (*) varying;
declare i fixed binary;
 
do i = 1 to length(word)-1;
if substr(word, i, 1) > substr(word, i+1, 1) then return ('0'b);
end;
return ('1'b);
end in_order;
end order;
 

OUTPUT:

There are 16 eligible words of length 6: 
knotty 
glossy 
floppy 
effort 
choppy 
choosy 
chilly 
biopsy 
billow 
bellow 
almost 
accost 
access 
accept 
accent 
abbott

[edit] Prolog

Works with SWI-Prolog

:- use_module(library( http/http_open )).
 
ordered_words :-
% we read the URL of the words
http_open('http://www.puzzlers.org/pub/wordlists/unixdict.txt', In, []),
read_file(In, [], Out),
close(In),
 
% we get a list of pairs key-value where key = Length and value = <list-of-its-codes>
% this list must be sorted
msort(Out, MOut),
 
group_pairs_by_key(MOut, POut),
 
% we sorted this list in decreasing order of the length of values
predsort(my_compare, POut, [_N-V | _OutSort]),
maplist(mwritef, V).
 
 
mwritef(V) :-
writef('%s\n', [V]).
 
read_file(In, L, L1) :-
read_line_to_codes(In, W),
( W == end_of_file ->
% the file is read
L1 = L
;
% we sort the list of codes of the line
% and keep only the "goods word"
( msort(W, W) ->
length(W, N), L2 = [N-W | L], (len = 6 -> writef('%s\n', [W]); true)
;
L2 = L
),
 
% and we have the pair Key-Value in the result list
read_file(In, L2, L1)).
 
% predicate for sorting list of pairs Key-Values
% if the lentgh of values is the same
% we sort the keys in alhabetic order
my_compare(R, K1-_V1, K2-_V2) :-
( K1 < K2 -> R = >; K1 > K2 -> R = <; =).
 

Output :

 ?- ordered_words.
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty
true.

[edit] PureBasic

Procedure.s sortLetters(*word.Character, wordLength) ;returns a string with the letters of a word sorted
Protected Dim letters.c(wordLength)
Protected *letAdr = @letters()
 
CopyMemoryString(*word, @*letAdr)
SortArray(letters(), #PB_Sort_Ascending, 0, wordLength - 1)
ProcedureReturn PeekS(@letters(), wordLength)
EndProcedure
 
Structure orderedWord
word.s
length.i
EndStructure
 
Define filename.s = "unixdict.txt", fileNum = 0, word.s
 
If OpenConsole()
NewList orderedWords.orderedWord()
If ReadFile(fileNum, filename)
While Not Eof(fileNum)
word = ReadString(fileNum)
If word = sortLetters(@word, Len(word))
AddElement(orderedWords())
orderedWords()\word = word
orderedWords()\length = Len(word)
EndIf
Wend
EndIf
 
SortStructuredList(orderedWords(), #PB_Sort_Ascending, OffsetOf(orderedWord\word), #PB_Sort_String)
SortStructuredList(orderedWords(), #PB_Sort_Descending, OffsetOf(orderedWord\length), #PB_Sort_integer)
Define maxLength
FirstElement(orderedWords())
maxLength = orderedWords()\length
ForEach orderedWords()
If orderedWords()\length = maxLength
Print(orderedWords()\word + " ")
EndIf
Next
 
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf

Sample output:

abbott  accent  accept  access  accost  almost  bellow  billow  biopsy  chilly
choosy  choppy  effort  floppy  glossy  knotty

[edit] Python

import urllib.request
 
url = 'http://www.puzzlers.org/pub/wordlists/unixdict.txt'
words = urllib.request.urlopen(url).read().decode("utf-8").split()
ordered = [word for word in words if word==''.join(sorted(word))]
maxlen = len(max(ordered, key=len))
maxorderedwords = [word for word in ordered if len(word) == maxlen]
print(' '.join(maxorderedwords))

Alternate Solution

import urllib.request
 
mx, url = 0, 'http://www.puzzlers.org/pub/wordlists/unixdict.txt'
 
for word in urllib.request.urlopen(url).read().decode("utf-8").split():
lenword = len(word)
if lenword >= mx and word==''.join(sorted(word)):
if lenword > mx:
words, mx = [], lenword
words.append(word)
print(' '.join(words))

Sample Output

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

Short local version:

from itertools import groupby
o = (w for w in map(str.strip, open("unixdict.txt")) if sorted(w)==list(w))
print list(next(groupby(sorted(o, key=len, reverse=True), key=len))[1])

[edit] Racket

 
#lang racket
(require net/url)
 
(define dict "http://www.puzzlers.org/pub/wordlists/unixdict.txt")
 
(define (ordered? str)
(define lower (string-downcase str))
(for/and ([i (in-range 1 (string-length str))])
(char<=? (string-ref lower (sub1 i)) (string-ref lower i))))
 
(define words (port->lines (get-pure-port (string->url dict))))
 
(let loop ([len 0] [longs '()] [words words])
(if (null? words)
(for-each displayln (reverse longs))
(let* ([word (car words)] [words (cdr words)]
[wlen (string-length word)])
(if (or (< wlen len) (not (ordered? word)))
(loop len longs words)
(loop wlen (cons word (if (> wlen len) '() longs)) words)))))
 

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] REXX

This problem assumes (or implies) an order of letter case, but fortunately, there're no uppercase letters
in the (default) dictionary to see which programs would fail when not recognizing this distinction.

In ASCII, A is less than a, while in EBCDIC, it's the other way around.
The problem can be avoided by first converting the word to a specific case, and
then test for ordered letters in that word (as indeed, this example does).

Output could be improved by sorting the words listed, but adding a sort would bulk up the program;
but since the word list is already in alphabetical order, this would-be improvement is mostly moot.

/*REXX program lists (longest) ordered words from a supplied dictionary.*/
ifid = 'UNIXDICT.TXT' /*filename of the word dictionary*/
@.= /*placeholder for list of words. */
mL=0 /*maximum length of ordered words*/
call linein ifid,1,0 /*point to the first word in dict*/
/*(above)───in case file is open.*/
do j=1 while lines(ifid)\==0 /*keep reading until exhausted. */
x=linein(ifid); w=length(x) /*get a word and also its length.*/
if w<mL then iterate /*if not long enough, ignore it. */
xU=x; upper xU /*create uppercase version of X.*/
z=left(xU,1) /*now, see if the word is ordered*/
/*handle words of mixed case. */
do k=2 to w; _=substr(xU,k,1) /*process each letter in the word*/
if \datatype(_,'U') then iterate /*Not a letter? Then skip it. */
if _<z then iterate j /*is letter < than the previous ?*/
z=_ /*we have a newer current letter.*/
end /*k*/ /*(above) logic includes ≥ order.*/
 
mL=w /*maybe define a new maximum len.*/
@.w=@.w x /*add orig. word to a word list.*/
end /*j*/
 
q=words(@.mL) /*just a handy-dandy var to have.*/
say q 'word's(q) "found (of length" mL')'; say /*show #words & length*/
do n=1 for q; say word(@.mL,n); end /*list all the words. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────S subroutine────────────────────────*/
s: if arg(1)==1 then return ''; return 's' /*a simple pluralizer.*/

output when using the default supplied word dictionary

16 words found (of length 6)

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Ruby

 
require 'open-uri'
ordered_words = open('http://www.puzzlers.org/pub/wordlists/unixdict.txt', 'r').select do |word|
word.chomp!
word.split( '' ).sort.join == word
end
 
grouped = ordered_words.group_by{ |word| word.size }
puts grouped[grouped.keys.max]
 

Sample Output

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Run BASIC

a$	= httpget$("http://www.puzzlers.org/pub/wordlists/unixdict.txt")
j = 1
i = instr(a$,chr$(10),j)
while i <> 0
a1$ = mid$(a$,j,i-j)
for k = 1 to len(a1$) - 1
if mid$(a1$,k,1) > mid$(a1$,k+1,1) then goto [noWay]
next k
maxL = max(maxL,len(a1$))
if len(a1$) >= maxL then a2$ = a2$ + a1$ + "||"
[noWay]
j = i + 1
i = instr(a$,chr$(10),j)
wend
n = 1
while word$(a2$,n,"||") <> ""
a3$ = word$(a2$,n,"||")
if len(a3$) = maxL then print a3$
n = n + 1
wend
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Rust

// rust 0.9-pre (1b12dca 2013-12-11 12:56:22 -0800)
 
fn is_ordered(s: &str) -> bool {
let mut prev = '\x00';
for c in s.chars() {
if c < prev {
return false;
}
prev = c;
}
 
return true;
}
 
fn find_longest_ordered_words(dict: ~[&str]) -> ~[~str] {
let mut result = ~[];
let mut longest_length = 0;
 
for &s in dict.iter() {
if is_ordered(s) {
let n = s.len();
if n > longest_length {
longest_length = n;
result.truncate(0);
}
if n == longest_length {
result.push(s.to_owned());
}
}
}
 
return result;
}
 
fn main() {
let raw = std::io::File::open(&Path::new("unixdict.txt")).read_to_end();
let lines:~[&str] = std::str::from_utf8(raw).lines_any().collect();
 
let longest_ordered = find_longest_ordered_words(lines);
 
for s in longest_ordered.iter() {
println(s.to_str());
}
}

Sample Output

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Scala

val wordsAll = scala.io.Source.fromURL("http://www.puzzlers.org/pub/wordlists/unixdict.txt").getLines.toSeq
 
/**
* Given a sequence of words return a sub-sequence of the
* words that have characters in sorted order.
*/

def orderedWords( words:Seq[String] ) : Seq[(String)] = {
 
def isOrdered( s:String ) : Boolean =
(s.foldLeft( (true,'@') ){
case ((false,_),_) => return false
case ((true,prev),c) => ((prev <= c),c)
})._1
 
wordsAll.filter( isOrdered(_) ).toSeq
}
 
val ww = orderedWords( wordsAll ).sortBy( -_.length )
 
println( ww.takeWhile( _.length == ww.head.length ).mkString("\n") )
Output:
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Scheme

The following implementation uses a char>=? procedure that accepts an arbitrary number of arguments. This is allowed, but not required, by R5RS, and is provided by many Scheme implementations. It has been tested under GNU Guile 1.8.8.

 
(define sorted-words
(let ((port (open-input-file "unixdict.txt")))
(let loop ((char (read-char port)) (word '()) (result '(())))
(cond
((eof-object? char)
(reverse (map (lambda (word) (apply string word)) result)))
((eq? #\newline char)
(loop (read-char port) '()
(let ((best-length (length (car result))) (word-length (length word)))
(cond
((or (< word-length best-length) (not (apply char>=? word))) result)
((> word-length best-length) (list (reverse word)))
(else (cons (reverse word) result))))))
(else (loop (read-char port) (cons char word) result))))))
 
(map (lambda (x)
(begin
(display x)
(newline)))
sorted-words)
 

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Seed7

$ include "seed7_05.s7i";
 
const func boolean: isOrdered (in string: word) is func
result
var boolean: ordered is TRUE;
local
var integer: index is 0;
begin
for index range 1 to pred(length(word)) do
if word[index] > word[succ(index)] then
ordered := FALSE;
end if;
end for;
end func;
 
const proc: write (in array string: wordList) is func
local
var string: word is "";
begin
for word range wordList do
writeln(word);
end for;
end func;
 
const proc: main is func
local
var file: dictionary is STD_NULL;
var string: word is "";
var integer: length is 0;
var array string: wordList is 0 times "";
begin
dictionary := open("unixdict.txt", "r");
if dictionary <> STD_NULL then
readln(dictionary, word);
while not eof(dictionary) do
if isOrdered(lower(word)) then
if length(word) > length then
length := length(word);
wordList := [] (word);
elsif length(word) = length then
wordList &:= word;
end if;
end if;
readln(dictionary, word);
end while;
close(dictionary);
end if;
write(wordList);
end func;

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Smalltalk

Works with: GNU Smalltalk
|file dict r t|
file := FileStream open: 'unixdict.txt' mode: FileStream read.
dict := Set new.
 
"load the whole dict into the set before, 'filter' later"
[ file atEnd ] whileFalse: [
dict add: (file upTo: Character nl) ].
 
"find those with the sorted letters, and sort them by length"
r := ((dict
select: [ :w | (w asOrderedCollection sort) = (w asOrderedCollection) ] )
asSortedCollection: [:a :b| (a size) > (b size) ] ).
 
"get those that have length = to the max length, and sort alphabetically"
r := (r select: [:w| (w size) = ((r at: 1) size)]) asSortedCollection.
 
r do: [:e| e displayNl].

Output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty


[edit] Tcl

package require http
 
# Pick the ordered words (of maximal length) from a list
proc chooseOrderedWords list {
set len 0
foreach word $list {
# Condition to determine whether a word is ordered; are its characters
# in sorted order?
if {$word eq [join [lsort [split $word ""]] ""]} {
if {[string length $word] > $len} {
set len [string length $word]
set orderedOfMaxLen {}
}
if {[string length $word] == $len} {
lappend orderedOfMaxLen $word
}
}
}
return $orderedOfMaxLen
}
 
# Get the dictionary and print the ordered words from it
set t [http::geturl "http://www.puzzlers.org/pub/wordlists/unixdict.txt"]
puts [chooseOrderedWords [http::data $t]]
http::cleanup $t

Output:

abbott accent accept access accost almost bellow billow biopsy chilly choosy choppy effort floppy glossy knotty

[edit] TUSCRIPT

 
$$ MODE TUSCRIPT
SET data = REQUEST ("http://www.puzzlers.org/pub/wordlists/unixdict.txt")
DICT orderdwords CREATE 99999
COMPILE
LOOP word=data
- "<%" = any token
SET letters=STRINGS (word,":<%:")
SET wordsignatur= ALPHA_SORT (letters)
IF (wordsignatur==letters) THEN
SET wordlength=LENGTH (word)
DICT orderdwords ADD/COUNT word,num,cnt,wordlength
ENDIF
ENDLOOP
 
DICT orderdwords UNLOAD words,num,cnt,wordlength
SET maxlength=MAX_LENGTH (words)
SET rtable=QUOTES (maxlength)
BUILD R_TABLE maxlength = rtable
SET index=FILTER_INDEX (wordlength,maxlength,-)
SET longestwords=SELECT (words,#index)
PRINT num," ordered words - max length is ",maxlength,":"
 
LOOP n,w=longestwords
SET n=CONCAT (n,"."), n=CENTER(n,4)
PRINT n,w
ENDLOOP
ENDCOMPILE
 

Output:

422 ordered words - max length is 6:
 1. abbott
 2. accent
 3. accept
 4. access
 5. accost
 6. almost
 7. bellow
 8. billow
 9. biopsy
10. chilly
11. choosy
12. choppy
13. effort
14. floppy
15. glossy
16. knotty 

[edit] Ursala

#import std
 
#show+
 
main = leql@bh$^ eql|= (ordered lleq)*~ unixdict_dot_txt
  • leql is a binary predicate testing a pair of lists for less or equal length
  • eql tests for equal length
  • lleq tests for lexically less or equal relatedness between characters or strings
  • ordered takes a binary predicate to a predicate operating on a list, which tests whether every pair of consecutive items is related by the binary predicate
  • postfix operator *~ turns a predicate into a list filtering function, deleting any item not satisfying it
  • postfix operator |= turns an equivalance relational predicate into function that partitions a list into a list of equivalence classes
  • postfix operator $^ turns a predicate into a function that searches a list for the maximum member with respect to it
  • postfix operator @bh makes its operand function apply to the pair of heads of a pair of lists
  • loading a file unixdict.txt into a list of strings is implied by using its name as an identifier and supplying it to the compiler in a command line parameter

output:

abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] VBA

 
Public Sub orderedwords(fname As String)
' find ordered words in dict file that have the longest word length
' fname is the name of the input file
' the words are printed in the immediate window
' this subroutine uses boolean function IsOrdered
 
Dim word As String 'word to be tested
Dim l As Integer 'length of word
Dim wordlength As Integer 'current longest word length
Dim orderedword() As String 'dynamic array holding the ordered words with the current longest word length
Dim wordsfound As Integer 'length of the array orderedword()
 
On Error GoTo NotFound 'catch incorrect/missing file name
Open fname For Input As #1
On Error GoTo 0
 
'initialize
wordsfound = 0
wordlength = 0
 
'process file line per line
While Not EOF(1)
Line Input #1, word
If IsOrdered(word) Then 'found one, is it equal to or longer than current word length?
l = Len(word)
If l >= wordlength Then 'yes, so add to list or start a new list
If l > wordlength Then 'it's longer, we must start a new list
wordsfound = 1
wordlength = l
Else 'equal length, increase the list size
wordsfound = wordsfound + 1
End If
'add the word to the list
ReDim Preserve orderedword(wordsfound)
orderedword(wordsfound) = word
End If
End If
Wend
Close #1
 
'print the list
Debug.Print "Found"; wordsfound; "ordered words of length"; wordlength
For i = 1 To wordsfound
Debug.Print orderedword(i)
Next
Exit Sub
 
NotFound:
debug.print "Error: Cannot find or open file """ & fname & """!"
End Sub
 
 
 
Public Function IsOrdered(someWord As String) As Boolean
'true if letters in word are in ascending (ascii) sequence
 
Dim l As Integer 'length of someWord
Dim wordLcase As String 'the word in lower case
Dim ascStart As Integer 'ascii code of first char
Dim asc2 As Integer 'ascii code of next char
 
wordLcase = LCase(someWord) 'convert to lower case
l = Len(someWord)
IsOrdered = True
If l > 0 Then 'this skips empty string - it is considered ordered...
ascStart = Asc(Left$(wordLcase, 1))
For i = 2 To l
asc2 = Asc(Mid$(wordLcase, i, 1))
If asc2 < ascStart Then 'failure!
IsOrdered = False
Exit Function
End If
ascStart = asc2
Next i
End If
End Function
 

Results:

OrderedWords("unixdict.txt")
Found 16 ordered words of length 6 
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty

[edit] Vedit macro language

File_Open("unixdict.txt", BROWSE)
#1 = 2 // length of longest word found
Repeat (ALL) {
#2 = EOL_Pos-Cur_Pos // length of this word
if (#2 >= #1) {
#3 = 1 // flag: is ordered word
Char(1)
While (!At_EOL) {
if (Cur_Char < Cur_Char(-1)) {
#3 = 0 // not an ordered word
break
}
Char(1)
}
if (#3) { // ordered word found
if (#2 > #1) { // new longer word found
#1 = #2
Reg_Empty(10) // clear list
}
BOL Reg_Copy(10,1,APPEND) // add word to list
}
}
Line(1,ERRBREAK) // next word
}
Buf_Quit(OK) // close file
Reg_Type(10) // display results
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty 

[edit] zkl

One pass, dictionary stays on disk:

var words=L(), sz=0;  // some state
fcn isLex(word){word.reduce(fcn(p,c){(p<=c) and c or T(Void.Stop,False)})}
File("dict.txt").pump(Void,fcn(w){
w=w.strip(); // get rid of newline
if(isLex(w)){n:=w.len(); if(n>sz) {words.clear(w); sz=n}
else if(n==sz) words.append(w)}
})
println("Num words: %d, all size %d\n".fmt(words.len(),sz));
words.pump(Console.println);

Or, reading dictionary into memory:

fcn isLex(word){word.reduce(fcn(p,c){(p<=c) and c or T(Void.Stop,False)})}
lwords:=File("dict.txt").readln(*).apply("strip").filter(isLex);
max:=lwords.reduce(fcn(n,w){w.len()>n and w.len() or n},0);
lwords=lwords.filter(fcn(w,n){w.len()==n},max);
println("Num words: %d, all size %d\n".fmt(lwords.len(),max));
words.pump(Console.println);
Output:
Num words: 16, all size 6
abbott
accent
accept
access
accost
almost
bellow
billow
biopsy
chilly
choosy
choppy
effort
floppy
glossy
knotty
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox