Un banco para amigos menos confiables

12

Introducción

Has conseguido un trabajo como ministro de finanzas en tu país inventado en tu patio trasero. Ha decidido crear su propio banco en su país para usted y sus amigos menos confiables. Como no confía en sus amigos, ha decidido escribir un programa para validar todas las transacciones para evitar que sus amigos gasten en exceso su moneda inventada y arruinen su economía.

Tarea

Dado el saldo inicial y todas las transacciones, filtre todas las transacciones en las que alguien intente gastar de más y bloquee a cualquiera que intente gastar de más (esto incluye tratar de gastar de más en una cuenta cerrada) para que nunca vuelva a usar su banco filtrando las transacciones futuras hacia o desde su / su cuenta bancaria.

De entrada y salida

Dos listas Ay Bcomo entrada y una lista Ccomo salida. Aes el saldo inicial de cada cuenta con el formato [["Alice", 5], ["Bob", 8], ["Charlie", 2], ...]. Bes una lista de transacciones con el formato [["Bob", "Alice", 3], ["Charlie", "Bob", 5], ...]donde ["Bob", "Alice", 3]significa que Bob quiere pagar a Alice 3 unidades monetarias. Cdebe tener el mismo formato que B. A, By Cpuede estar en cualquier formato razonable.

Casos de prueba

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

Puntuación

Este es el , gana el código más corto en bytes en cada idioma.

Herman L
fuente
¿Qué tan estricto es el formato IO? ¿ ATambién podría ser un diccionario o una lista de tuplas?
Laikoni
@Laikoni ¿O incluso solo una lista del formulario ["A", 2, "B", 3, "C", 5]?
Erik the Outgolfer
Sugerido caso de prueba: A: [["A", 2], ["B", 3], ["C", 4]], B: [["A", "B", 3], ["C", "B", 4]], C: [["C", "B", 4]](una transacción válida después de una y otra inválida).
Arnauld
3
¿Qué sucede si alguien trata de gastar de más y el destinatario ya ha gastado de más?
Nitrodon el
No hay coma en ["B" 3] en el segundo y tercer caso de prueba
Jo King

Respuestas:

5

JavaScript (ES6), 91 88 79 bytes

Guardado 8 bytes gracias a @NahuelFouilleul

Toma entrada en la sintaxis de curry (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))

Casos de prueba

Embellecido y comentado

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
fuente
¿Qué hay de 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))portar la solución de Perl a JavaScript?
Nahuel Fouilleul el
@NahuelFouilleul Mucho mejor de hecho. ¡Gracias!
Arnauld el
4

Perl 5, 72 + 2 (-ap) = 74 bytes

%h=@F;$_=<>;s/(\S+) (\S+) (\S+)/($h{$1}-=$3)<0||($h{$2}+=$3)<$3?"":$&/ge

pruébalo en línea

Nahuel Fouilleul
fuente
2

Python 2 , 103 bytes

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

Pruébalo en línea!

-12 gracias a los ovs .

Ya debido a restricciones de formato de salida:

Cdebe tener el mismo formato que B.

De lo contrario, podría haber hecho esto por 92 bytes:

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)
Erik el Outgolfer
fuente
103 bytes
ovs
@ovs wow, eso es inteligente
Erik the Outgolfer
2

Ruby , 57 bytes

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

Pruébalo en línea!

Toma la entrada Acomo a Hashen el formato {"A"=>2, "B"=>3}. La entrada By la salida Cestán en el formato sugerido.

Explicación

->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
}
Justin Mariner
fuente
1

C ++, 193 bytes

Ingrese A como std::map, B como 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;}

Pruébalo en línea!

Colera Su
fuente