text – Conversion of the (telephone) number into a short phrase in English

One way of storing phone numbers is to convert the number into a simple phrase in natural language (English, for example), so that when composing on a keyboard, typing that word or phrase. Here are the conversions, taken from a standard phone keypad:

subs1 = {2 -> {"a", "b", "c"},
3 -> {"d", "e", "f"},
4 -> {"g", "h", "i"},
5 -> {"j", "k", "l"},
6 -> {"m", "n", "o"},
7 -> {"p", "q", "r", "s"},
8 -> {"t", "u", "v"},
9 -> {"w", "x", "y", "z"}};

(We will come back to the question of 0 and 1.)

Thus, the phone number (seven digits) 3987228 would be converted into "extract", that the user simply type in the phone, guided by the letters of the keyboard. (Note that, of course, a given number may have several valid matching words: 228 could be converted to "act", "bat" or "cat".)

Here is a simple code that finds valid (single) English words corresponding to a number (here 228):

To select[StringJoin /@ Tuples[IntegerDigits[228] /. subs1], DictionaryWordQ]

(*
{"act", "bat", "cat"}
*)

Also:

To select[StringJoin /@ Tuples[IntegerDigits[5865] /. submarines], DictionaryWordQ]

(* {"waste"} *)

The overall problem becomes a bit more complicated for two reasons. First, you have to deal with the numbers 0 and 1, which do not have the corresponding letters on a keyboard. Secondly, a full 10-digit phone number rarely unique corresponding word. The above code must be modified to find sets or phrases of valid English words (of any length) corresponding to the length of the number. (The semantic meaning of the sentence is irrelevant.) In addition, there are some heuristics, such as 0 can be read as "oh", 1 can be read as "a", etc.

So the phone number 2427793647 could be rendered as "2 happy dogs" (or, given the substitutions below, "two happy dogs" and the user knows how to squeeze $ 2 $ rather than specifying "t w o").

Here is a broader set of substitutions that capture some of these ideas.

subs = = 0 -> {"o"},
1 -> {"i", "a"},
2 -> {"a", "b", "c", "two", "also"},
3 -> {"d", "e", "f"},
4 -> {"g", "h", "i", "for"},
5 -> {"j", "k", "l"},
6 -> {"m", "n", "o"},
7 -> {"p", "q", "r", "s"},
8 -> {"t", "u", "v"},
9 -> {"w", "x", "y", "z"}};

Which modification of the code above would take an arbitrary number of 10 digits
telephone and generate a sentence in English (from any number of
word / components) that could be used to memorize this number?

We will surely want to use a text for different divisions of strings. For example:

testphrases = {"catdog", "longit", "hotbag"};

To select[testphrases, AllTrue[StringPartition[#, 3], DictionaryWordQ]&]

(*
{"catdog", "hotbag"}
*)

This just tests two valid words generated by splitting the source string after the third character. We must check all division positions and more simultaneous division positions (giving three or four components or more).