Self Describing Sentences

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math topics]   [Library]   [Utilities]




Search WWW


As of October, 2016, Embarcadero is offering a free release of Delphi (Delphi 10.1 Berlin Starter Edition ).     There are a few restrictions, but it is a welcome step toward making more programmers aware of the joys of Delphi.  They do say "Offer may be withdrawn at any time", so don't delay if you want to check it out.  Please use the feedback link to let me know if the link stops working.


Support DFF - Shop

 If you shop at Amazon anyway,  consider using this link. 


We receive a few cents from each purchase.  Thanks


Support DFF - Donate

 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.

Mensa Daily Puzzlers

For over 15 years Mensa Page-A-Day calendars have provided several puzzles a year for my programming pleasure.  Coding "solvers" is most fun, but many programs also allow user solving, convenient for "fill in the blanks" type.  Below are Amazon  links to the two most recent years.

Mensa 365 Puzzlers  Calendar 2017

Mensa 365 Puzzlers Calendar 2018

(Hint: If you can wait, current year calendars are usually on sale in January.)


Feedback:  Send an e-mail with your comments about this program (or anything else).

Search only




Problem Description

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.

Programmer's Notes:

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:

bulletMaking 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 NumberWords.
bulletIdentifying the letters to be counted:  Even though I specified ___ A's as the format for the letters to be counted, 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.   
bulletHandling vowels to be counted:  Vowels represent a set of letters rather than  single letter so that checking must be handled with special processing.  
bulletSetting 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 fields Letter (the letter being counted), InCount, (the count of that letter found in the original input text), and  Position (position of the underscore characters in the original text where the proper number word will be inserted when a solution is found).

 A 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 records.    

bulletGenerating 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.  
bulletChecking 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[0].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.


June 21, 2014:  Version 2.2 posted today adds a few extra examples of self-describing sentences or "Autograms" as Wikipedia calls them.   I also added some run statistics and the ability to interrupt long running cases.  Got to run.  We're off to Kitty Hawk and the beach today to spend a few days with daughter and family.

October 28, 2015:  This October 25th Mensa Calendar Puzzle  was solvable by the previous version of the program, but while playing with it I decided that counting "Consonants" as well as letters and "Vowels" would be and interesting exercise.  It was.  Version 2.3 posted today does that.  The short description of the exercise is that it was a mistake earlier to put the vowel counting record in the first record that track's location.  Adding a second out-of-order record for Consonants was too tough for me to crack until I went to plan B.  Search "Plan B" in the source code for details.         


Running/Exploring the Program 

bullet Download source
bulletDownload  executable

Suggestions for Further Explorations

Correct grammar to eliminate the 's for singular letter counts (e.g. "contains 1 A" instead of "contains "1 A's")
Create a "Pangram", sentence with all 26 letters counted.  Not an easy task!.


Original:  September 6, 2010

Modified:  May 15, 2018

  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2018, Gary Darby    All rights reserved.