Advertisement
Guest User

press_challenge

a guest
Jul 19th, 2019
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.99 KB | None | 0 0
  1. #include <err.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. struct press_info {
  6.   char               pi_button;
  7.   int                pi_count;
  8.   struct press_info *pi_next;
  9. };
  10.  
  11. int
  12. get_press_info(const char *string, struct press_info **press_info)
  13. {
  14.   struct press_info start = {0};
  15.   struct press_info *it   = &start;
  16.  
  17.   while (*string) {
  18.     it->pi_next = malloc(sizeof(struct press_info));
  19.     if (!it->pi_next) return -1;
  20.  
  21.     it            = it->pi_next;
  22.     it->pi_button = *string;
  23.     it->pi_count  = 0;
  24.     it->pi_next   = NULL;
  25.     while (*string == it->pi_button) {
  26.       string++;
  27.       it->pi_count++;
  28.     }
  29.   }
  30.  
  31.   *press_info = start.pi_next;
  32.   return 0;
  33. }
  34.  
  35. int
  36. press_info_to_char(const struct press_info *pi,
  37.                    const struct press_info *previous)
  38. {
  39.   const char lookup_table[12][5] = {"1", "2abc", "3def", "4ghi",
  40.                                     "5jkl", "6mno", "7pqrs", "8tuv",
  41.                                     "9wxyz", "*^", "#.,", "0+ "};
  42.   const int data_sizes[] = {1, 4, 4, 4, 4, 4, 5, 4, 5, 2, 2, 3};
  43.  
  44.   if (pi->pi_button == '0') {
  45.     if (previous &&
  46.         previous->pi_button != '1' &&
  47.         pi->pi_count == 1 &&
  48.         pi->pi_next &&
  49.         pi->pi_next->pi_button == previous->pi_button)
  50.       return 0;
  51.  
  52.     return lookup_table[11][pi->pi_count % data_sizes[11]];
  53.   }
  54.  
  55.   for (int i = 0; i < 11; i++)
  56.     if (lookup_table[i][0] == pi->pi_button)
  57.       return lookup_table[i][pi->pi_count % data_sizes[i]];
  58.  
  59.   return -1;
  60. }
  61.  
  62. int
  63. main(int argc, char **argv)
  64. {
  65.   if (argc != 2) errx(1, "usage: %s [keypad sequence]", *argv);
  66.  
  67.   int    button;
  68.   struct press_info *pi = NULL, *prev = NULL;
  69.  
  70.   if (get_press_info(argv[1], &pi))
  71.     errx(1, "unable to read input");
  72.  
  73.   while (pi) {
  74.     if ((button = press_info_to_char(pi, prev)) == -1)
  75.       errx(1, "unable to parse character: %c", pi->pi_button);
  76.     else if (button)
  77.       putchar(button);
  78.  
  79.     prev = pi;
  80.     pi = pi->pi_next;
  81.   }
  82.  
  83.   putchar('\n');
  84. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement