不太值得信赖的朋友的银行


12

介绍

您已经在后院的虚假国家担任财政部长的工作。您已决定在您的国家/地区为自己和不那么可信赖的朋友建立自己的银行。由于您不信任朋友,因此您决定编写一个程序来验证所有交易,以防止朋友过度消费您的虚构货币并破坏您的经济。

任务

给定初始余额和所有交易,请过滤掉某人试图超支的所有交易,并阻止所有试图超支的人(包括试图超支至已关闭账户的人)再次使用您的银行,方法是过滤掉往来于他的银行的交易。 /她的银行帐户。

输入输出

两个列表AB作为输入和一个列表C作为输出。A是格式为的每个帐户的期初余额[["Alice", 5], ["Bob", 8], ["Charlie", 2], ...]B是具有以下格式的交易列表,[["Bob", "Alice", 3], ["Charlie", "Bob", 5], ...]其中["Bob", "Alice", 3]表示Bob想要支付Alice 3货币单位。C格式应与相同BAB并且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

@Laikoni甚至只是表单列表["A", 2, "B", 3, "C", 5]
暴民埃里克(Erik the Outgolfer)

建议测试用例:A: [["A", 2], ["B", 3], ["C", 4]]B: [["A", "B", 3], ["C", "B", 4]]C: [["C", "B", 4]](以下无效的一个有效的交易)。
Arnauld

3
如果有人尝试超支,而预期的收件人已经超支了,会发生什么?
Nitrodon

在第二和第三个测试用例中,[“ B” 3]中没有逗号
Jo King

Answers:


5

JavaScript(ES6),91 88 79字节

@NahuelFouilleul节省了8个字节

以currying语法接受输入(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()

如何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呢?
Nahuel Fouilleul

@NahuelFouilleul确实好得多。谢谢!
Arnauld


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感谢ovs

由于输出格式限制而更长:

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)


@ovs哇,这真是太聪明了
Outgolfer的Erik

2

Ruby,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 as std::map,B as 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;}

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.