Crossword

by Adam Renak: L6 Age ~16

Introduction

This program checks to see if a word supplied by the user is in its dictionary. If a question mark (a wildcard) is used to represent each unknown letter, the program outputs all the possible words matching the pattern. For example, the input sla?e generates slake, slate and slave as matching words. In cases for which no possible matches are found, nearly matching words with different endings are offered. This could be helpful in the event of certain mistakes by the user.

The program puts all words of the same length as the target word into an array. It then uses the first part of this array to hold all words of the correct length that have the same first letter as the target word. This procedure is repeated for the second and subsequent letters so that finally the first part of the array contains only the matching words required. (If the target character is a wildcard then comparisons are not performed). Think about the significance of the words that remain in the array immediately after the matching words.

The program reads data from a file named DictWordlist.txt which you will need to download and save in the same directory as the program file. (See Special Notes, below.)

The dictionary, taken from the Sun example dictionary file at (http://java.sun.com/docs/books/tutorial/collections/interfaces/examples/dictionary.txt) is intended for (Java) programmers. You can easily replace the existing text file with one to suit your needs. Make sure that its name is the same as that in the program (DictWordlist.txt). There are extensive dictionaries in a compressed file downloadable from http://icon.shef.ac.uk/Moby/mwords.html.

The Program

program Crossword;
{$APPTYPE CONSOLE}

{
    Copyright (c) 2010 Adam Renak

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/

}

uses
  SysUtils;
const
  ListLength = 213563;
var
  Words: array[1..ListLength] of string;
  NarrowWords: array[1..100000] of string;
  Count1, Count2, CharPosn, writecount, NarrowFactor: integer;
  input: string;

Procedure LoadWordlist;
var
  Wordlist: textfile;
  Count: integer;
begin
  AssignFile(Wordlist, 'DictWordList.txt');
  Reset(Wordlist);
  Count := 1;
  while not eof(Wordlist) do
    begin
      readln(Wordlist, Words[count]);
      inc(count);
    end;
  CloseFile(Wordlist);
end;

Procedure NarrowLength; //Narrows the wordlist down to words of similar length
begin
  Count2 := 0;
  for Count1 := 1 to ListLength do
    begin
      if length(input) = length(words[count1]) then
        begin
          inc(count2);
          Narrowwords[count2] := words[count1];
          Narrowfactor := count2;
        end;
    end;
end;

Procedure Narrow(vWord: string; position: integer); //Narrows list according to character position.
var
  NarrowPos, InsertCount : integer;
begin
  InsertCount := 0 ; //Sets the pointer that the new narrowlist begins at
  for NarrowPos := 1 to Narrowfactor do //From 1 to the current number of narrowed words
    if (vWord[position] = narrowwords[NarrowPos][position]) then
      begin
        Inc(InsertCount);
        NarrowWords[InsertCount] := Narrowwords[NarrowPos];
      end;
   Narrowfactor := InsertCount //Reduces the Narrowfactor
end;

begin
  Loadwordlist;
  repeat
    writeln('Input the word to solve. Use ? to show unknowns:');
    readln(input);
    input := lowercase(input); //Makes the input lower case
    Narrowlength;

    for CharPosn := 1 to length(input) do
      if input[CharPosn] <> '?' then
        Narrow(input, CharPosn);

    //writes a list of matching words:
    writeln('--------------------------------------');
    for WriteCount := 1 to (Narrowfactor) do  // Writes out the possible words
      writeln('MATCH: ', NarrowWords[writecount]);

    //If no match is found, it writes the five closest matches.
    if Narrowfactor = 0 then
      begin
        writeln('No match found. Try these suggestions:', #13#10);
        for WriteCount := (Narrowfactor + 1) to (Narrowfactor + 6) do  //Writes out the possible words
          writeln(NarrowWords[writecount]);
      end;
    writeln('--------------------------------------', #13#10);
    sleep(1000);
  until input = 'end';

end.

Special Notes

This program requires a data file. (How can you tell by looking at the program that a file is required?)

Here is a link to a file that you can use with the program. Download it and place it in the same directory as the program, before running the program. (Or try running the program without it and see what happens).

Download data file DictWordlist.txt required by the program. The next page shows a version of Crossword that includes the text file in the Windows executable, which you can download and use. The third version of Crossword is written in the Oxygene for Java dialect of Pascal and the fourth is a Smart Pascal console program that you can use online.

Remarks

Can you think of a search program that you could write?

Programming - a skill for life!

Student programs to inspire you!