Advertisement
airevent

oke

Dec 3rd, 2015
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.28 KB | None | 0 0
  1. //
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6.  
  7. #define CELL_HEALTHY 'o'
  8. #define CELL_VOID '.'
  9. #define CELL_SICK '!'
  10. #define CELL_ALMOST_SICK 'X'
  11.  
  12. #define ASK_FOR_FIELD_SIZE_PROMPT "Field size: "
  13. #define ASK_FOR_FIELD_FILL_PROMPT "Now fill it:\n"
  14.  
  15. #define FIELD_MAX_W 100
  16. #define FIELD_MAX_H 100
  17.  
  18. #define RESULT_OK 0
  19. #define ERROR_FIELD_SIZE_INVALID 1
  20. #define ERROR_FIELD_INVALID_CELL_VALUE 2
  21. #define ERROR_FIELD_INVALID_CELL_COUNT 3
  22.  
  23. #define epic_fail( r ) { printf("Error: %s\n", error_names[r]); exit(1); }
  24. #define invalid_cell( cell ) ((cell != CELL_HEALTHY && cell != CELL_VOID && cell != CELL_SICK) ? 1 : 0)
  25. #define isspace( c ) (c=='\r' || c=='\n' || c==' ')
  26. #define infect( x, y ) if ( field[y][x] == CELL_HEALTHY ) field[y][x] = CELL_ALMOST_SICK
  27.  
  28. static const char * const error_names[] = {
  29.     "RESULT_OK",
  30.     "invalid field size",
  31.     "invalid cell value",
  32.     "invalid cells amount in a row",
  33. };
  34.  
  35. int ask_for_field_size( int *w, int *h );
  36. int ask_for_field_fill( char **field, int w, int h );
  37. char **create_field( int w, int h );
  38. char **clone_field( char **field, int w, int h );
  39. void do_the_math( char **field, int w, int h, int *days, int *infected_n );
  40. void debug_field( char **field, int w, int h );
  41. void plz_no_errors( int r );
  42. char *trim( char *str );
  43.  
  44. int main(void) {
  45.     int field_w, field_h; // размеры поля
  46.     char **field; // поле
  47.     int days, infected_n; // как быстро и сколько заразит
  48.  
  49.     // вводим размеры поля:
  50.     plz_no_errors(ask_for_field_size(&field_w, &field_h));
  51.  
  52.     // создаем 2D массив:
  53.     field = create_field(field_w, field_h);
  54.  
  55.     // заполняем поле:
  56.     plz_no_errors(ask_for_field_fill(field, field_w, field_h));
  57.  
  58. debug_field(field, field_w, field_h);
  59.  
  60.     printf("Now we will count ... ");
  61.  
  62.     // посчитать сколько заразит и как быстро
  63.     do_the_math(field, field_w, field_h, &days, &infected_n);
  64.  
  65.     printf("DONE\ninfected: %d, days: %d\n", infected_n, days);
  66.  
  67. debug_field(field, field_w, field_h);
  68.  
  69.     //free_field(field, field_w, field_h);
  70. }
  71.  
  72. char **clone_field( char **field, int w, int h ) {
  73.     int x, y;
  74.  
  75.     char **clone = (char **)malloc(h * sizeof(char *));
  76.  
  77.     for ( y=0; y<h; y++ ) {
  78.         clone[y] = (char *)malloc(w * sizeof(char));
  79.  
  80.         for ( x=0; x<w; ++x ) {
  81.             clone[y][x] = field[y][x];
  82.         }
  83.     }
  84.  
  85.     return clone;
  86. }
  87.  
  88. void do_the_math( char **field, int w, int h, int *days, int *infected_n ) {
  89.     int x, y;
  90.     int infected_today;
  91.  
  92.     *days = 0;
  93.     *infected_n = 0;
  94.  
  95.     //char **clone = clone_field(field, w, h);
  96.  
  97.     while ( 1 ) {
  98.         infected_today = 0;
  99.  
  100.         for ( y=0; y<h; y++ ) {
  101.             for ( x=0; x<w; ++x ) {
  102.                 if ( field[y][x] == CELL_SICK ) {
  103.                     // top (y-1, x)
  104.                     if ( y-1 >= 0 ) { // exists
  105.                         infect(x, y-1);
  106.                     }
  107.                     // bottom (y+1, x)
  108.                     if ( y+1 < h ) { // exists
  109.                         infect(x, y+1);
  110.                     }
  111.                     // left (y, x-1)
  112.                     if ( x-1 >= 0 ) { // exists
  113.                         infect(x-1, y);
  114.                     }
  115.                     // right (y, x+1)
  116.                     if ( x+1 < w ) { // exists
  117.                         infect(x+1, y);
  118.                     }
  119.                 }
  120.             }
  121.         }
  122.  
  123.         // convert CELL_ALMOST_SICK to CELL_SICK and increment infected_n
  124.  
  125.         for ( y=0; y<h; y++ ) {
  126.             for ( x=0; x<w; ++x ) {
  127.                 if ( field[y][x] == CELL_ALMOST_SICK ) {
  128.                     field[y][x] = CELL_SICK;
  129.                     infected_today++;
  130.                 }
  131.             }
  132.         }
  133.  
  134.         if ( !infected_today ) break;
  135.  
  136.         *infected_n += infected_today;
  137.         (*days)++;
  138.     }
  139.  
  140.     //free_field(clone, w, h);
  141. }
  142.  
  143. int ask_for_field_fill( char **field, int w, int h ) {
  144.     printf(ASK_FOR_FIELD_FILL_PROMPT);
  145.  
  146.     char str[FIELD_MAX_W + 1]; // read buffer
  147.     char *str_trimmed;
  148.     int str_len;
  149.     int x, y;
  150.  
  151.     // сначала заполняем первый ряд, потом второй и т.п.
  152.     for ( y=0; y<h; y++ ) {
  153.         while ( 1 ) {
  154.             memset(str, 0, FIELD_MAX_W + 1);
  155.             fgets(str, FIELD_MAX_W, stdin);
  156.             str_trimmed = trim(str);
  157.             str_len = strlen(str_trimmed);
  158.  
  159.             if ( !str_len ) {
  160.                 continue; // пропускаем пустые линии
  161.             }
  162.  
  163.             if ( str_len != w ) {
  164.                 return ERROR_FIELD_INVALID_CELL_COUNT; // у нас ячеек больше или меньше, чем ввели буковок
  165.             }
  166.  
  167.             // наконец-то заполняем
  168.             for ( x=0; x<w; ++x ) {
  169.                 if ( invalid_cell(str_trimmed[x]) ) {
  170.                     return ERROR_FIELD_INVALID_CELL_VALUE; // какую-то херню ввели
  171.                 }
  172.  
  173.                 field[y][x] = str_trimmed[x];
  174.             }
  175.             break;
  176.         }
  177.     }
  178.  
  179.     return RESULT_OK;
  180. }
  181.  
  182. char **create_field( int w, int h ) {
  183.     int x, y;
  184.  
  185.     char **field = (char **)malloc(h * sizeof(char *));
  186.  
  187.     for ( y=0; y<h; y++ ) {
  188.         field[y] = (char *)malloc(w * sizeof(char));
  189.     }
  190.  
  191.     return field;
  192. }
  193.  
  194. void debug_field( char **field, int w, int h ) {
  195.     int x, y;
  196.  
  197.     for ( y=0; y<h; y++ ) {
  198.         for ( x=0; x<w; ++x ) {
  199.             printf("%c ", field[y][x]);
  200.         }
  201.         printf("\n");
  202.     }
  203. }
  204.  
  205. int ask_for_field_size( int *w, int *h ) {
  206.     printf(ASK_FOR_FIELD_SIZE_PROMPT);
  207.  
  208.     *w = 0;
  209.     *h = 0;
  210.  
  211.     scanf("%d %d", w, h);
  212.  
  213.     if ( *w < 1 || *w > FIELD_MAX_W || *h < 1 || *h > FIELD_MAX_H ) {
  214.         return ERROR_FIELD_SIZE_INVALID;
  215.     } else {
  216.         return RESULT_OK;
  217.     }
  218. }
  219.  
  220. void plz_no_errors( int r ) {
  221.     if ( r != RESULT_OK ) {
  222.         epic_fail(r);
  223.     }
  224. }
  225.  
  226. char *trim( char *str ) {
  227.     char *end;
  228.  
  229.     while ( isspace(*str) ) str++;
  230.  
  231.     if ( *str == 0 ) {
  232.         return str;
  233.     }
  234.  
  235.     end = str + strlen(str) - 1;
  236.  
  237.     while ( end > str && isspace(*end) ) {
  238.         end--;
  239.     }
  240.  
  241.     *(end+1) = 0;
  242.  
  243.     return str;
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement