diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/learn-your-telephone-number.c | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/src/learn-your-telephone-number.c b/src/learn-your-telephone-number.c deleted file mode 100644 index 6540feb..0000000 --- a/src/learn-your-telephone-number.c +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Copyright © 2016 Mattias Andrée <maandree@member.fsf.org> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#define _DEFAULT_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <alloca.h> -#include <errno.h> -#include <string.h> - - -#define t(...) do { if (__VA_ARGS__) goto fail; } while (0) - - -static const char* argv0; - - -char* compare(const char* restrict e, const char* restrict c) -{ - size_t en = strlen(e); - size_t cn = strlen(c); - size_t** matrix = alloca((en + 1) * sizeof(size_t*)); - char** path_matrix = alloca((en + 1) * sizeof(char*)); - size_t ei, ci, ri = 0; - char* rc = NULL; - - for (ei = 0; ei <= en; ei++) - { - matrix[ei] = alloca((cn + 1) * sizeof(size_t)); - matrix[ei][0] = ei; - path_matrix[ei] = alloca((cn + 1) * sizeof(char)); - path_matrix[ei][0] = '|'; - } - for (ci = 0; ci <= cn; ci++) - { - matrix[0][ci] = ci; - path_matrix[0][ci] = '-'; - } - path_matrix[0][0] = '\0'; - - e--, c--; - - for (ei = 1; ei <= en; ei++) - for (ci = 1; ci <= cn; ci++) - { - size_t d = matrix[ei - 1][ci - 1]; - size_t l = matrix[ei + 0][ci - 1]; - size_t u = matrix[ei - 1][ci + 0]; - size_t lu = 1 + (l < u ? l : u); - int ch = (e[ei] != c[ci]); - d += (size_t)ch; - matrix[ei][ci] = d < lu ? d : lu; - path_matrix[ei][ci] = d < lu ? (ch ? '\\' : '=') : (l < u ? '-' : '|'); - } - - t (!(rc = malloc((en + cn + 2) * sizeof(char)))); - -#if 0 - for (ei = 0; ei <= en; ei++) - { - for (ci = 0; ci <= cn; ci++) - printf("%zu%s", matrix[ei][ci], ci == cn ? "" : - path_matrix[ei][ci + 1] == '-' ? "\033[1;32m-\033[m" : " "); - printf("\n"); - if (ei < en) - for (ci = 0; ci < cn; ci++) - printf("%s%s", path_matrix[ei + 1][ci + 0] == '|' ? "\033[1;31m|\033[m" : " ", - path_matrix[ei + 1][ci + 1] == '\\' ? "\033[1;33m\\\033[m" : - path_matrix[ei + 1][ci + 1] == '=' ? "\033[1;39m\\\033[m" : " "); - printf("\n"); - } -#endif - - rc[ri++] = '\0'; - for (ei = en, ci = cn; ei + ci;) - switch (path_matrix[ei][ci]) - { - case '=': ei--, ci--; rc[ri++] = '='; break; - case '\\': ei--, ci--; rc[ri++] = '!'; break; - case '|': ei--; rc[ri++] = '-'; break; - case '-': ci--; rc[ri++] = '+'; break; - default: - abort(); - } - rc[ri] = '\0'; - - fail: - return rc; -} - - -int main(int argc, char* argv[]) -{ - char* correct; - char* entered = NULL; - size_t n = 0; - void* new; - char* w; - char* r; - char* path = NULL; - char* path_; - char* p; - int rc = 0; - - argv0 = argc ? argv[0] : "learn-your-telephone-number"; - if (argc != 2) - goto usage; - - correct = alloca((2 * strlen(argv[1]) + 1) * sizeof(char)); - for (w = correct, r = argv[1]; *r; r++) - if (isdigit(*r)) *w++ = *r; - else if (isalpha(*r)) goto usage; - else if (*r == '+') *w++ = '0', *w++ = '0'; - *w = '\0'; - - t (fprintf(stdout, "Enter your telephone number: ") < 0); - t (fflush(stdout)); - t (errno = 0, getline(&entered, &n, stdin) < 0); - n = strlen(entered) - 1; - entered[n] = '\0'; - - t (!(new = realloc(entered, (2 * n + 1) * sizeof(char)))); - entered = new; - memmove(r = (entered + n), w = (entered), n + 1); - for (; *r; r++) - if (isdigit(*r)) *w++ = *r; - else if (*r == '+') *w++ = '0', *w++ = '0'; - *w = '\0'; - - if (!strcmp(entered, correct)) - goto done; - t (!(path = compare(entered, correct))); - - path_ = strchr(path + 1, '\0'); - t (fprintf(stdout, "\033[A\033[KEntered: ") < 0); - for (p = entered; *--path_;) - switch (*path_) - { - case '=': t (fprintf(stdout, "\033[39m%c", *p++) < 0); break; - case '!': t (fprintf(stdout, "\033[31m%c", *p++) < 0); break; - case '+': t (fprintf(stdout, " ") < 0); break; - case '-': t (fprintf(stdout, "\033[31m%c", *p++) < 0); break; - } - t (fprintf(stdout, "\033[m\n") < 0); - - path_ = strchr(path + 1, '\0'); - t (fprintf(stdout, "Correct: ") < 0); - for (p = correct; *--path_;) - switch (*path_) - { - case '=': t (fprintf(stdout, "\033[39m%c", *p++) < 0); break; - case '!': t (fprintf(stdout, "\033[32m%c", *p++) < 0); break; - case '+': t (fprintf(stdout, "\033[32m%c", *p++) < 0); break; - case '-': t (fprintf(stdout, " ") < 0); break; - } - t (fprintf(stdout, "\033[m\n") < 0); - - rc = 1; - done: - free(entered); - free(path); - return rc; - fail: - rc = 1; - if (errno == 0) - goto done; - perror(argv0); - rc = 2; - goto done; - usage: - fprintf(stderr, "usage: %s YOUR-TELEPHONE-NUMBER\n", argv0); - return 2; -} - |