patterncMinor
Mimicking T9 cell messaging
Viewed 0 times
cellmimickingmessaging
Problem
Today I solved a question from Google Code Jam: mimicking a cell phone keypad messaging.
Here is the program, with
```
#include
int main()
{
char c, c1 = NULL;
int top;
top:
while((c = getchar()) != '\n')
{
if (c == ' ')printf("0");
if(c == 'a' || c == 'b' || c == 'c')
{
if(c1 == 'a' || c1 == 'b' || c1 == 'c')
printf(" ");
if(c == 'a') printf("2");
if(c == 'b') printf("22");
if(c == 'c') printf("222");
c1 = c;
goto top;
}
if(c == 'd' || c == 'e' || c == 'f')
{
if(c1 == 'd' || c1 == 'e' || c1 == 'f')
printf(" ");
if(c == 'd') printf("3");
if(c == 'e') printf("33");
if(c == 'f') printf("333");
c1 = c;
goto top;
}
if(c == 'g' || c == 'h' || c == 'i')
{
if(c1 == 'g' || c1 == 'h' || c1 == 'i')
printf(" ");
if(c == 'g') printf("4");
if(c == 'h') printf("44");
if(c == 'i') printf("444");
c1 = c;
goto top;
}
if(c == 'j' || c == 'k' || c == 'l')
{
if(c1 == 'j' || c1 == 'k' || c1 == 'l')
printf(" ");
if(c == 'j') printf("5");
if(c == 'k') printf("55");
if(c == 'l') printf("555");
c1 = c;
goto top;
}
if(c == 'm' || c == 'n' || c == 'o')
{
if(c1 == 'm' || c1 == 'n' || c1 == 'o')
printf(" ");
if(c == 'm') printf("6");
if(c == 'n') printf("66");
if(c == 'o') printf("666");
c1 = c;
goto top;
}
if(c == 'p' || c == 'q' || c == 'r' || c == 's')
{
if(c1 == 'p' || c1 == 'q' || c1 == 'r' || c1 == 's')
Here is the program, with
goto statements. I know it is an unstructured style to use goto, but I still did because it improved speed.```
#include
int main()
{
char c, c1 = NULL;
int top;
top:
while((c = getchar()) != '\n')
{
if (c == ' ')printf("0");
if(c == 'a' || c == 'b' || c == 'c')
{
if(c1 == 'a' || c1 == 'b' || c1 == 'c')
printf(" ");
if(c == 'a') printf("2");
if(c == 'b') printf("22");
if(c == 'c') printf("222");
c1 = c;
goto top;
}
if(c == 'd' || c == 'e' || c == 'f')
{
if(c1 == 'd' || c1 == 'e' || c1 == 'f')
printf(" ");
if(c == 'd') printf("3");
if(c == 'e') printf("33");
if(c == 'f') printf("333");
c1 = c;
goto top;
}
if(c == 'g' || c == 'h' || c == 'i')
{
if(c1 == 'g' || c1 == 'h' || c1 == 'i')
printf(" ");
if(c == 'g') printf("4");
if(c == 'h') printf("44");
if(c == 'i') printf("444");
c1 = c;
goto top;
}
if(c == 'j' || c == 'k' || c == 'l')
{
if(c1 == 'j' || c1 == 'k' || c1 == 'l')
printf(" ");
if(c == 'j') printf("5");
if(c == 'k') printf("55");
if(c == 'l') printf("555");
c1 = c;
goto top;
}
if(c == 'm' || c == 'n' || c == 'o')
{
if(c1 == 'm' || c1 == 'n' || c1 == 'o')
printf(" ");
if(c == 'm') printf("6");
if(c == 'n') printf("66");
if(c == 'o') printf("666");
c1 = c;
goto top;
}
if(c == 'p' || c == 'q' || c == 'r' || c == 's')
{
if(c1 == 'p' || c1 == 'q' || c1 == 'r' || c1 == 's')
Solution
Terminating when
Considering that you only support lowercase, it would be nice if you folded the input to lowercase.
That is one long, uninspired while-loop, full of cut-and-paste code. I recommend a completely different approach. Defining a
You should probably support digits as well, to be typed with one additional keypress. All it would take to support that enhancement is a simple change:
getchar() encounters \n is poor practice. If the program encounters EOF before Newline, then it will enter an infinite loop.Considering that you only support lowercase, it would be nice if you folded the input to lowercase.
That is one long, uninspired while-loop, full of cut-and-paste code. I recommend a completely different approach. Defining a
print_t9() function makes the code more meaningful and reusable.#include
#include
#include
#include
/**
* Determines the key and the number of repetitions of that key to type
* character c in T9. If c is a supported character, returns true.
* If c is unsupported, returns false, and the contents of *key and *reps
* are undefined.
*/
static _Bool t9_lookup(char c, int *key, int *reps) {
static const char t9_table[][5] = {
" ", /* 0 */
"", "abc", "def", /* 1 2 3 */
"ghi", "jkl", "mno", /* 4 5 6 */
"pqrs", "tuv", "wxyz" /* 7 8 9 */
};
c = tolower(c);
for (*key = 0; *key < sizeof(t9_table); (*key)++) {
char *p;
if ((p = strchr(t9_table[*key], c))) {
if (reps) {
*reps = p - t9_table[*key] + 1;
}
return true;
}
}
return false;
}
/**
* If c is one of the supported characters, prints the T9 representation and
* returns true. Otherwise, returns false. If the T9 representation uses the
* same key as the previous character, a space is printed as a separator.
*/
_Bool print_t9(FILE *output, char c, char prev_c) {
int key, reps, prev_key;
if (!t9_lookup(c, &key, &reps)) return false;
if (t9_lookup(prev_c, &prev_key, NULL) && key == prev_key) {
fprintf(output, " ");
}
while (reps--) {
fprintf(output, "%d", key);
}
return true;
}
int main() {
for (char prev_c = '\0', c; EOF != (c = getchar()); prev_c = c) {
print_t9(stdout, c, prev_c) || putchar(c);
}
return 0;
}You should probably support digits as well, to be typed with one additional keypress. All it would take to support that enhancement is a simple change:
static const char t9_table[][6] = {
" 0",
"1", "abc2", "def3",
"ghi4", "jkl5", "mno6",
"pqrs7", "tuv8", "wxyz9"
};Code Snippets
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
/**
* Determines the key and the number of repetitions of that key to type
* character c in T9. If c is a supported character, returns true.
* If c is unsupported, returns false, and the contents of *key and *reps
* are undefined.
*/
static _Bool t9_lookup(char c, int *key, int *reps) {
static const char t9_table[][5] = {
" ", /* 0 */
"", "abc", "def", /* 1 2 3 */
"ghi", "jkl", "mno", /* 4 5 6 */
"pqrs", "tuv", "wxyz" /* 7 8 9 */
};
c = tolower(c);
for (*key = 0; *key < sizeof(t9_table); (*key)++) {
char *p;
if ((p = strchr(t9_table[*key], c))) {
if (reps) {
*reps = p - t9_table[*key] + 1;
}
return true;
}
}
return false;
}
/**
* If c is one of the supported characters, prints the T9 representation and
* returns true. Otherwise, returns false. If the T9 representation uses the
* same key as the previous character, a space is printed as a separator.
*/
_Bool print_t9(FILE *output, char c, char prev_c) {
int key, reps, prev_key;
if (!t9_lookup(c, &key, &reps)) return false;
if (t9_lookup(prev_c, &prev_key, NULL) && key == prev_key) {
fprintf(output, " ");
}
while (reps--) {
fprintf(output, "%d", key);
}
return true;
}
int main() {
for (char prev_c = '\0', c; EOF != (c = getchar()); prev_c = c) {
print_t9(stdout, c, prev_c) || putchar(c);
}
return 0;
}static const char t9_table[][6] = {
" 0",
"1", "abc2", "def3",
"ghi4", "jkl5", "mno6",
"pqrs7", "tuv8", "wxyz9"
};Context
StackExchange Code Review Q#20462, answer score: 2
Revisions (0)
No revisions yet.