In honor of recent news of Google developing a keyboard for iPhone...
Your input (for simplicity, all input is case sensitive):
Location of standard dictionary file. File format is 1 valid word per line; in alphabetical order. Example file:
apple banana citrus domino durian orange tuna zabc
Location of personal dictionary file (initially, may be empty or non-existant). Format is 1 word per line, comma separated by count of times that word was used. Example file:
Stackoverflow,15 StackExchange,11 Meta,13 TFGITW,2 VTC,10
A stream of words on standard input (for simplicity, newline separated), in the following format on each line: "Typed_word,intended_word".
You need to emulate a predictive keyboard, as follows. For every line in the stream of words:
- Process the typed word character by character
After 3rd character, generate the 5 most-used words that start with the currently-seen substring
"5" is a hard-coded constant, but my example below uses "2" for simplicity. "most-used" are picked as first words when words are sorted in the order of counting; alphabetic order within same counts.
The rules for most-used words are: the word from the standard dictionary is assumed to have the used count of 20 (that's a hard-coded constant, but my example below uses "2" for simplicity). The word from personal dictionary has a used count of whatever number the dictionary file has.
If one of 5 words matches intended word, print the success: "MATCH:$substring,$intended_word" and stop
- If typed word is finished and matches intended_word, print it: "FULLWORD:$typed_word,$intended_word" and stop
- If typed word is finished, but none of teh matches or the word match intended_word, print ERROR message including both typed and intended word: "MISMATCH:$typed_word,$intended_word"
- Add the intended word to the personal dictionary if missing from it; or increment its usage count in personal dictionary if already present
Answers should be genuine working code - no gotchas/loopholes, no edge cases like super-small input.
SAMPLE RUN
(I'm going to change the constants to 2 guesses (instead of 5) and main dictionary words weigh as 2 user-usages instead of 20)
Standard Dictionary:
abacus
abacii
abandon
abandoned
abandonment
User dictionary
EMPTY
INPUT
abanana,abanana
abanana,abanana
abanana,abanana
abandonmint,abandonment
cat,cad
OUTPUT
FULLWORD:abanana,abanana #after this, add "abanana,1" to custom dictionary
MATCH:abana,abanana
# NOTE: your code should have matched "abandon,abandoned" till seeing "abana"
# change custom dict count for abanana to 2
MATCH:aban,abanana #By now, aban matches "abanana,abandon"
MATCH:abandonm,abandonment
MISMATCH:cat,cad # Add cad to custom dictionary
NOTE: someone asked to be able to live with no files. I'm fine with that, the simplest spec seems to be to pass all 3 inputs on STDIN, separated by empty line between the inputs.