#define _POSIX_C_SOURCE 2 #include #include #include #include #include #include #include int read_line(int fd, char *buf, size_t len, int *bye) { char c; ssize_t st; if (len == 0) return 0; // precaution while ((st = read(fd, &c, 1))) { if (st < 0) return errno; if (c == '\n') break; else if (len <= 1) return -1; // buffer too small else { *buf = c; buf++; len--; } } *buf = '\0'; if (st == 0) *bye = 1; return 0; } int line_is_empty(char *data) { for(;*data != '\0'; data++) { if (!isspace(*data)) return 0; } return 1; } int parse_line(char *data, int *result, int nlevels) { if (data == NULL || result == NULL) return 0; char *tok; int howmany; for (howmany = 0;;howmany++) { if (!howmany) tok = strtok(data, " "); else tok = strtok(NULL, " "); if (tok == NULL) break; if (howmany >= nlevels) return -1; // too many fields errno = 0; *result = (int) strtol(tok, NULL, 10); result++; // must be valid if (errno) return errno; } if (howmany != nlevels) return -2; // too few fields return 0; } char *skip_spaces(char *data) { while (*data != '\0' && isspace(*data)) data++; return data; } char *skip_nonspaces(char *data) { while (*data != '\0' && !isspace(*data)) data++; return data; } int *duplicate_integer_array(int *array, int len) { int *a = malloc(sizeof(int) * len); if (a == NULL) { puts("MALLOC FAILED"); exit(1); } for (int i = 0; i < len; i++) { a[i] = array[i]; } return a; } void convert_to_steps(int *array, int len) { for (int i = 0; i < len - 1; i++) array[i] = array[i+1] - array[i]; } int abs(int i) { return i >= 0 ? i : -i; } int sign(int i) { if (i > 0) return 1; else if (i == 0) return 0; else return -1; } void complain(int msg, int where) { printf("On line %d: ", where); if (msg > 0) puts(strerror(msg)); else printf("internal error: %d", msg); } int main() { char buf[1024]; int line; int bye = 0; int i[1024]; int *records[1024]; int st; int nlevels = 0; for(line = 0; line < 1024; line++) { if ((st = read_line(0, buf, 1024, &bye))) { complain(st, line + 1); return 1; } else if (line_is_empty(buf) && !bye) { line--; // 200iq continue; } if (bye) break; if (!nlevels) { char *tmp; tmp = skip_spaces(buf); while (*tmp != '\0') { tmp = skip_nonspaces(tmp); nlevels++; tmp = skip_spaces(tmp); } if (nlevels > 1024) { puts("Too many levels"); return 1; } } if ((st = parse_line(buf, i, nlevels))) { complain(st, line + 1); return 1; } records[line] = duplicate_integer_array(i, nlevels); } int *a; int s; int safety = 1; for (int iter = 0; iter < line; iter++) { a = records[iter]; convert_to_steps(a, nlevels); s = sign(a[0]); safety = 1; for (int j = 0; j < nlevels - 1; j++) { if (s != sign(a[j]) || abs(a[j]) < 1 || abs(a[j]) > 3) { safety = 0; break; } } if (safety) puts("Safe"); else puts("Unsafe"); free(a); } }