Noam_15

Solve_The_Maze_V022

Jun 24th, 2018
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.45 KB | None | 0 0
  1. // Solve The Maze
  2. // V0.2.2
  3. //
  4. // Date: 2018.06.24
  5. // (Based on: https://symbolsprogrammingblog.wordpress.com/2010/06/20/%D7%9E%D7%A6%D7%99%D7%90%D7%AA-%D7%94%D7%93%D7%A8%D7%9A-%D7%94%D7%A7%D7%A6%D7%A8%D7%94-%D7%91%D7%99%D7%95%D7%AA%D7%A8-%D7%91%D7%9E%D7%91%D7%95%D7%9A/ )
  6.  
  7.  
  8. #include <stdio.h>
  9. #include <memory.h>
  10. #include <time.h>
  11. #include <stdlib.h>
  12.  
  13.  
  14. #define HEIGHT   50
  15. #define WIDTH    9
  16.  
  17. #define WALL     -1
  18. #define PATH     0
  19. #define START    83  // 'S'
  20. #define END      69  // 'E'
  21. #define ARROW    176
  22.  
  23. #define true 1
  24. #define false 0
  25. typedef int Boolean;
  26.  
  27. struct Point {
  28.    int Row;
  29.    int Column;
  30. };
  31.  
  32. typedef struct node {
  33.     struct Point point;
  34.     struct node* next;
  35. } node_t, node_p;
  36.  
  37. int SolveMaze(int Maze[HEIGHT][WIDTH]);
  38. struct Point FindStartingPoint(int Maze[HEIGHT][WIDTH]);
  39. struct Point FindStartingPathPoint(int Maze[HEIGHT][WIDTH]);
  40. int SolveMazeREC(int Maze[HEIGHT][WIDTH], int h, int w, int stepsUntilNow, node_t** outHeadOfList);
  41. void ShowBoard(int Board[HEIGHT][WIDTH]);
  42. void CopyBoard(int targetBoard[HEIGHT][WIDTH], int sourceBoard[HEIGHT][WIDTH]);
  43. void InitMinStepsInMazeArray();
  44. struct node* CreateNewList(struct Point point);
  45. void PrintList(struct node* head);
  46. void FreeList(struct node* head);
  47. void PushToList(node_t ** refEnd, struct Point point);
  48. void PaintAllPositionsInMazeThatAppearInFinalList(struct node* headOfFinalList, int Maze[HEIGHT][WIDTH]);
  49.  
  50. // Global Variables
  51. int MinStepsToEachPositionInMaze[HEIGHT][WIDTH];
  52. int MinStepsToGoToEnd;
  53.  
  54.  
  55. // This function try to solve the maze with minimum steps.
  56. //
  57. // If succeeded - fill the given board with 'ARROW' in the path that is found,
  58. //                and return the number of steps.
  59. // If failed    - return -1
  60. int SolveMaze(int Maze[HEIGHT][WIDTH])
  61. {
  62.     int h, w;
  63.     int steps = 2;
  64.     int lowestSteps = -1;
  65.     int NewMaze[HEIGHT][WIDTH];
  66.     int tmp;
  67.     struct Point startingPathPoint;
  68.     struct Point startingPoint;
  69.     struct node* headOfFinalList;
  70.     struct node* headOfNewList;
  71.  
  72.     // Init global variables
  73.     InitMinStepsInMazeArray();
  74.     MinStepsToGoToEnd = HEIGHT * WIDTH + 10; // Any number greater than number of positions in maze
  75.  
  76.     // Search start position
  77.     startingPathPoint = FindStartingPathPoint(Maze);
  78.     startingPoint = FindStartingPoint(Maze);
  79.  
  80.     // Init final positions list
  81.     headOfFinalList = CreateNewList(startingPathPoint);
  82.  
  83.     h = startingPathPoint.Row;
  84.     w = startingPathPoint.Column;
  85.  
  86.     MinStepsToEachPositionInMaze[h][w] = steps-1;
  87.  
  88.     // So the START position will not bother us
  89.     Maze[startingPoint.Row][startingPoint.Column] = ARROW;
  90.  
  91.     Maze[h][w] = ARROW;
  92.  
  93.     // UP
  94.     if (Maze[h-1][w] != WALL && Maze[h-1][w] != ARROW)
  95.     {
  96.         CopyBoard(NewMaze, Maze);
  97.         tmp = SolveMazeREC(NewMaze, h-1, w, steps, &headOfNewList);
  98.         if (tmp != -1)
  99.             if (tmp < lowestSteps || lowestSteps == -1)
  100.             {
  101.                 lowestSteps = tmp;
  102.                 headOfFinalList->next = headOfNewList;
  103.             }  
  104.     }
  105.  
  106.     // DOWN
  107.     if (Maze[h+1][w] != WALL && Maze[h+1][w] != ARROW)
  108.     {
  109.         CopyBoard(NewMaze, Maze);
  110.         tmp = SolveMazeREC(NewMaze, h+1, w, steps, &headOfNewList);
  111.         if (tmp != -1)
  112.             if (tmp < lowestSteps || lowestSteps == -1)
  113.             {
  114.                 lowestSteps = tmp;
  115.                 headOfFinalList->next = headOfNewList;
  116.             }
  117.     }
  118.  
  119.     // RIGHT
  120.     if (Maze[h][w+1] != WALL && Maze[h][w+1] != ARROW)
  121.     {
  122.         CopyBoard(NewMaze, Maze);
  123.         tmp = SolveMazeREC(NewMaze, h, w+1, steps, &headOfNewList);
  124.         if (tmp != -1)
  125.             if (tmp < lowestSteps || lowestSteps == -1)
  126.             {
  127.                 lowestSteps = tmp;
  128.                 headOfFinalList->next = headOfNewList;
  129.             }
  130.     }
  131.    
  132.     // LEFT
  133.     if (Maze[h][w-1] != WALL && Maze[h][w-1] != ARROW)
  134.     {
  135.         CopyBoard(NewMaze, Maze);
  136.         tmp = SolveMazeREC(NewMaze, h, w-1, steps, &headOfNewList);
  137.         if (tmp != -1)
  138.             if (tmp < lowestSteps || lowestSteps == -1)
  139.             {
  140.                 lowestSteps = tmp;
  141.                 headOfFinalList->next = headOfNewList;
  142.             }
  143.     }
  144.  
  145.     // Reset the START position
  146.     Maze[startingPoint.Row][startingPoint.Column] = START;
  147.     Maze[h][w] = PATH;
  148.  
  149.     // (If all directions are blocked, lowestSteps = -1)
  150.     if (lowestSteps == -1)
  151.     {
  152.         return -1;
  153.     }
  154.     else
  155.     {
  156.         PaintAllPositionsInMazeThatAppearInFinalList(headOfFinalList, Maze);
  157.         FreeList(headOfFinalList);     
  158.         return steps + lowestSteps;
  159.     }
  160. }
  161.  
  162. int SolveMazeREC(int Maze[HEIGHT][WIDTH], int h, int w, int stepsUntilNow, node_t** outHeadOfList)
  163. {
  164.     int lowestSteps = -1;
  165.     int NewMaze[HEIGHT][WIDTH];
  166.     int tmp;
  167.     struct Point startingPathPoint;
  168.     struct node* headOfNewList;
  169.  
  170.     // If we've come here before in a faster way (Or another way in the same length), we can stop.
  171.     if (MinStepsToEachPositionInMaze[h][w] <= stepsUntilNow)
  172.     {
  173.         (*outHeadOfList) = NULL; // (We don't really need this line)
  174.         return -1;
  175.     }
  176.     else
  177.     {
  178.         MinStepsToEachPositionInMaze[h][w] = stepsUntilNow;
  179.     }
  180.  
  181.     // -- If END
  182.     if (Maze[h][w] == END)
  183.     {
  184.         (*outHeadOfList) = NULL;
  185.         MinStepsToGoToEnd = stepsUntilNow;
  186.         return 1;
  187.     }
  188.  
  189.     // If we already crossed the "MinStepsToGoToEnd"
  190.     if (MinStepsToGoToEnd <= stepsUntilNow)
  191.     {
  192.         (*outHeadOfList) = NULL; // (We don't really need this line)
  193.         return -1;
  194.     }
  195.  
  196.     startingPathPoint.Row = h;
  197.     startingPathPoint.Column = w;
  198.     (*outHeadOfList) = CreateNewList(startingPathPoint);
  199.     Maze[h][w] = ARROW;
  200.  
  201.     // UP
  202.     if (Maze[h-1][w] != WALL && Maze[h-1][w] != ARROW)
  203.     {
  204.         CopyBoard(NewMaze, Maze);
  205.         tmp = SolveMazeREC(NewMaze, h-1, w, stepsUntilNow+1, &headOfNewList);
  206.         if (tmp != -1)
  207.             if (tmp < lowestSteps || lowestSteps == -1)
  208.             {
  209.                 lowestSteps = tmp;
  210.                 (*outHeadOfList)->next = headOfNewList;
  211.             }
  212.     }
  213.  
  214.     // DOWN
  215.     if (Maze[h+1][w] != WALL && Maze[h+1][w] != ARROW)
  216.     {
  217.         CopyBoard(NewMaze, Maze);
  218.         tmp = SolveMazeREC(NewMaze, h+1, w, stepsUntilNow+1, &headOfNewList);
  219.         if (tmp != -1)
  220.             if (tmp < lowestSteps || lowestSteps == -1)
  221.             {
  222.                 lowestSteps = tmp;
  223.                 (*outHeadOfList)->next = headOfNewList;
  224.             }
  225.     }
  226.  
  227.     // RIGHT
  228.     if (Maze[h][w+1] != WALL && Maze[h][w+1] != ARROW)
  229.     {
  230.         CopyBoard(NewMaze, Maze);
  231.         tmp = SolveMazeREC(NewMaze, h, w+1, stepsUntilNow+1, &headOfNewList);
  232.         if (tmp != -1)
  233.             if (tmp < lowestSteps || lowestSteps == -1)
  234.             {
  235.                 lowestSteps = tmp;
  236.                 (*outHeadOfList)->next = headOfNewList;
  237.             }
  238.     }
  239.    
  240.     // LEFT
  241.     if (Maze[h][w-1] != WALL && Maze[h][w-1] != ARROW)
  242.     {
  243.         CopyBoard(NewMaze, Maze);
  244.         tmp = SolveMazeREC(NewMaze, h, w-1, stepsUntilNow+1, &headOfNewList);
  245.         if (tmp != -1)
  246.             if (tmp < lowestSteps || lowestSteps == -1)
  247.             {
  248.                 lowestSteps = tmp;
  249.                 (*outHeadOfList)->next = headOfNewList;
  250.             }
  251.     }
  252.    
  253.     Maze[h][w] = PATH;
  254.    
  255.     // (If all directions are blocked, lowestSteps = -1)
  256.     if (lowestSteps == -1)
  257.     {
  258.         (*outHeadOfList) = NULL; // (We don't really need this line)
  259.         return -1;
  260.     }
  261.     else
  262.     {
  263.         return 1 + lowestSteps;
  264.     }
  265. }
  266.  
  267.  
  268. struct Point FindStartingPoint(int Maze[HEIGHT][WIDTH])
  269. {
  270.     int startRow;
  271.     int startColumn;
  272.     struct Point StartingPoint;
  273.     for (startRow = 0; startRow < HEIGHT; startRow++)
  274.     {
  275.         for (startColumn = 0; startColumn < WIDTH; startColumn++)
  276.         {
  277.             if (Maze[startRow][startColumn] == START)
  278.             {
  279.                 StartingPoint.Column = startColumn;
  280.                 StartingPoint.Row = startRow;
  281.                 return StartingPoint;
  282.             }
  283.         }
  284.     }
  285.  
  286.     printf("Error in FindStartingPoint\n");
  287.     return StartingPoint;
  288. }
  289.  
  290. struct Point FindStartingPathPoint(int Maze[HEIGHT][WIDTH])
  291. {
  292.     struct Point StartingPathPoint;
  293.     StartingPathPoint = FindStartingPoint(Maze);
  294.  
  295.     if (Maze[StartingPathPoint.Row + 1][StartingPathPoint.Column] == PATH)
  296.     {
  297.         StartingPathPoint.Row += 1;
  298.         return StartingPathPoint;
  299.     }
  300.     else if (Maze[StartingPathPoint.Row - 1][StartingPathPoint.Column] == PATH)
  301.     {
  302.         StartingPathPoint.Row -= 1;
  303.         return StartingPathPoint;
  304.     }
  305.     else if (Maze[StartingPathPoint.Row][StartingPathPoint.Column + 1] == PATH)
  306.     {
  307.         StartingPathPoint.Column += 1;
  308.         return StartingPathPoint;
  309.     }
  310.     else if (Maze[StartingPathPoint.Row][StartingPathPoint.Column - 1] == PATH)
  311.     {
  312.         StartingPathPoint.Column -= 1;
  313.         return StartingPathPoint;
  314.     }
  315.     else
  316.     {
  317.         printf("Error in FindStartingPathPoint\n");
  318.         return StartingPathPoint;
  319.     }
  320. }
  321.  
  322.  
  323. void InitMinStepsInMazeArray()
  324. {
  325.     int i, j;
  326.     for (i = 0; i < HEIGHT; i++)
  327.     {
  328.         for (j = 0; j < WIDTH; j++)
  329.         {
  330.             MinStepsToEachPositionInMaze[i][j] = HEIGHT * WIDTH + 10; // Any number greater than number of positions in maze
  331.         }
  332.     }
  333. }
  334.  
  335. void ShowBoard(int Board[HEIGHT][WIDTH])
  336. {
  337.     int row;
  338.     int col;
  339.  
  340.     printf("Full maze:\n\n\n");
  341.     for (row = 0; row < HEIGHT; row++)    // Loop through every row
  342.     {
  343.         for (col = 0; col < WIDTH; col++) // And every column
  344.         {
  345.             switch(Board[row][col])
  346.             {
  347.                 case WALL  :
  348.                   putchar('\xDB');
  349.                   break;
  350.  
  351.                 case PATH  :
  352.                   putchar(' ');
  353.                   break;
  354.  
  355.                 case ARROW :
  356.                   putchar(ARROW);
  357.                   break;
  358.                
  359.                 case START :
  360.                   putchar(START);
  361.                   break;
  362.                
  363.                 case END   :
  364.                   putchar(END);
  365.                   break;
  366.                
  367.                 default    :
  368.                   putchar('?');
  369.                   break;
  370.             }
  371.         }
  372.         putchar('\n');
  373.     }
  374.     printf("\n\n\n");
  375. }
  376.  
  377. void CopyBoard(int targetBoard[HEIGHT][WIDTH], int sourceBoard[HEIGHT][WIDTH])
  378. {
  379.     // Fast copy:
  380.     memcpy(targetBoard, sourceBoard, WIDTH * HEIGHT * sizeof(int));
  381. }
  382.  
  383. void InitializeTheMaze(int Board[HEIGHT][WIDTH])
  384. {
  385.     // Maze Option A:
  386.     // #define HEIGHT   50
  387.     // #define WIDTH    9
  388.     int TmpBoard[HEIGHT][WIDTH] = {
  389.         { WALL , WALL , START, WALL, WALL , WALL , WALL , WALL , WALL  },
  390.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  391.         { WALL , PATH , WALL , WALL, WALL , PATH , WALL , WALL , WALL  },
  392.         { WALL , PATH , WALL , PATH, WALL , PATH , PATH , PATH , WALL  },
  393.         { WALL , WALL , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  394.         { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  395.         { WALL , PATH , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  396.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  397.         { WALL , PATH , WALL , WALL, WALL , WALL , WALL , WALL , WALL  },
  398.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  399.         { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  400.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  401.         { WALL , PATH , WALL , WALL, PATH , WALL , WALL , PATH , WALL  },
  402.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  403.         { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  404.         { WALL , PATH , WALL , PATH, PATH , PATH , WALL , PATH , WALL  },
  405.         { WALL , PATH , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  406.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  407.         { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  408.         { WALL , PATH , PATH , PATH, PATH , PATH , WALL , PATH , WALL  },
  409.         { WALL , WALL , PATH , WALL, WALL , WALL , WALL , PATH , WALL  },
  410.         { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL  },
  411.         { WALL , PATH , WALL , WALL, WALL , PATH , WALL , WALL , WALL  },
  412.         { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL  },
  413.         { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  414.         { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  415.         { WALL , WALL , WALL , WALL, WALL , PATH , WALL , PATH , WALL  },
  416.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  417.         { WALL , PATH , WALL , PATH, PATH , WALL , PATH , WALL , WALL  },
  418.         { WALL , PATH , PATH , PATH, WALL , WALL , PATH , WALL , WALL  },
  419.         { WALL , WALL , WALL , PATH, WALL , WALL , PATH , WALL , WALL  },
  420.         { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL  },
  421.         { WALL , WALL , WALL , PATH, WALL , WALL , PATH , PATH , WALL  },
  422.         { WALL , PATH , PATH , PATH, WALL , WALL , WALL , PATH , WALL  },
  423.         { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  424.         { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  425.         { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL  },
  426.         { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  427.         { WALL , WALL , WALL , WALL, PATH , WALL , PATH , WALL , WALL  },
  428.         { WALL , PATH , PATH , PATH, PATH , WALL , PATH , PATH , WALL  },
  429.         { WALL , PATH , WALL , WALL, WALL , WALL , PATH , WALL , WALL  },
  430.         { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL  },
  431.         { WALL , PATH , WALL , WALL, WALL , WALL , PATH , WALL , WALL  },
  432.         { WALL , PATH , PATH , PATH, WALL , PATH , PATH , PATH , WALL  },
  433.         { WALL , PATH , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  434.         { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  435.         { WALL , WALL , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  436.         { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  437.         { WALL , PATH , PATH , WALL, WALL , WALL , PATH , PATH , WALL  },
  438.         { WALL , END  , WALL , WALL, WALL , WALL , WALL , WALL , WALL  }
  439.     };
  440.  
  441.  
  442.  
  443.     // Maze Option B:
  444.     //// #define HEIGHT   9
  445.     //// #define WIDTH    9
  446.     //int TmpBoard[HEIGHT][WIDTH] = {
  447.     //  { WALL , WALL , START, WALL, WALL , WALL , WALL , WALL , WALL  },
  448.     //  { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  449.     //  { WALL , PATH , WALL , WALL, WALL , PATH , WALL , WALL , WALL  },
  450.     //  { WALL , PATH , WALL , PATH, WALL , PATH , PATH , PATH , WALL  },
  451.     //  { WALL , WALL , WALL , PATH, WALL , PATH , WALL , PATH , WALL  },
  452.     //  { WALL , PATH , WALL , PATH, PATH , PATH , PATH , PATH , WALL  },
  453.     //  { WALL , PATH , WALL , WALL, WALL , WALL , WALL , PATH , WALL  },
  454.     //  { WALL , PATH , PATH , PATH, PATH , PATH , PATH , PATH , WALL  },
  455.     //  { WALL , END  , WALL , WALL, WALL , WALL , WALL , WALL , WALL  },
  456.     //};
  457.  
  458.     CopyBoard(Board, TmpBoard);
  459. }
  460.  
  461. void PaintAllPositionsInMazeThatAppearInFinalList(struct node* headOfFinalList, int Maze[HEIGHT][WIDTH])
  462. {
  463.     struct node* current = headOfFinalList;
  464.     int i = 0;
  465.     while (current != NULL) {
  466.         Maze[current->point.Row][current->point.Column] = ARROW;
  467.         current = current->next;
  468.     }
  469. }
  470.  
  471.  
  472.  
  473. // ** List Functions **
  474. //
  475. // - - Example of use: - -
  476. //)
  477. //struct node* head;
  478. //struct node* endOfList;
  479. //struct Point point1, point2, point3, point4;
  480. //
  481. //point1.Column = 3;
  482. //point1.Row = 5;
  483. //point2.Column = 30;
  484. //// ... (init all points)
  485. //
  486. //endOfList = head = CreateNewList(point1);
  487. //PushToList(&endOfList, point2);
  488. //PushToList(&endOfList, point3);
  489. //PushToList(&endOfList, point4);
  490. // 
  491. //PrintList(head);
  492. //FreeList(head);
  493. //
  494.  
  495. struct node* CreateNewList(struct Point point)
  496. {
  497.     struct node* headAndEndOfList;
  498.     headAndEndOfList = (struct node*)malloc(sizeof(node_t));
  499.     headAndEndOfList->point = point;
  500.     headAndEndOfList->next = NULL;
  501.     return headAndEndOfList;
  502. }
  503.  
  504. void PrintList(struct node* head) {
  505.     struct node* current = head;
  506.     while (current != NULL) {
  507.         printf("C: %d, R: %d\n", current->point.Column, current->point.Row);
  508.         current = current->next;
  509.     }
  510. }
  511.  
  512. void FreeList(struct node* head) {
  513.     struct node * p;
  514.     while( head ) {
  515.         p = head;
  516.         head = head->next;
  517.         free( p );
  518.     }
  519. }
  520.  
  521. // Adding an item to the beginning of the list
  522. void PushToList(node_t ** refEnd, struct Point point) {
  523.     node_t * new_node;
  524.     new_node = (struct node*)malloc(sizeof(node_t));
  525.  
  526.     new_node->point = point;
  527.     new_node->next = NULL;
  528.  
  529.     (*refEnd)->next = new_node;
  530.     (*refEnd) = new_node;
  531. }
  532.  
  533. int main()
  534. {
  535.     int Board [HEIGHT][WIDTH];
  536.     int Steps;
  537.     clock_t begin, end;
  538.     double time_spent;
  539.  
  540.     InitializeTheMaze(Board);
  541.  
  542.     printf("* Start:\n\n");
  543.     ShowBoard(Board);
  544.  
  545.     printf("* Program Answer:\n\n");
  546.     begin = clock();
  547.     Steps = SolveMaze(Board);
  548.     end = clock();
  549.     time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  550.  
  551.     if (Steps != -1) // Path found
  552.     {
  553.         printf("Number of steps: %d\n-----------------------\n", Steps);
  554.         ShowBoard(Board);
  555.     }
  556.     else
  557.     {
  558.         printf("Maze cannot be solved! :(\n\n");
  559.     }
  560.  
  561.     printf("Time:  %lf Seconds\n", time_spent);
  562.     getchar();
  563. }
Advertisement
Add Comment
Please, Sign In to add comment