Does Cash Register challenge support arbitrary answers?

Tell us what’s happening:
Describe your issue in detail here.

  **Your code so far**

const amounts = {
PENNY: 0.01,
NICKEL: 0.05,
DIME: 0.1,
QUARTER: 0.25,
ONE: 1,
FIVE: 5,
TEN: 10,
TWENTY: 20,
"ONE HUNDRED": 100
};

const typesSorted = [ //By the most value to the least value
"ONE HUNDRED",
"TWENTY",
"TEN",
"FIVE",
"ONE",
"QUARTER",
"DIME",
"NICKEL",
"PENNY"
];

let lst = [];
let lstTypes = [];
let states = {};
let ans = {};

function addToAns(pos){
  let type = lstTypes[pos];
  if(!(type in ans)){
    ans[type] = 0;
  }
  ans[type] += lst[pos];
}

function stateGo(pos, rem){
if(Math.abs(rem) < 1e-5){
  return true;
}
if(rem < 0){
  return false;
}
if(pos >= lst.length || lst[pos] > rem){
  return false;
}
let strState = `${pos} ${rem}`;
if(strState in states){
  return false;
}
states[strState] = true;
if(stateGo(pos+1, rem-lst[pos])){
  addToAns(pos);
  return true;
}
if(stateGo(pos+1, rem)){
  return true;
}
return false;
}

function checkCashRegister(price, cash, cid) {
let smCID = 0;
let lstTmp = [];
cid.forEach((key) => {
  let type = key[0];
  let amount = key[1];
  smCID += amount;
  let cnt = Math.round(amount / amounts[type]);
  let amountOne = amounts[type];
  while(cnt > 0){
    let some = Math.ceil(cnt / 2);
    lstTmp.push([Math.round(100 * some * amountOne) / 100, type]);
    cnt -= some;
  }
});
let diff = cash - price;
if(smCID < diff){ //insufficient
  return {status: "INSUFFICIENT_FUNDS", change: []};
} else if(Math.abs(smCID - diff) < 1e-5){ //Equal
  return {status: "CLOSED", change:cid};
} else { //Check if it is possible
  lstTmp = lstTmp.sort((a, b)=>{return a[0] > b[0];}); //Increasing order
  lstTmp.forEach((key) => {lst.push(key[0]); lstTypes.push(key[1]);});
  if(stateGo(0, diff)){
    let result = [];
    typesSorted.forEach((type) => {
      if(type in ans){
        result.push([type, Math.round(100 * ans[type]) / 100]);
      }
    });
    //Maybe I should have sorted it in another way?
    //result = result.sort((a, b) => {return a[1] < b[1]});
    return {status: "OPEN", change: result};
  } else {
    return {status: "INSUFFICIENT_FUNDS", change: []};
  }
}
}

  **Your browser information:**

User Agent is: Mozilla/5.0 (X11; Linux x86_64; rv:92.0) Gecko/20100101 Firefox/92.0

Challenge: Cash Register

Link to the challenge:

If I am getting the problem right, there shouldn’t be anything wrong with my code. I checked its output for one of the failed tests and the output was sane (it was possible, and its sum was as requested). Can there be any other reasons why it fails? For example my output should be sorted in another way, or judge only accepts solutions giving the exact same output that it has?

Your code contains global variables that are changed each time the function is run. This means that after each test completes, subsequent tests start with the previous value. To fix this, make sure your function doesn’t change any global variables, and declare/assign variables within the function if they need to be changed.

Example:

var myGlobal = [1];
function returnGlobal(arg) {
  myGlobal.push(arg);
  return myGlobal;
} // unreliable - array gets longer each time the function is run

function returnLocal(arg) {
  var myLocal = [1];
  myLocal.push(arg);
  return myLocal;
} // reliable - always returns an array of length 2
1 Like

Thanks for your reply. Using global variables doesn’t seem to be a problem. Each test case runs separately from the others (meaning global variables aren’t preserved across test cases). In any case, I changed it and still got no luck.

For example, for the test case

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]])

for which the official answer is

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

I return

{ status: 'OPEN',
  change: [ [ 'DIME', 0.2 ], [ 'NICKEL', 0.1 ], [ 'PENNY', 0.2 ] ] }

which is a valid answer, but not the one the judge expects. My only concern is if this has something to do with having to sort in a different order (I tried sorting in decreasing amount of money paid using each currency unit, but still no luck).

Can we fix the judge (or is it my fault?) to accept other valid answers too?

Also, this problem is just the general case knapsack, or am I overthinking it?

the test will pass only with the answers it expects - you should give priority to the highest coin value when giving change

if you want to discuss changes to the project, you can open a github issue

1 Like

Thank you, I got it. :smiley:
In any case, it wouldn’t hurt if the judge accepted other valid outputs too (or at least the statement somehow made sure there is only one valid output for each test case).

it would complicate the tests a lot, but it may be possible to do. I don’t know if it would be an accepted change tho.
If you want to discuss about changes to the project, please open a github issue

The wording on the instructions should be adjusted I think: what you’re describing is a slightly different problem. The problem as tested asks for the best solution, not any solution. As stated, if you look at the test cases you have to prioritise the largest coin value, the smallest total number of coins: you have to pack as efficiently as possible

This isn’t true. The global state is preserved in the test suite. Or at least it should be, to discourage abuse of global variables in this way.

edit: Huh, I’ve verified that this projects seems to be resetting global state. That, in my opinion, is a huge mistake. Letting solutions that [ab]use the global space in this way is not good.

Yep, the bug has been introduced in all lessons. That’s just… great.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.