Skip to content

luizvictor19/Water-Jug-Challenge

Repository files navigation

Water Jug Challenge Machine

Application Link

Get Start

If you want to run the application locally you can start cloning it by HTTPS or SSH as you wish


"git clone https://github.com/luizvictor19/Water-Jug-Challenge.git" or "git clone git@github.com:luizvictor19/Water-Jug-Challenge.git"


Enter the folder with "cd Water-Jug-Challenge/" and install the dependencies with "yarn"


Run "yarn dev" to get the local application link and paste it at the browser

Used Libraries

  • React Router Dom
  • Styled Components

Organization

The main complex logics are located at Utils Folder, besides that the structure is simple, with separations by folders like pages, components, routes, styles, typescript types and others assets.

Inside the Functions

Return the greatest common divisor of bucket Y and bucket X

const greatestCommonDivisor = (bucketY: number, bucketX: number): number => {
  if (bucketX == 0) {
    return bucketY;
  } else {
    return greatestCommonDivisor(bucketX, bucketY % bucketX);
  }
};

Get the steps list when there is a solution

const getStepsList = (
  fromBucket: number,
  toBucket: number,
  finalAmount: number,
  invertResponse: boolean
): Array<IStepsList> => {
  let steps = [];
  let from = fromBucket;
  let to = 0;

  !invertResponse
    ? steps.push({
        explanation: `Fill Jug X with ${from} litters`,
        bucketXAmount: `${from}`,
        bucketYAmount: `${to}`,
      })
    : steps.push({
        explanation: `Fill Jug Y with ${from} litters`,
        bucketXAmount: `${to}`,
        bucketYAmount: `${from}`,
      });

  while (from != finalAmount && to != finalAmount) {
    let maximumAmountCapacity = Math.min(from, toBucket - to);

    to += maximumAmountCapacity;
    from -= maximumAmountCapacity;

    !invertResponse
      ? steps.push({
          explanation: `Transfer ${maximumAmountCapacity} litters from bucketX to bucketY`,
          bucketXAmount: `${from}`,
          bucketYAmount: `${to}`,
        })
      : steps.push({
          explanation: `Transfer ${maximumAmountCapacity} litters from bucketY to bucketX`,
          bucketXAmount: `${to}`,
          bucketYAmount: `${from}`,
        });

    if (from == finalAmount || to == finalAmount) break;

    if (from == 0) {
      from = fromBucket;
      !invertResponse
        ? steps.push({
            explanation: `Fill Jug X with ${from} litters`,
            bucketXAmount: `${from}`,
            bucketYAmount: `${to}`,
          })
        : steps.push({
            explanation: `Fill Jug Y with ${from} litters`,
            bucketXAmount: `${to}`,
            bucketYAmount: `${from}`,
          });
    }

    if (to == toBucket) {
      to = 0;
      !invertResponse
        ? steps.push({
            explanation: `Empty Jug Y`,
            bucketYAmount: `${to}`,
            bucketXAmount: `${from}`,
          })
        : steps.push({
            explanation: `Empty Jug X`,
            bucketYAmount: `${from}`,
            bucketXAmount: `${to}`,
          });
    }
  }
  return steps as Array<IStepsList>;
};

Return the best solution or no solution if there isn't one

export const WaterJugChalangeBestSolution = (
  bucketX: number,
  bucketY: number,
  amountWanted: number
): Array<IStepsList> | string => {
  let invertStepString = false;

  if (bucketX > bucketY) {
    let oldBucketX = bucketX;
    bucketX = bucketY;
    bucketY = oldBucketX;
    invertStepString = true;
  }

  if (
    amountWanted > bucketY ||
    amountWanted % greatestCommonDivisor(bucketY, bucketX) != 0 ||
    bucketX < 0 ||
    !Number.isInteger(bucketX) ||
    bucketY < 0 ||
    !Number.isInteger(bucketY) ||
    amountWanted <= 0
  )
    return "No solution";

  if (
    getStepsList(bucketY, bucketX, amountWanted, invertStepString).length <
    getStepsList(bucketX, bucketY, amountWanted, invertStepString).length
  ) {
    return getStepsList(bucketY, bucketX, amountWanted, !invertStepString);
  } else {
    return getStepsList(bucketX, bucketY, amountWanted, invertStepString);
  }
};