*JavaScript Algorithms and Data Structures Projects: Cash Register

Tell us what’s happening:

Can I get any suggestion how to move on in here?

Your code so far


function checkCashRegister(price, cash, cid) {

return {status: "INSUFFICIENT_FUNDS", change: []};
}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36.

Challenge: Cash Register

Link to the challenge:

Hey there!

Yes, the cash register is a hard project!

Do you understand the description of the project?
Do you understand the given tests and how you could solve them by hand?

2 Likes

Greetings santiagodeleondecar1,

Figuratively speaking, you possess a cash drawer containing a specific combination of various currency denominations, something represented with the ‘cid’ parameter. At this point, the cash draw has a balance, the sum of the contained currency.

A purchase transaction occurs when an item selling for a specific ‘price’, is paid for using ‘cash’. This transaction will have several real-world impacts, including the exchange (or not) of an item, and the exchange (or not) of currency, the latter of which will affect (or not) the composition and balance of the cash draw because the purchaser will need to be furnished (or not) an amount of change.

The aim of the exercise is to model the impact this transaction has on the cash draw.

Several cash draw conditions or impacts are identified in the problem statement. These are convenient tags for describing certain combination of factors, and include:

  • INSUFFICIENT_FUNDS (cash >= price, cid < change)
  • INSUFFICIENT_FUNDS (cash >= price, cid >= change, no suitable denomination available)
  • OPEN (cash >= price, cid > change)
  • CLOSED (cash >= price, cid == change)

A case could also be made for adding the following condition:

  • INSUFFICIENT_PAYMENT (cash < price)

something that could prove useful in input validation, but doesn’t impact the cash drawer.

To proceed from the starting point you posted, you could:

  • Identify values you would need to compute such as the total amount in the ‘cid’, and the amount of change to furnish, this probably being the key value since it determines so much that follows

  • Perform input validation which, aside from eliminating erroneous values, will help identify some conditions at an early stage

  • Determine a suitable mapping of denominations to amounts, to allow easy lookup, and the performance of relevant arithmetic operations

  • Model the cash drawer (starting with an empty cash draw may prove useful)

Many more issues, of course, the surface has barely been scratched !

Finally, be aware that this project is quite challenging (I would say the most challenging, by far, of the five), so try not to be overwhelmed. Take things step-by-step, stay determined and focused.

2 Likes

let us know what is still confusing you about it

Something that helped me and might work for you as well to write your code in a way that made the most sense, is to actually get a bunch of bills, pennies nickels and dimes and put each denomination in its own pile. same as you would in a cash register.

then try again to work out the problem.

1 Like

Thanks for your early answer. I was thinking about it from monday. I started earlier today. I think I was tried when I tried to solve this and I am thankfil with yuu for your kind answer.

This is useful. I had a hard time to understand this excercises. It is difficult this excercise really. Your explanation will be used by me because it is clear and concise. Thanks!

This is diffcult. I got an explanation from @ajborla. I am still having a hard time doing it, but I am on it. I am not very sure, but I am trying in here. Every one of you has been magnificent @miku86 @kravmaguy @kravmaguy. Thanks!

2 Likes

I am also trying this question, but still finding it difficult to understand. I don’t understand the output returned by the test cases. specifically when the status is OPEN. For e.g.

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]])

In this call, I know the change would be (20 - 19.5) i.e. 0.5 but which currency do I have to return is what confusing me. For this, the output is expected as

{status: "OPEN", change: [["QUARTER", 0.5]]}

Why did we choose QUARTER and not any other denomination? It’d be really helpful if someone could answer it.

1 Like

@miku86 @miku86 @kravmaguy @gutsytechster
How may I work with CID? I think these are the cases.

function checkCashRegister(price, cash, cid) {

          

          if(cash>=price){

return {status: "OPEN",change: cid}

          }else if(cash==price){

return {status: "CLOSED",change: cid}

          }

return {status: "INSUFFICIENT_FUNDS", change: []}
            

}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

I think these are the cases

su codigo actualmente no pasa ninguna prueba. e por favor autoformate su codigo la proxima vez que publicas.

How may I work with CID?

@ajborla dijo como asi:

Identify values you would need to compute such as the total amount in the ‘cid’, and the amount of change

if (cash >= price)

es no es util. puedes asumir que un cliente no intentaria pagar en efectivo menos del precio

return { status: "OPEN", change: cid }

no devuelves esto. Por que intenta pagarle al cliente todo el cambio en su caja? tienes que devolverle el cambio que se le debe, ni mas, e ni menos. tu no esta calculando esto.

} else if (cash == price) {

como sabes eso? esta linea no es util. la prueba no pide eso.

    `return { status: "CLOSED", change: cid }`

si el efectivo con el que esta pagan es igual al precio del articulo que esta comprando, entonces no hay nada que hacer. no le de al cliente todo el cambio en su registro.

how to work with cid:
primero debe calcular la diferencia entre el efectivo menos el precio.

ajborla "need to compute such as the total amount in the ‘cid’:

por esso necicitas que ciclar(loop through) en todo los subarrays que tienes en su cid variable. sume todos esos valores para saber cuanto posee en su registro. no has hecho esto.
necesita crear otro objeto o un array que pueda comparar con las monedas dentro del cid. como… la computadora no sabe cuanto vale un penny o un quarter o un dollar o otra moneda… la computadora no sabes nada esso.

usara esto en sus calculos para saber si pagar al cliente con una moneda en particular. si el valor de una moneda es mayor de lo que le debe, no le pagara con eso. avanzara al siguiente valor mas bajo.

cauando haces eso, tambien debe verificar que realmente tenga algo de esa moneda que existe. no le pagues con monedas que no existen.

return {status: "INSUFFICIENT_FUNDS", change: []}

solo hace esto si la suma de todo el cambio que tiene en su caja registradora es menor que el cambio que debe … como dije, necesita calcular cuanto cambio realmente debe. no estas haciendo eso. Despues de calcular la cantidad de cambio que debe, debe sumar todo lo que hay en su caja para saber si realmente no tienes suficiente en su caja para devolver lo que escribiste enicima

1 Like

I will try that again. Lo haré de nuevo. Thanks!

1 Like

what you mean you dont understand cases when the status is open?
it will stay open as long as you still have change left over in your cash register after youve completed the transaction. Only close the register if you have nothing left in it.

pay him out from the largest currency that you have that is less than the money that you owe. while you are paying him out make the adjustments to what you actually have in the register while at the same time decreasing from the change you owe

what currency do I have to return?

all the coins/bills that together will add up exactly to the amount you owe. not more, not less.

because you owe exactly fifty cents. if you will ask “why can’t I just pay him out with dimes?” in the example you showed you do have enough. however its not what Ive used or other solutions ive looked at have used to pass the challenge. use this technique:

you need an object or array that you can compare to the coins you have in the drawer. you will use this if the sum of everything in your drawer is greater than the change you owe. arrange the object or array that you made with the coin values in such a way that it matches up with what you have in your cid.

you will start from the highest value and you will ask yourself two questions "does there exist some coins at this value in my drawer? is the monetary value of ONE of these coins/bills less than or equal to the change that is due to the customer?

if you answered yes to the above two questions than you will use that coin, subtract from what you have in your drawer and also from the total change owed to the customer. if not skip over that coin and go down to the next coin that is smaller than it.

after you have gone through all the compartments in your drawer ask yourself if the total change is greater than zero? if it is it means you do not have sufficient funds to pay out.

1 Like

Do you have an idea to solve the problem for getting the min number of cash from the cash register to give to the customer?

function checkCashRegister(price, cash, cid) {

  

 var change=cash-price;

 var numArr=[];

 for(let i=0;i<cid.length;i++){

               

               numArr.push(cid[i][1]/change)

 } 

 

console.log(numArr)

const min = Math.min(...numArr)

console.log(min)

}

checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

please format your code better next time for better readability. i.e. the indentations…

ive not understood. what do mean get the min number of cash? you will give him exactly the amount of cash or you should give him nothing at all.

You wrote a better code this time, you are getting closer to solving it, the variable you have created called “change” is good so leave that. but delete that variable you have called min.

instead do this, ive only added one line to what you wrote:

    let sumOfTotalMoneyInDrawer=0
    for (let i = 0; i < cid.length; i++) {
        // numArr.push(cid[i][1] / change)
        sumOfTotalMoneyInDrawer+=cid[i][1]
    }

now you have the total of all the money in the register. Continue forward from here and see what more work you can get done. you already have enough information now to pass some of the tests. post your next code when you are ready.

1 Like

Thanks very much for the information!

1 Like

@santiagodeleondecar1 have you added some new code?

about your code that you last wrote and about that whole min thing you were doing:

Trying to see how many times the amount that you owe the customer will fit into the total amount that you possess of a certain denomination. and then you were trying to get the smallest of those values. I dont think that will get you anywhere.

you should create an object or array that defines how much each coin/denomination/bill is worth.

if the the sumOfTotalMoneyInDrawer is not equal to the change you owe the customer and is not less than what you owe the customer you will use this object/array in your logic. after your done going through all your denominations and making your payouts, you should again confirm that the debt/change has been paid off. as you can not pay a partial debt. only exact.

1 Like

Yes, I have added some new code, but I am having problems with the return of the object. I am not getting the correct answer yet. Thanks for asking. @gutsytechster @ajborla @miku86. Thanks everybody for participate in this forum.

function checkCashRegister(price, cash, cid) {

let  change   =   cash  -   price   ;

let   arr     =   [                 ] ;

let   money   =        

[ 

      [   "PENNY"  ,       0.01   ]   ,  

  

      [   "NICKEL" ,       0.05   ]   , 

      [   "DIME"   ,        0.1   ]   ,

  

      [   "QUARTER",       0.25   ]   , 

  

      [   "ONE"    ,          1   ]   , 

  

      [   "FIVE"   ,          5   ]   ,  

  

      [    "TEN"   ,         10   ]   , 

   

      [    "TWENTY",         20   ]   , 

   

      ["ONE HUNDRED",       100   ]

  

]   

          for (  let  i  =  0 ;   i <  money.length  ; i ++  )   {

           arr.push(    change    /   money[    i   ]   [   1    ]   )

      }

 const    intArr   =    [                               ]   ;

           for (  let  i  =  0 ;   i <  money.length  ; i ++  )   {

                       

           if     (    Number.isInteger(    arr[   i   ]   )   )   {

                            

                            intArr.push(    arr[   i   ]    )   ;

                       

                  }    

        

      }

//console.log(intArr)

const     min           =     Math.min(   ...intArr   )        ;

const isLargeNumber     =     (   e   )     =>    e   ==     min;            

            

let           index   =            arr.findIndex(   isLargeNumber   )   ;

      

let    newQtyOfBills    =      cid[  index ][  1    ] -   change          ;

let           newObj      =                                                         [   

  

                      [   

  "status"

                        ]                    

    

]       

console.log(newObj)

          if   (    [  cid   [  index ][  1   ]]      >=         change       ){

      return  console.log("{","status",[[cid   [  index ][  0   ], change ]],"}")

    }

      

}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

How may I write the object in order to get the correct answer?

function    checkCashRegister   (price    ,     cash    ,     cid   )     {

    

    var     change    =     cash    -   price   ;

    var     money     =     [

  

  [   "PENNY"     ,     0.01      ]    ,

 

  [   "NICKEL"    ,     0.05      ]    ,

 

  [    "DIME"     ,     0.1       ]    ,

 

  [    "QUARTER"  ,     0.25      ]    ,

 

  [    "ONE"      ,     1        ]     ,

 

  [    "FIVE"     ,     5         ]    ,

 

  [     "TEN"      ,    10         ]    ,

 

  [    "TWENTY"    ,     20        ]   ,

 

  [    "ONE HUNDRED",    100      ]

]

var   arr   =   []    ;

                            for(    let     i   =   0; i<money.length   ;i++){

                                  let intMon=  change/money[i][1]

                                   

                                   if(Number.isInteger(intMon)){

                                        arr.push(intMon)                         

                                   }

                                                      

                            } 

                                        

            let   minNumb   =   Math.min(   ...arr   )                  ;

                        

            let isLargeNumber   =    (element) => element == minNumb;

           

            let indexMin=arr.findIndex(isLargeNumber)    ;

       

            let st=["OPEN","CLOSED"]

                    

                  if(cash>price){

                           

                  }

            return {status: "INSUFFICIENT_FUNDS", change: []}      

}

checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);

you have to format your code in a way that is readable. use prettier for vs code, if you do not want to do this, please find another option to format it. you can also use the online version prettier.io

How may I write the object in order to get the correct answer?

the object you wrote is fine. all your other code i do not like

ive formatted your code for better readability:

function checkCashRegister(price, cash, cid) {
    var change = cash - price;
  
    var money = [
      ["PENNY", 0.01],
  
      ["NICKEL", 0.05],
  
      ["DIME", 0.1],
  
      ["QUARTER", 0.25],
  
      ["ONE", 1],
  
      ["FIVE", 5],
  
      ["TEN", 10],
  
      ["TWENTY", 20],
  
      ["ONE HUNDRED", 100]
    ];
  
    var arr = [];
  
    for (let i = 0; i < money.length; i++) {
      let intMon = change / money[i][1];
  
      if (Number.isInteger(intMon)) {
        arr.push(intMon);
      }
    }
  
    let minNumb = Math.min(...arr);
  
    let isLargeNumber = element => element == minNumb;
  
    let indexMin = arr.findIndex(isLargeNumber);
  
    let st = ["OPEN", "CLOSED"];
  
    if (cash > price) {
    }
  
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  }
  
  console.log(checkCashRegister(19.5, 20, [
    ["PENNY", 1.01],
    ["NICKEL", 2.05],
    ["DIME", 3.1],
    ["QUARTER", 4.25],
    ["ONE", 90],
    ["FIVE", 55],
    ["TEN", 20],
    ["TWENTY", 60],
    ["ONE HUNDRED", 100]
  ]));

the last line of your code:

    return { status: "INSUFFICIENT_FUNDS", change: [] };

you are always returning insufficient funds. that is incorrect. you should not do this.

    if (cash > price) {
    }

the above line serves no purpose. ive explained in spanish , maybe it was not clear. the cash is always greater than the price. no customer will attempt to pay you less. accept that as fact.

why have you not added up all the cash in your drawer as I showed you? you have to do this.

    for (let i = 0; i < money.length; i++) {
      let intMon = change / money[i][1];
  
      if (Number.isInteger(intMon)) {
        arr.push(intMon);
      }
    }

  let minNumb = Math.min(...arr);

  let isLargeNumber = element => element == minNumb;

  let indexMin = arr.findIndex(isLargeNumber);

so… you are building an array of integers telling you how many times a certain denomination value can fit into the money you owe, and then your taking the smallest number in that arr and finding the index of the largest coin value that you can pay off your debt with. I would advise you not try to do it that way.

all you will find out using that way of thinking is that you are able to theoretically pay off your 50 cent debt with 2 quarters, and as youve found out that in the same vain you can also pay it with 50 pennies, or 10 nickels, or five dimes… so yes you are choosing the largest value, but how do you even know you have two quarters in your possession? what if the debt is 60 cents? what will you do then? you need to consider these things.

you are not checking how much monies you actually have of a specific coin, no place in your code are you adding up all your money in your drawer, no place in your code are you subtracting frow what you actually have in your possession while making your payouts while at the same time subtracting from your debt to the customer

1 Like

Your answer is really fine. I am going to do it over. Thanks! Thanks for your your time, I appreciate it that so much.