Advertisement
Guest User

Untitled

a guest
Nov 25th, 2012
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.39 KB | None | 0 0
  1. //
  2. // main.cpp
  3. // 2-Shipments
  4. //
  5. // Created by Moshe Berman on 11/25/12.
  6. // Copyright (c) 2012 Moshe Berman. All rights reserved.
  7. //
  8.  
  9. #include <iostream>
  10. #include <fstream>
  11. #include <sstream>
  12.  
  13. #include "Warehouse.h"
  14. #include "Card.h"
  15.  
  16. // Some utility methods I wrote for file IO.
  17. #include "FileIO/FileIO.h"
  18.  
  19. using namespace std;
  20.  
  21. //
  22. // Method implementations are preceeded by
  23. // full explanations of each piece of code.
  24. //
  25.  
  26. bool pricesFromStringToArray(string input, double *);
  27. string cityNameFromCard(string);
  28. string pricesForWarehouse(string card);
  29. bool loadQuantitiesFromString(string, int[], const int);
  30. bool warehouseHasDesiredAmountOfItem(Warehouse, int, int);
  31. Warehouse *warehouseMostStockThatFillsItemAndAmount(Warehouse[], int, int, int);
  32.  
  33. //
  34. // Declare a constant for the number of variables
  35. //
  36.  
  37. const int numberOfWarehouses = 5;
  38.  
  39. //
  40. // The names of the warehouses
  41. //
  42.  
  43. string warehouseNames[numberOfWarehouses] = {"New York", "Los Angeles", "Miami", "Houston", "Chicago"};
  44.  
  45.  
  46. //
  47. // Returns a warehouse from a given
  48. // array, matching a given name.
  49. //
  50.  
  51. template <int N>
  52. Warehouse &warehouseForNameFromArray(string name, Warehouse (&warehouses)[N])
  53. {
  54. for (Warehouse* it=warehouses; it!=(warehouses+N); ++it)
  55. if (it->name == name)
  56. return *it;
  57.  
  58. throw "whoops";
  59. }
  60.  
  61.  
  62. int main(int argc, const char * argv[])
  63. {
  64.  
  65. //
  66. // Since we know there are 5 warehouses,
  67. // we can declare a static array. No need
  68. // for dynamic arrays or vectors or whatever.
  69. //
  70.  
  71. Warehouse warehouses[numberOfWarehouses];
  72.  
  73. //
  74. // Read the warehouse names into the warehouse array.
  75. // TODO: It would be awesome if we could do this dynamically,
  76. // but there are too many edge cases to handle, so it's
  77. // out of the scope the assignment...
  78. //
  79.  
  80. for (int i=0; i<numberOfWarehouses; i++) {
  81. warehouses[i].name = warehouseNames[i];
  82.  
  83. //Also prep the warehouse with default values.
  84. warehouses[i].quantities[0] = 0;
  85. warehouses[i].quantities[1] = 0;
  86. warehouses[i].quantities[2] = 0;
  87. }
  88.  
  89. //
  90. // Open an the records file
  91. //
  92.  
  93. ifstream recordsFile;
  94. string fileName = "cards.txt";
  95.  
  96. // If opening fails, print out an error.
  97.  
  98. if(!openInputStream(recordsFile, fileName)){
  99. cout << "Could not open " << fileName << endl;
  100. }
  101.  
  102. // Otherwise, proceed to parse the file
  103.  
  104. else{
  105.  
  106. //
  107. // Declare some variables to hold the prices & quantities
  108. //
  109.  
  110. double prices[3];
  111. int quantities[3];
  112.  
  113. //
  114. // Read out the line that contains the
  115. // prices and parse it into an array.
  116. //
  117.  
  118. string pricesString;
  119.  
  120. getline(recordsFile, pricesString);
  121.  
  122. pricesFromStringToArray(pricesString, prices);
  123.  
  124.  
  125. //
  126. // Read in each line and process it.
  127. //
  128.  
  129. while (!recordsFile.eof()) {
  130.  
  131. string cardString;
  132.  
  133. getline(recordsFile, cardString);
  134.  
  135. //
  136. // Check for an empty line
  137. //
  138.  
  139. if (cardString != "") {
  140.  
  141. //
  142. // Process the card
  143. //
  144.  
  145. Card card;
  146.  
  147. card.cardType = cardString[0];
  148. card.city = cityNameFromCard(cardString);
  149.  
  150. if(!loadQuantitiesFromString(pricesForWarehouse(cardString), quantities, 3)){
  151. cout << "Failed to read quantities from the card. Skipping this card." << endl;
  152. continue;
  153. }
  154.  
  155. //
  156. // Put the quantities in the card.
  157. //
  158.  
  159. card.amount1 = quantities[0];
  160. card.amount2 = quantities[1];
  161. card.amount3 = quantities[2];
  162.  
  163. //
  164. // Choose the correct warehouse
  165. //
  166.  
  167. Warehouse& workingWarehouse = warehouseForNameFromArray(card.city, warehouses);
  168.  
  169. // Print out the card, since we want to do that
  170. // regardless of the contents of the card.
  171.  
  172. cout << card.description();
  173.  
  174. //
  175. // Handle shipments here...
  176. //
  177.  
  178. if (card.cardType == 's') {
  179.  
  180. // ...update the quantities...
  181.  
  182. workingWarehouse.quantities[0] += card.amount1;
  183. workingWarehouse.quantities[1] += card.amount2;
  184. workingWarehouse.quantities[2] += card.amount3;
  185.  
  186. // ..and print out the warehouse values.
  187.  
  188. cout << workingWarehouse.description();
  189.  
  190. }
  191.  
  192. // ... and Orders here.
  193.  
  194. else if(card.cardType == 'o'){
  195.  
  196. // First print out the card
  197.  
  198. double price = 0;
  199. bool orderFilled = true;
  200.  
  201. //
  202. // Process each of the desired items...
  203. //
  204.  
  205. for(int i=0; i <2; i++){
  206.  
  207. //
  208. // If the item is available, process the order...
  209. //
  210.  
  211. if (warehouseHasDesiredAmountOfItem(workingWarehouse, quantities[i], i)) {
  212.  
  213. // Add the item to the total cost, and
  214. // subtract from the total available.
  215.  
  216. price += quantities[i] * prices[i];
  217. workingWarehouse.quantities[i] -= quantities[i];
  218.  
  219. }
  220.  
  221. //
  222. // ... otherwise the item is not available in the requested warehouse.
  223. //
  224.  
  225. else{
  226.  
  227. Warehouse *alternateWarehouse = warehouseMostStockThatFillsItemAndAmount(warehouses, numberOfWarehouses, i, quantities[i]);
  228.  
  229. //
  230. // If there's no alternate warehouse, flag it.
  231. //
  232.  
  233. if (alternateWarehouse == NULL) {
  234. orderFilled = false;
  235. }
  236.  
  237. //
  238. // If there's an alternate warehouse,
  239. // then we should process from there.
  240. //
  241.  
  242. else{
  243.  
  244. // Charge an extra 10% and deduct from the
  245. // correct warehouse.
  246. price += quantities[i] * (prices[i] * 1.1);
  247. (*alternateWarehouse).quantities[i] -= quantities[i];
  248.  
  249. //
  250. // Print out that the item has been shifted.
  251. //
  252.  
  253. cout << quantities[i] << " of item " << i << " shipped from ";
  254. cout << (*alternateWarehouse).name << " to" << workingWarehouse.name;
  255.  
  256. //
  257. // Print out the description of the alternate warehouse.
  258. //
  259.  
  260. cout << (*alternateWarehouse).description() << endl;
  261. }
  262.  
  263.  
  264. }
  265. }
  266.  
  267. cout << workingWarehouse.description();
  268.  
  269. if (orderFilled) {
  270. cout << "Price: $" << price << endl;
  271. }
  272. else{
  273. cout << "Order Unfulfilled" << endl;
  274. }
  275.  
  276. }
  277.  
  278. }
  279. }
  280.  
  281. }
  282. return 0;
  283. }
  284.  
  285. //
  286. // Parses a string which contains dollar amounts
  287. // into an array of double values.
  288. //
  289. // For the code to work, we assume that prices are
  290. // embedded in a single line string, preceeded by
  291. // a dollar sign, and followed by a space. If the format
  292. // varies, this code won't work.
  293. //
  294. // IMPORTANT: We don't resize the buffer. So you have
  295. // to know how many strings you're planning to extract
  296. // ahead of time.
  297. //
  298.  
  299. bool pricesFromStringToArray(string input, double *buffer){
  300.  
  301. size_t position = 0;
  302.  
  303. int indexForBuffer = 0;
  304.  
  305. while (position < input.length()-1) {
  306.  
  307. size_t positionOfDollarSign = input.find("$", position);
  308.  
  309. //
  310. // If there are no dollar signs, just
  311. // set the position to out of range
  312. // of the while loop and it will exit.
  313. //
  314.  
  315. if (positionOfDollarSign == string::npos) {
  316. position = input.length();
  317. break;
  318. }
  319.  
  320. size_t positionOfTrailingSpace = input.find(" ", positionOfDollarSign-1);
  321.  
  322. //
  323. // We found the last dollar sign,
  324. // so take the substring from the
  325. // dollar sign until the end.
  326. //
  327.  
  328. if(positionOfTrailingSpace == string::npos){
  329.  
  330. //
  331. // Get the index of the last character
  332. //
  333.  
  334. positionOfTrailingSpace = input.length()-1;
  335. }
  336.  
  337.  
  338. //
  339. // By this point, we have to indices to use
  340. // to grab a substring from the input.
  341. //
  342.  
  343. string priceValueAsString;
  344.  
  345. priceValueAsString = input.substr(positionOfDollarSign+1, positionOfTrailingSpace-positionOfDollarSign);
  346.  
  347. //
  348. // Convert the string into a double via a stream.
  349. //
  350. // If for some reason the conversion fails, then
  351. // return false
  352. //
  353.  
  354. istringstream stringToDoubleConverter(priceValueAsString);
  355.  
  356. if(!(stringToDoubleConverter >> buffer[indexForBuffer])){
  357. return false;
  358. }
  359.  
  360. //
  361. // Move the "header" of the loop to
  362. // the next part of the string.
  363. //
  364.  
  365. position = positionOfTrailingSpace;
  366.  
  367. //
  368. // Don't forget to update the buffer index
  369. //
  370.  
  371. indexForBuffer++;
  372. }
  373.  
  374. return true;
  375. }
  376.  
  377. //
  378. // This method searches for
  379. // known city names and returns
  380. // the one that occurs in the
  381. // shipment card.
  382. //
  383. // Known city names are defined in the
  384. // global array "warehouseNames".
  385. //
  386. // Note that this is necessary because
  387. // city names have spaces.
  388. //
  389.  
  390. string cityNameFromCard(string card){
  391. for (int i = 0; i < numberOfWarehouses; i++) {
  392.  
  393. if (card.find(warehouseNames[i]) != string::npos) {
  394. return warehouseNames[i];
  395. }
  396. }
  397.  
  398. return NULL;
  399. }
  400.  
  401. //
  402. // This method returns the contents
  403. // of a card which follow its city name.
  404. //
  405. // Based on our format, this is the prices.
  406. //
  407.  
  408. string pricesForWarehouse(string card){
  409.  
  410. string warehouseName = cityNameFromCard(card);
  411.  
  412. size_t locationOfString = card.find(warehouseName);
  413.  
  414. return card.substr(locationOfString+warehouseName.length());
  415. }
  416.  
  417. //
  418. // Takes a string with prices, an array, and
  419. // the number of quantities we expect to load.
  420. //
  421.  
  422. bool loadQuantitiesFromString(string pricesString, int quantities[], const int numberOfQuantities){
  423.  
  424. istringstream conversionStream(pricesString);
  425.  
  426. for (int i = 0; i < numberOfQuantities; i++) {
  427. if(!(conversionStream >> quantities[i])){
  428. return false;
  429. }
  430. }
  431.  
  432. return true;
  433. }
  434.  
  435. //
  436. // Checks if a given warehouse has enough stock of a given item
  437. //
  438.  
  439. bool warehouseHasDesiredAmountOfItem(Warehouse warehouse, int desiredAmount, int item){
  440. return warehouse.quantities[item] >= desiredAmount;
  441.  
  442. }
  443.  
  444. //
  445. // Finds a warehouse from an array of warehouses
  446. // that can handle the requested item in the
  447. // quantity that was requested.
  448. //
  449.  
  450. Warehouse *warehouseMostStockThatFillsItemAndAmount(Warehouse warehouses[], int numberOfWarehouses, int desiredAmount, int item){
  451.  
  452. //
  453. // Prepare an empty warehouse
  454. //
  455.  
  456. Warehouse *workingWarehouse = NULL;
  457.  
  458. //
  459. // For each warehouse, check if it
  460. // has enough and more than the last
  461. // warehouse we checked.
  462. //
  463.  
  464. for (int i = 0; i<numberOfWarehouses; i++) {
  465. if (warehouses[i].quantities[item] >= desiredAmount) {
  466. if(workingWarehouse != NULL && warehouses[i].quantities[item] > (*workingWarehouse).quantities[item]){
  467. workingWarehouse = &warehouses[i];
  468. }
  469. }
  470. }
  471.  
  472. //
  473. // At this point we'll have a warehouse
  474. // that can fill the order. Return it.
  475. //
  476.  
  477. return workingWarehouse;
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement