Банк для менее надежных друзей

12

Вступление

Вы получили работу в качестве министра финансов в своей вымышленной стране на заднем дворе. Вы решили создать свой собственный банк в своей стране для себя и своих менее надежных друзей. Поскольку вы не доверяете своим друзьям, вы решили написать программу для проверки всех транзакций, чтобы предотвратить перерасход ваших друзей за вымышленную валюту и разрушение вашей экономики.

задача

Учитывая начальный баланс и все транзакции, отфильтруйте все транзакции, в которых кто-то пытается перерасходовать, и заблокируйте любого, кто пытается перерасходовать (включая попытку перерасхода на закрытый счет), когда-либо снова использовать ваш банк, отфильтровывая будущие транзакции с его или из него. / ее банковский счет.

Ввод, вывод

Два списка Aи Bкак вход и список Cкак выход. Aэто начальный баланс каждого аккаунта в формате [["Alice", 5], ["Bob", 8], ["Charlie", 2], ...]. Bсписок транзакций в формате [["Bob", "Alice", 3], ["Charlie", "Bob", 5], ...]где ["Bob", "Alice", 3]означает, что Боб хочет заплатить Алисе 3 единицы валюты. Cдолжен иметь тот же формат, что и B. A, BИ Cможет быть в любом подходящем формате.

Тестовые случаи

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: []

счет

Это , выигрывает самый короткий код в байтах на каждом языке.

Герман Л
источник
Насколько строг формат IO? Может Aбыть также словарь, или список кортежей?
Лайкони
@Laikoni Или даже просто список формы ["A", 2, "B", 3, "C", 5]?
Эрик Outgolfer
Похожий тест: A: [["A", 2], ["B", 3], ["C", 4]], B: [["A", "B", 3], ["C", "B", 4]], C: [["C", "B", 4]](действительная сделка после недопустимой один).
Arnauld
3
Что произойдет, если кто-то попытается перерасходовать средства, а предполагаемый получатель уже перерасходовал средства?
Нитродон
Там нет запятой в ["B" 3] во втором и третьем тестовых случаях
Джо Кинг,

Ответы:

5

JavaScript (ES6), 91 88 79 байт

Сохранено 8 байт благодаря @NahuelFouilleul

Принимает ввод в синтаксисе карри (a)(b).

a=>b=>b.filter(([x,y,z])=>(a[x]+=z)<0&a[y]<0?a[y]-=z:0,a.map(([x,y])=>a[x]=~y))

Контрольные примеры

Украшенный и прокомментированный

a => b =>                 // given the two lists a and b
  b.filter(([x, y, z]) => // for each (x = payer, y = payee, z = amount) in b:
    (a[x] += z) < 0 &     //   update the payer's account; if it's still valid
    a[y] < 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]) =>     //   initialization: for each (x = owner, y = amount) in a:
      a[x] = ~y           //     set up this account (>= 0: closed, -1: $0, -2: $1, etc.)
    )                     //   end of map()
  )                       // end of filter()
Arnauld
источник
как насчет a=>b=>b.filter(([x,y,z])=>(a[x]-=z)>0&a[y]>0?a[y]+=z:0,a.map(([x,y])=>a[x]=y+1))портирования Perl решения на JavaScript?
Науэль Фуйе
@NahuelFouilleul Гораздо лучше. Благодарность!
Арно
2

Python 2 , 103 байта

A,B=input()
C=[]
for i in B:
 N,P,M=i
 if M>A[N]:A[N]=-1
 if A[N]>-1<A[P]:A[N]-=M;A[P]+=M;C+=i,
print C

Попробуйте онлайн!

-12 благодаря овс .

Дольше из-за ограничений формата вывода:

Cдолжен иметь тот же формат, что и B.

В противном случае я мог бы сделать это для 92 байтов:

A,B=input()
for(N,P,M)in B:
 if M>A[N]:A[N]=-1
 if A[N]>-1<A[P]:A[N]-=M;A[P]+=M;print(N,P,M)
Эрик Outgolfer
источник
103 байт
овс
@ovs Вау, это умно
Эрик Outgolfer
2

Рубин , 57 байт

->a,b{b.select{|(s,r,x)|a[r]+=x if[a[s]-=x,a[r]].min>-1}}

Попробуйте онлайн!

Принимает ввод Aкак Hashв формате {"A"=>2, "B"=>3}. Ввод Bи вывод Cв предложенном формате.

объяснение

->a,b{                      # lambda function taking arguments A and B
b.select{|(s,r,x)|              # select items in B that return truthy (s = sender, r = receiver, x = amount)
            a[s]-=x,                # subtract amount from sender
        if [         a[r]].min>-1   # check if the smaller of the balances is non-negative
                                    # (true if both values are non-negative)
a[r]+=x                             # if so, add to the receiver's balance
}                               # the select function returns truthy when the above if statement passes
}
Джастин Маринер
источник
1

C ++, 193 байта

Введите A как std::map, B как std::list.

#import<bits/stdc++.h>
using s=std::string;struct p{s a,b;int c;};using t=std::list<p>;t f(std::map<s,int>A,t B){t C;for(p&i:B)(A[i.a]-=i.c)<0|A[i.b]<0?0:(C.push_back(i),A[i.b]+=i.c);return C;}

Попробуйте онлайн!

Колера Су
источник