alien_fx_fiend

Untitled

Oct 15th, 2019
199
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  *
  3.  * Homework 4 - Water Jug Problem
  4.  * author: @rgadhia - Raj Gadhia and Albert Chen
  5.  * Pledge: I pledge my honor that I have abided by the Stevens Honor System.
  6.  * Date: 10/08/19
  7.  */
  8.  
  9. #include <iostream>
  10. #include <vector>
  11. #include <algorithm>
  12. #include <sstream>
  13. #include <iomanip>
  14. #include <list>
  15.  
  16. using namespace std;
  17.  
  18. // Struct to represent state of water in the jugs.
  19. struct State {
  20.     int a, b, c;
  21.     vector<string> directions;
  22.    
  23.     State(int _a, int _b, int _c) : a(_a), b(_b), c(_c) { }
  24.    
  25.     // String representation of state in tuple form.
  26.     string to_string() {
  27.         ostringstream oss;
  28.         oss << "(" << a << ", " << b << ", " << c << ")";
  29.         return oss.str();
  30.     }
  31. };
  32.  
  33. //if been visited already, dont put it in the queue
  34. //break outta queue while not empty loop when u find the goal
  35. //if the queue is empty, return 0
  36. //function that returns a vector that contains all the possible states u can go from current
  37. //vectors of strings in the state class: add the vector after every move
  38.  
  39. //dhorowit@stevens.edu
  40.  
  41. //returns a vector of the possible moves for that state
  42. vector<State> possiblepours(State s, int capA, int capB, int capC) {
  43.     vector<State> possible;
  44.     //C to A
  45.     if (s.a != capA && s.c != 0)
  46.     {
  47.         State temp(s.a,s.b,s.c);
  48.         int pamount;
  49.         temp.directions = s.directions;
  50.         if (temp.c + temp.a <= capA)
  51.         {
  52.             pamount = temp.c;
  53.             temp.a += pamount;
  54.             temp.c = 0;
  55.         }
  56.         else
  57.         {
  58.             pamount = capA - temp.a;
  59.             temp.a += pamount;
  60.             temp.c -= pamount;
  61.         }
  62.         if(pamount == 1){
  63.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from C to A. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  64.         } else {
  65.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from C to A. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  66.         }
  67.         possible.push_back(temp);
  68.     }
  69.     //B to A
  70.     if (s.a != capA && s.b != 0)
  71.     {
  72.         State temp(s.a,s.b,s.c);
  73.         temp.directions = s.directions;
  74.         int pamount;
  75.         if (temp.b + temp.a <= capA)
  76.         {
  77.             pamount = temp.b;
  78.             temp.a += pamount;
  79.             temp.b = 0;
  80.         }
  81.         else
  82.         {
  83.             pamount = capA - temp.a;
  84.             temp.a += pamount;
  85.             temp.b -= pamount;
  86.         }
  87.         if(pamount == 1){
  88.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from B to A. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  89.         } else {
  90.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from B to A. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  91.         }
  92.         possible.push_back(temp);
  93.     }
  94.     //C to B
  95.     if (s.b != capB && s.c != 0)   // (0,0,8) -> (0,5,3)
  96.     {
  97.         State temp(s.a,s.b,s.c);
  98.         temp.directions = s.directions;
  99.         int pamount;
  100.         if (temp.c + temp.b <= capB)
  101.         {
  102.             pamount = temp.c;
  103.             temp.b += pamount;
  104.             temp.c = 0;
  105.         }
  106.         else
  107.         {
  108.             pamount = capB - temp.b;
  109.             temp.b += pamount;
  110.             temp.c -= pamount;
  111.         }
  112.         if(pamount == 1){
  113.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from C to B. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  114.         } else {
  115.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from C to B. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  116.         }
  117.         possible.push_back(temp);
  118.     }
  119.     //A to B
  120.     if (s.b != capB && s.a != 0)
  121.     {
  122.         State temp(s.a,s.b,s.c);
  123.         temp.directions = s.directions;
  124.         int pamount;
  125.         if (temp.a + temp.b <= capB)
  126.         {
  127.             pamount = temp.a;
  128.             temp.b += pamount;
  129.             temp.a = 0;
  130.         }
  131.         else
  132.         {
  133.             pamount = capB - temp.b;
  134.             temp.b += pamount;
  135.             temp.a -= pamount;
  136.         }
  137.         if(pamount == 1){
  138.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from A to B. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  139.         } else {
  140.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from A to B. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  141.         }
  142.         possible.push_back(temp);
  143.     }
  144.     //B to C
  145.     if (s.c != capC && s.b != 0)
  146.     {
  147.         State temp(s.a,s.b,s.c);
  148.         temp.directions = s.directions;
  149.         int pamount;
  150.         if (temp.b + temp.c <= capC)
  151.         {
  152.             pamount = temp.b;
  153.             temp.c += pamount;
  154.             temp.b = 0;
  155.         }
  156.         else
  157.         {
  158.             pamount = capC - temp.c;
  159.             temp.c += pamount;
  160.             temp.b -= pamount;
  161.         }
  162.         if(pamount == 1){
  163.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from B to C. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  164.         } else {
  165.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from B to C. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  166.         }
  167.         possible.push_back(temp);
  168.     }
  169.     //A to C
  170.     if (s.c != capC && s.a != 0)
  171.     {
  172.         State temp(s.a,s.b,s.c);
  173.         int pamount;
  174.         temp.directions = s.directions;
  175.         if (temp.a + temp.c <= capC)
  176.         {
  177.             pamount = temp.a;
  178.             temp.c += pamount;
  179.             temp.a = 0;
  180.         }
  181.         else
  182.         {
  183.             pamount = capC - temp.c;
  184.             temp.c += pamount;
  185.             temp.a -= pamount;
  186.         }
  187.         if(pamount == 1){
  188.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallon from A to C. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  189.         } else {
  190.             temp.directions.push_back("Pour " + std::to_string(pamount)+ " gallons from A to C. " + "(" + std::to_string(temp.a) + ", " + std::to_string(temp.b) + ", " + std::to_string(temp.c) + ")\n");
  191.         }
  192.         possible.push_back(temp);
  193.     }
  194.     return possible;
  195. }
  196.  
  197. State breadthSearch (vector<int> nums) {
  198.     int cols = nums[0]+1;
  199.     int rows = nums[1]+1;
  200.     bool** visited = new bool*[rows];
  201.     // go through rows filling / visiting
  202.     for (int i=0; i<rows; i++)
  203.     {
  204.         visited[i] = new bool[cols];
  205.         fill(visited[i], visited[i] + cols, false);
  206.     }
  207.  
  208.     list<State> queue;
  209.     vector<State> moves;
  210.     State start(0, 0, nums[2]);
  211.     State goal(nums[3], nums[4], nums[5]);
  212.     State current(0, 0, 0);
  213.     queue.push_back(start);
  214.     while (!(queue.empty())) {
  215.         current = queue.front(); //extracts first element of queue
  216.         queue.pop_front(); //pops it out
  217.  
  218.         if (current.a == goal.a && current.b == goal.b && current.c == goal.c)
  219.         {
  220.             queue.push_back(current);
  221.             break;
  222.         }
  223.         else
  224.         {
  225.             moves = possiblepours(current, nums[0], nums[1], nums[2]);
  226.             for (int i = 0; i < (int)moves.size(); i++)
  227.             {
  228.                 current = moves[i];
  229.                 if (current.a == goal.a && current.b == goal.b && current.c == goal.c)
  230.                 {
  231.  
  232.                     for (int i = 0; i < cols; i++)
  233.                     {
  234.                         delete [] visited[i];
  235.                     }
  236.                     delete [] visited;
  237.  
  238.                     return current;
  239.                 }
  240.                 if (visited[current.a][current.b] == false)
  241.                 {
  242.                     queue.push_back(current);
  243.                     visited[current.a][current.b] = true;
  244.                 }
  245.             }
  246.         }
  247.     }
  248.     for (int i = 0; i < cols; i++) {
  249.         delete [] visited[i];
  250.     }
  251.    
  252.     delete [] visited;
  253.  
  254.     if (queue.empty()) {
  255.         return State(-1, -1, -1);
  256.     }
  257.     return current;
  258. }
  259.  
  260. int main(int argc, char * const argv[]) {
  261.     vector<int> nums;
  262.  
  263.     //user input should only have seven arguments
  264.     if (argc != 7)
  265.     {
  266.         cout << "Usage: ./waterjugpuzzle <cap A> <cap B> <cap C> <goal A> <goal B> <goal C>" << endl;
  267.         return 0;
  268.     }
  269.    
  270.    // ensure there is no error for integer capacity of jugs
  271.    // whenever there is no error, we pushback the capacity and goals into the nums vector
  272.     for (int i = 1; i < 4; i++) {
  273.         istringstream iss(argv[i]);
  274.         int isnum;
  275.         // if assigning iss to isnum fails, that means it's not an integer
  276.         if (!(iss>>isnum) || isnum <= 0)
  277.         {
  278.             if (i == 1)
  279.             {
  280.                  cout << "Error: Invalid capacity '" << argv[i] << "' for jug A." << endl;
  281.             }
  282.             if (i == 2)
  283.             {
  284.                  cout << "Error: Invalid capacity '" << argv[i] << "' for jug B." << endl;
  285.             }
  286.             if (i == 3)
  287.             {
  288.                  cout << "Error: Invalid capacity '" << argv[i] << "' for jug C." << endl;
  289.             }
  290.             iss.clear();
  291.             return 1;
  292.         }
  293.         nums.push_back(isnum);
  294.         iss.clear();
  295.     }
  296.     for (int i = 4; i < 7; i++)
  297.     {
  298.         istringstream iss(argv[i]);
  299.         int isnum;
  300.         if (!(iss>>isnum) || isnum < 0)
  301.         {
  302.             if (i == 4)
  303.             {
  304.                  cout << "Error: Invalid goal '" << argv[i] << "' for jug A." << endl;
  305.             }
  306.             if (i == 5)
  307.             {
  308.                  cout << "Error: Invalid goal '" << argv[i] << "' for jug B." << endl;
  309.             }
  310.             if (i == 6)
  311.             {
  312.                  cout << "Error: Invalid goal '" << argv[i] << "' for jug C." << endl;
  313.             }
  314.             iss.clear();
  315.             return 1;
  316.         }
  317.         nums.push_back(isnum);
  318.         iss.clear();
  319.     }
  320.     for (int i = 4; i < 7; i++)
  321.     {
  322.         if (nums[i-1] > nums[i-4])
  323.         {
  324.             if (i == 4)
  325.             {
  326.                 cout << "Error: Goal cannot exceed capacity of jug A." << endl;
  327.             }
  328.             if (i == 5)
  329.             {
  330.                 cout << "Error: Goal cannot exceed capacity of jug B." << endl;
  331.             }
  332.             if (i == 6)
  333.             {
  334.                 cout << "Error: Goal cannot exceed capacity of jug C." << endl;
  335.             }
  336.             return 1;
  337.         }
  338.     }
  339.     if (!(nums[3] + nums[4] + nums[5] == nums[2]))
  340.     {
  341.         cout << "Error: Total gallons in goal state must be equal to the capacity of jug C." << endl;
  342.         return 0;
  343.     }
  344.  
  345.     //----------------------------------------------------------------------------------------------------
  346.     // Do the BFS if there are no errors
  347.  
  348.     State found = breadthSearch(nums);
  349.  
  350.     if(found.a < 0){
  351.         cout << "No solution.";
  352.         return 1;
  353.     }
  354.  
  355.     cout << "Initial state. (0, 0, " << nums[2] <<")" << endl;
  356.  
  357.     for (int i = 0; i < (int) found.directions.size(); i++) {
  358.         cout << found.directions[i];
  359.     }
  360.  
  361.     return 0;
  362. }
Add Comment
Please, Sign In to add comment