What can I add to complete this search term?
Even-length words of known length, using length 6 as an example:
Odd-length words of known length, using length 7 as an example:
First, I'll reason through how to do this for even-length words. It's simpler to think about, and odd-length words are just a little extension at the end.
If we want to exclude palindromes we're going to have to leverage the "difference constraint" tool:
A difference constraint consists of an exclamation mark followed by an equals sign, followed by a sequence of variables. All these variables are constrained to have values different from one another.
Note the word "variables". The moment a tilde
~ is used to reverse something, you've created a compound pattern, which is different. This difference constraint part of the system must look like this:
What do we want to be different? The start and end of the should-not-be-a-palindrome. Specifically, the first half should not match the reverse of the second half. Without losing any generality, let's have A be the first half and B the reverse of the second half. One of the words in the system will be
A~B. The other, or the reverse of the first word, will be
B~A. Now the system looks like:
You may have noticed it seems we're right back to the original problem... palindromes are showing up in the list! This is because though we required the two halves of the word to not equal each other, we did not require the halves to be halves, at least not in the sense of "half the length". Therefore things like
b·ob / bo·b
d·eed / dee·d got through. To force halves to be halves, we need to constrain their lengths. Let's look at how to do that:
A length constraint consists of a sequence of variables bounded on both sides by vertical bar characters
|, followed by an equals sign, followed by a length specification as described under ‘Qualified patterns’ above (without the colon).
The section it's referring to says:
A pattern can be further qualified by prepending a length specification. This can be:
- a number followed by a colon, which allows only matches of that length, or
- a number followed by a hyphen and a colon, which allows only matches of at least that length, or
- a hyphen followed by a number and a colon, which allows only matches of at most that length, or
- a number followed by a hyphen, another number and a colon, which allows only matches in the specified range of lengths.
Note that none of these allow for any sort of variables for the length. To force two lengths to be the same, we'll need to force them to both be equal to the same constant, as opposed to having them be equal to each other or both equal to some variable. Arbitrarily, let's make the word be of length 6, which means each half should be of length 3. The system now is:
Almost there. Each pair of words is coming up twice in the results, as the values of
B swap to form another legal solution. To fix this we'll leverage another part of the "difference constraints" section:
If a ‘less than’ symbol appears between two of the variables, the variable to its left is constrained to be ‘less than’ the variable to its right; and likewise, mutatis mutandis, for the ‘greater than’ symbol.
> symbol will make it so only one assignment (of two strings to
B respectively) is a legal solution. Arbitrarily picking
Now to extend this pattern to work with odd-length words. To prevent palindromes here, it is sufficient to only look at the sections on either side of the central letter. The central letter of an odd-length word will always palindromically match itself anyways.
Most of the structure from the even-length word finder can stay. We just need to insert a letter into the middle of both
B~A. However, we can't use
. or its cousins which match any number of letters, because the central letter must be the same between both words. Introduce a new length-1 variable
C and sneak it in between the halves:
A very similar pattern can be used to find even-length words. Adapt by forcing
C to be of length 0 instead. This is equivalent to having
C not be present at all, as in the previous even-length word finder-pattern.
Here's a different way to find all words that form a (possibly identical) word when reversed:
Look, it even makes a cute face!
>matches a (multi-letter) word
&is a logical AND
<matches the reverse of a (multi-letter) word
Here's a way to remove the palindromes:
&is another logical AND
)enclose a group
0*1matches a word with different initial and final letters
0matches a letter
*matches a (possibly empty) string
1matches a letter different from
|is a logical OR
.0*1.matches a word with different second and penultimate letters
.matches a letter (the two
.s can be different, although it does not matter here)
..0*1..matches a word with different third and antepenultimate letters
...0*1...matches a word with different fourth and preantepenultimate letters
Ultimately, this restricts the list to words that differ in two letters that are the same distance from either end, i.e., non-palindromic words. Observe that, barring further extension, it would fail to include a non-palindromic word that differed only in its fifth and propreantepenultimate letters, e.g., aaaabcaaaa. However, the longest words found are less than 10 letters long, so this suffices.