If you shop at Amazon anyway, consider using this
link. We receive a few cents from each purchase. Thanks.
If you benefit from the website, in terms of
knowledge, entertainment value, or something otherwise useful,
consider making a donation via PayPal to help defray the
costs. (No PayPal account necessary to donate via credit
card.) Transaction is secure.
Send an e-mail with your
comments about this program (or anything else).
Needed: a program to fill in the blanks of a "self-describing" sentence to
make it true. Sentences are of the form ".... ____ X's,
... ____ Y's, .... ____ Z's, .... and ____ vowels., " The underscore
areas must be filled with number words from "one" to "ninety-nine" (one,
five, thirteen, twenty-seven, etc.) to make the sentence true.
Background & Techniques
This is another puzzle type from my Mensa "Puzzle-A-Day" calendar. The
example included with this program is the same as theirs except
they displayed the sentence inside of a nine-sided polygon (a nonagon). I
replaced the word "nonagon" with "sentence" which reduces
the number of solution to two from the the "nonagon" version. The general structure specifies a set of letters
to count and optionally to also count the vowels. the tricky part is that
filling in the number-words for the counts, generally changes the counts!
As far as I can figure, the only way to solve this puzzle is to choose a set
of candidate number words and then check to see if they meet the sentence
conditions. For example "Here are ____ A's and ____E's." has "three"
A's and "four" E's until we fill in the word "three", then it has "six" E's.
In practice, choosing any word number can affect the correct answer for that
letter or any other letter in the set to be searched. Changing any number word
will certainly change the number of vowels in the sentence.
You can override the supplied sentence with your own text. The letters
to be searched are identified by at least two underscore characters followed by
one or more spaces, the letter to be counted and an 's,
for example ___ A's.
I have defined number words from "one" to "one hundred
ninety-nine". Above that (probably vowels) the program will gracefully
give up the search.
Non-programmers are welcome to read on, but may want to jump to bottom of
this page to download the executable program now.
Even though it's difficult to see how break the given problem into parts, the
problem of coding the search can be (and was) broken into sub-problems:
|Making the "number words": I originally defined an array,
First20, of the number names from 0 ("zero) to 20 ("twenty").
In version 2, I expanded that to 99 and then to 199. by adding a Decades
array of the names "twenty" through "ninety". Those words plus a
hyphen and entries 1 through 9 from First20 and enough to generate
names "twenty-one" through "ninety-nine". Then is was easy to prefix
the names with "one hundred" to generate entries up through "one hundred
ninety-nine". These are saved in a string array
|Identifying the letters to be counted: Even though I
specified ___ A's as the format for the
letters to be counter, I found in testing that it was good to handle
variations with no or multiple space characters between the underscore and
the letter. accepting ___'A's, etc. I
search for any 's letter pair and try to
identify a letter preceding that point. |
|Handling vowels to be counted: Vowels represent a set of
letters rather than single letter so that checking must be handled
with special processing. |
|Setting up the data structure: A Letters array of
TLetterrec records has an entry for each letter to be counted plus entry
0 reserved for the vowel count statistics. Each record has the Letter
being counter, the count of that letter found in the original input text (inCount)
and the Position of the underscore characters in the original text
where the proper number word will be inserted when a solution is found.|
second record type, Testrec, is passed in a TestWords array to
our checking routine and contains an entry for each letter in the Letters
array but it contains the current word being tested for that letter,
Testword, its numeric value, TestValue, which the
target value if this is to be a solution, and TestCount,
the current count for that letter including the contribution to this letter
count from the TestWord entries in all of the Testwords
|Generating sets of potential solutions: Recursive procedure
Checknext is given letter to test. It tests for each plausible
count for that letter starting with the input count for that letter in the
original text. For each guess, it calls itself asking for the next
letter. On entry, CheckNext tests if all of the letters values
have been filled and if so, checks for a solution. |
|Checking whether a trial solution set is a solution:
Checking for a solution is relatively simple. First we run through all
of the TestWord guesses updating TestCount values.
If vowels are being counted , we'll also run through each TestWord
and update the Testwords.TestCount entry with the number of
vowels found. When done, if all of the Testword records
have TestCount values equal to the corresponding TestValue
entries, we have a solution. Plugging the solution back into the
original text takes a bit more fiddling, but the hard part is over. |
April 23,2011: A fix was applied today to create Version
2.1 which fixes a problem that showed up when I tried to solve this "Easter Egg"
puzzle. I added that puzzle to the program, just for the heck of it.
Running/Exploring the Program
Suggestions for Further Explorations
|Original: September 6, 2010
April 23, 2011