收银机免费代码转换算法需要帮助

时间:2019-07-11 10:21:40

标签: javascript arrays multidimensional-array

我需要有关FreeCodeCamp上的收银机挑战的代码的帮助。我正在通过其他检查,但“ OPEN”检查除外

对于第二次检查,我得到了正确的细分[[QUARTER]:0.25],[“ QUARTER”:0.25],即四分之四,但我不知道如何将它们加在一起并以[“ QUARTER”的形式返回:0.5]。

对于第三项,故障几乎已经存在,但是它并没有夺走最后一分钱,因此我在最终故障中缺少一个[“ PENNY”:0.01]。当我检查剩余的零钱时,一分钱。

所以我真正需要帮助的是将更改作为每种类型单位的组合值返回,并查看为什么在第三种情况下它不返回总金额。

function checkCashRegister(price, cash, cid) {
  var cashAvailable = cid;
  var units = [
    ["PENNY", 0.01],
    ["NICKEL", 0.05],
    ["DIME", 0.1],
    ["QUARTER", 0.25],
    ["ONE", 1],
    ["FIVE", 5],
    ["TEN", 10],
    ["TWENTY", 20],
    ["ONE HUNDRED", 100]
  ].reverse()
  var cashAvailable = cid.slice().reverse()
  var stat = {
    status: '',
    change: []
  };
  var changeRequired = cash - price;
  var totalCash = cashAvailable.flat().filter(x => {
    return isNaN(x) == false
  }).reduce((a, b) => {
    return a + b
  }).toFixed(2)
  var unitsNeeded = []
  if (totalCash == changeRequired) {
    stat.status = 'CLOSED'
    stat.change = cid
  } else if (totalCash < changeRequired) {
    stat.status = 'INSUFFICIENT_FUNDS'
    stat.change = []
  } else if (totalCash > changeRequired) {
    for (var i = 0; i < units.length; i++) {
      while (changeRequired >= units[i][1] && cashAvailable[i][1] > 0) {
        unitsNeeded.push(units[i])
        cashAvailable[i][1] -= units[i][1]
        console.log((changeRequired -= units[i][1]).toFixed(2))
      }
      if (changeRequired > units[8][1]) {
        stat.status = 'INSUFFICIENT_FUNDS'
        stat.change = []
      } else {
        stat.status = 'OPEN';
        stat.change = unitsNeeded
      }
    }
  }

  return stat
}

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

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

这是两项检查。

2 个答案:

答案 0 :(得分:0)

不是解决方案,而是可以帮助您找到解决方案的提示:

您在此处为var totalCash指定一个文本(不是数字)。 toFixed()是一个数字格式化函数,有充分的理由返回字符串:由于基于浮点数的二进制实现,因此不存在像0.01这样的数字。不要将其用于四舍五入数字,它将无法正常工作!

  var totalCash = cashAvailable.flat().filter(x => {
    return isNaN(x) == false
  }).reduce((a, b) => {
    return a + b
  }).toFixed(2)

然后您对文本进行数值比较:

  if (totalCash == changeRequired) {
      ...
  } else if (totalCash < changeRequired) {
      ...
  } else if (totalCash > changeRequired) {
      ...
  }

解决方案:从上方删除toFixed(2)并仅将toFixed()用于可视化!

另一个提示: 在这里,您可以在changeRequired语句中修改console.log()的值。如果以后删除日志,代码的语义将发生变化:

console.log((changeRequired -= units[i][1]).toFixed(2))

更好:

changeRequired -= units[i][1];
console.log(changeRequired.toFixed(2));

答案 1 :(得分:0)

以下演示使用类和ES6 Map。演示中有详细评论。

/* This Map represents what the till has initially. Each value is 
the count of each type -- not the monetary value.*/
let funds = new Map([
  ['One Hundred', 2],
  ['Twenty', 10],
  ['Ten', 20],
  ['Five', 20],
  ['One', 50],
  ['Quarter', 20],
  ['Dime', 25],
  ['Nickel', 30],
  ['Penny', 100]
]);

/** Register(funds)
@Params: funds[Map]: key = name / value = count not monetary
A class that has the following methods:
  - set/get change 
      Allows direct access to this._change constructor property.
  - transact(cost, payment)
      Simply subtracts cost from payment to determine amount of
      change.
  - distribute(title = 'Change') 
      Takes a given amount and distributes it as currency in the
      smallest amount of denominations. If a title isn't passed, 
      the default is used.
  - remaining(map, title = 'Remaining in Till')
      Pass the Map of change and return a Map of remaining money
      from the fund Map. If a title isn't passed, the default is
      used.
  - displayMap(map)
      A utility method to aid in displaying Maps.
*/
class Register {
  constructor(funds) {
    this.denomination = new Map([
      ["One Hundred", 100],
      ["Twenty", 20],
      ["Ten", 10],
      ["Five", 5],
      ["One", 1],
      ["Quarter", 0.25],
      ["Dime", 0.1],
      ["Nickel", 0.05],
      ["Penny", 0.01]
    ]);
    this.distribution = funds;
    this._change = 0.00;
  }

  set change(money) {
    this._change = money;
  }

  get change() {
    return this._change;
  }

  transact(cost, payment) {
    this.change = payment - cost;
    return this.change;
  }

  distribute(title = 'Change') {
    let dist = new Map();
    dist.set('||', `~~~~~~~~~~[${title}]~~~~~~~~~~`);
    let total = Number(this.change);
    let denom = Array.from(this.denomination.entries());

    for (let [key, value] of denom) {
      if (total >= value) {
        let money = Math.floor(total / value);
        dist.set(key, money);
        total = total % value;
      }
    }
    return dist;
  }

  remaining(map, title = 'Remaining in Till') {
    for (let [key, value] of map.entries()) {
      if (this.distribution.has(key)) {
        let fund = this.distribution.get(key);
        this.distribution.set(key, (fund - value));
      }
    }
    map.set('|', `~~~~~~~~~~[${title}]~~~~~~~~~~`);
    return this.distribution;
  }

  displayMap(map) {
    for (let [key, value] of map.entries()) {
      console.log(key + ': ' + value);
    }
  }
}

// Instantiate class instance as `r` pass the funds Map
const r = new Register(funds);

// Arbitrary values
let cost = 252.63;
let payment = 300.00;

// set/get this.change from constructor
r.transact(cost, payment);

// Returns the change in the least amount of denominations
const dist = r.distribute();

// Returns the remaining count of each denomination after change
const till = r.remaining(dist);

// Display Maps
r.displayMap(dist);
r.displayMap(till);