alien_fx_fiend

Untitled

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