9

An autogram is a sentence which describes its letters. For example, from Wikipedia:

This sentence employs two a’s, two c’s, two d’s, twenty-eight e’s, five f’s, three g’s, eight h’s, eleven i’s, three l’s, two m’s, thirteen n’s, nine o’s, two p’s, five r’s, twenty-five s’s, twenty-three t’s, six v’s, ten w’s, two x’s, five y’s, and one z.

These sentences are extremely difficult to create by hand, so surely a computer is best suited for the task, but how can this be done efficiently? What is an efficient algorithm for finding autograms with a given initial string? What about linked autograms, where the previous sentence describes the contents of the next? While this thread is about the same topic, it merely asks for existence, and all of the algorithms described there are much too slow in practice.

A naive approach would be to search through the sets of possible number combinations from, say, 0 to 40, for a possible solution. However, with 40^26 possibilities, this would take impossibly long.

We could improve our search, at the possible expense of missing a solution, by starting with some initial guess at the letter combinations, then searching only for autograms that deviate from our guess by 3 on either side. This still would take 6^26 times. Even at a million checks per second, this would take more than 5 million years to finish.

A further refinement comes from recognizing that a, b, c, d, j, k, m, p, q, and z never appear in any number-words, so those ten letters have their counts fixed by the initial string. We now have a mere 3 trillion combinations - still not great.

It might be better to start with an initial guess and...

  1. Create a new "autogram" which describes the letter counts of the previous autogram
  2. Check if we have repeated an autogram yet. If we have, and the loop is length 1, we are done. Otherwise, slightly modify the guess and go to step 1.

...but this has its fair share of limitations. Despite the seeming fruitlessness of this task, other people have found success. In fact, http://autograms.net/ even has a chain of twenty-five linked autograms. How?

Community
  • 1
  • 1
  • Cool! but whats the question? – R Nar Nov 17 '15 at 22:12
  • @RNar How can a computer efficiently generate autograms? Everything I've come up with takes an absurdly long time. –  Nov 17 '15 at 22:18
  • Sorry. While interesting, this is a [duplicate](http://stackoverflow.com/questions/23980436), and also too broad and abstract for Stack Overflow. It will almost certainly be closed. I suggest you [take the tour](http://stackoverflow.com/tour), then read about [what's on-topic](http://stackoverflow.com/help/on-topic) and [things to avoid](http://stackoverflow.com/help/dont-ask). – Tom Zych Nov 17 '15 at 23:15
  • @TomZych I saw that thread before posting this one, but I thought this wouldn't be a duplicate because that one asked for existence, rather than execution. –  Nov 17 '15 at 23:17
  • True. I only skimmed it. The other objection still stands, though, as do my suggestions. – Tom Zych Nov 17 '15 at 23:20
  • 4
    @TomZych I agree with you that the general sentiment will be that this is too broad, however I, for one, welcome this question on SO and hope it will not be closed. MTyler, while we're making suggestions, I would suggest that you write this up as a challenge and post it on [Code Golf](http://codegolf.stackexchange.com/). It would be interesting to see what folks come up with. – beaker Nov 17 '15 at 23:27
  • This may well be a very good question over on the [Programming Puzzles & Code Golf](//codegolf.stackexchange.com) StackExchange site. It's not just for Code Golf! – Toby Speight Dec 07 '15 at 14:57

2 Answers2

0

An efficient way to do this is by replacing the phrase with a phrase describing the previous phrase until they are the same, i.e. the phrase is an autogram. But it may not work in a lot of cases.

Labo
  • 2,482
  • 2
  • 18
  • 38
  • That was the algorithm I described at the bottom of the question, but it has a few problems. For instance, the cycle length will rarely be 1, and it's difficult to figure out if the next autogram attempted was somewhere in the chain generated by a prior guess. –  Nov 17 '15 at 22:36
  • 1
    For that you can use the tortoise and hare algorithm : https://en.wikipedia.org/wiki/Cycle_detection#Algorithms – Labo Nov 17 '15 at 22:40
  • Right, but what if the cycle length isn't 1? Then, we will need to start with a new guess and a new cycle, but there is no easy way of knowing if these lead to the same cycle. –  Nov 17 '15 at 22:45
  • The cycle length may be 18 or 42, just regenerate random values and repeat the iterations. It is NOT a deterministic method, but it works. – Labo Nov 17 '15 at 22:47
0

I would approach this as an integer constraint programming problem. Define your sentence structure like below:

This sentence has [countA] 'a'[s], [countB] 'b'[s], ... and [countZ] 'z'[s].

I've included all 26 letters, but if e.g. countB is zero as in your example from Wikipedia, then we can just omit that letter (and its count) from the sentence entirely; or alternatively you can make it say "zero 'b's", for example.

Now we can count the number of letters that will actually be used, and write some constraints:

  • The letter 'a' occurs twice in the structure ("has", "and"), once if countA > 0 (which it must), and does not occur in any number words.
  • The letter 'b' does not occur in any number words, so it occurs only once if countB > 0.
  • ...
  • The letter 'e' occurs three times in the structure ("sentence"), once if countE > 0 (which it must), and:
    • Once for each count variable equal to 1 ("one"), 5 ("five"), 8 ("eight"), 9 ("nine"), 10 ("ten"), ...
    • Twice for each count variable equal to 3 ("three"), 7 ("seven"), 12 ("twelve"), ...
    • Three times for each count variable equal to 11 ("eleven"), ...
    • ...
  • ...

These constraints are a bit complicated, but they can be formulated using a constraint programming framework like Z3. Some of the constraints can be directly simplified by hand (e.g. countA must equal 3, countB must equal 0 or 1), but it is not really necessary to do this, since a good constraint solver will do it automatically anyway.

kaya3
  • 47,440
  • 4
  • 68
  • 97