A bank for less Trustworthy Friends Introduction

You have gotten a job as the minister of finance in your made-up country in your back yard. You have decided to make your own bank in your country for you and your less trustworthy friends. Since you don't trust your friends, you have decided to write a program to validate all transactions to stop your friends from overspending your made-up currency and ruining your economy.

Task

Given the starting balance and all transactions, filter out all transactions where someone tries to overspend and block anyone who tries to overspend (this includes trying to overspend to a closed account) from ever using your bank again by filtering out future transactions to or from his/her bank account.

Input/Output

Two lists A and B as input and a list C as output. A is the starting balance of each account with the format [["Alice", 5], ["Bob", 8], ["Charlie", 2], ...]. B is a list of transactions with the format [["Bob", "Alice", 3], ["Charlie", "Bob", 5], ...] where ["Bob", "Alice", 3] means that Bob wants to pay Alice 3 currency units. C should have the same format as B. A, B and C may be in any reasonable format.

Test Cases

A: [["Alice", 5], ["Bob", 2]]
B: [["Alice", "Bob", 5], ["Bob", "Alice" 7]]
C: [["Alice", "Bob", 5], ["Bob", "Alice" 7]]

A: [["A", 2], ["B", 3], ["C", 5]]
B: [["C", "A", 2], ["B", "C", 4], ["A", "B", 2]]
C: [["C", "A", 2]]

A: [["A", 2], ["B", 3]]
B: [["A", "B", 2], ["A", "B", 2]]
C: [["A", "B", 2]]

A: [["A", 4], ["B", 0]]
B: [["A", "B", 1], ["A", "B", 5], ["A", "B", 2]]
C: [["A", "B", 1]]

A: [["A", 2], ["B", 3], ["C", 4]]
B: [["A", "B", 3], ["C", "B", 4]]
C: [["C", "B", 4]]

A: [["A", 2], ["B", 3], ["C", 4]]
B: [["A", "B", 3], ["B", "A", 4], ["C", "B" 2]]
C: []


Scoring

This is code-golf, the shortest code in bytes in each language wins.
JavaScript (ES6), 91 88 79 bytes

Saved 8 bytes thanks to @NahuelFouilleul

Takes input in currying syntax (a)(b).

a=&gt;b=&gt;b.filter(([x,y,z])=&gt;(a[x]+=z)&lt;0&amp;a[y]&lt;0?a[y]-=z:0,a.map(([x,y])=&gt;a[x]=~y))


Test cases



let f =

a=&gt;b=&gt;b.filter(([x,y,z])=&gt;(a[x]+=z)&lt;0&amp;a[y]&lt;0?a[y]-=z:0,a.map(([x,y])=&gt;a[x]=~y))

console.log(JSON.stringify(f(
  [["Alice", 5], ["Bob", 2]]
)(
  [["Alice", "Bob", 5], ["Bob", "Alice", 7]]
)))

console.log(JSON.stringify(f(
  [["A", 2], ["B", 3], ["C", 5]]
)(
  [["C", "A", 2], ["B", "C", 4], ["A", "B", 2]]
)))

console.log(JSON.stringify(f(
  [["A", 2], ["B", 3]]
)(
  [["A", "B", 2], ["A", "B", 2]]
)))

console.log(JSON.stringify(f(
  [["A", 4], ["B", 0]]
)(
  [["A", "B", 1], ["A", "B", 5], ["A", "B", 2]]
)))

console.log(JSON.stringify(f(
  [["A", 2], ["B", 3], ["C", 4]]
)(
  [["A", "B", 3], ["C", "B", 4]]
)))




Beautified and commented

a =&gt; b =&gt;                 // given the two lists a and b
  b.filter(([x, y, z]) =&gt; // for each (x = payer, y = payee, z = amount) in b:
    (a[x] += z) &lt; 0 &amp;     //   update the payer's account; if it's still valid
    a[y] &lt; 0 ?            //   and the payee's account is also valid:
      a[y] -= z           //     update the payee's account
    :                     //   else:
      0,                  //     do nothing
    a.map(([x, y]) =&gt;     //   initialization: for each (x = owner, y = amount) in a:
      a[x] = ~y           //     set up this account (&gt;= 0: closed, -1: $0, -2: $1, etc.)
    )                     //   end of map()
  )                       // end of filter()