package Ġcom . ch im ber . de bt isl av . service Ċ Ċ import Ġcom . ch im ber . de bt isl av . exception . Not Authorized Exception Ċ import Ġcom . ch im ber . de bt isl av . model . De bt Ċ import Ġcom . ch im ber . de bt isl av . model . De bt Status Ċ import Ġcom . ch im ber . de bt isl av . model . Group Ċ import Ġcom . ch im ber . de bt isl av . model . User Ċ import Ġcom . ch im ber . de bt isl av . repository . De bt Repository Ċ import Ġcom . ch im ber . de bt isl av . repository . Group Repository Ċ import Ġcom . ch im ber . de bt isl av . util . Edge Ċ import Ġcom . ch im ber . de bt isl av . util . Graph Ċ import Ġorg . springframework . stereotype . Service ĊĊ Ċ @ Service Ċ class ĠGroup Service ( ĊĠĠĠ Ġprivate Ġval Ġgroup Repository : ĠGroup Repository , ĊĠĠĠ Ġprivate Ġval Ġde bt Repository : ĠDeb t Repository Ċ ) Ġ{ ĊĠĠĠ Ġfun ĠaddTo Group ( currentUser : ĠUser , Ġuser ToAdd : ĠUser , Ġgroup : ĠGroup ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( currentUser . id Ġ!= Ġgroup . admin _ id ) Ġthrow ĠNot Authorized Exception () ĊĊĠĠĠĠĠĠĠ Ġgroup . user List . add ( user ToAdd ) ĊĠĠĠĠĠĠĠ Ġgroup Repository . save ( group ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcreate Group ( user : ĠUser , ĠgroupName : ĠString ): ĠLong Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġgroup Ġ= ĠGroup ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= ĠgroupName , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadmin _ id Ġ= Ġuser . id ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġgroup . user List . add ( user ) ĊĠĠĠĠĠĠĠ Ġgroup Repository . save ( group ) ĊĠĠĠĠĠĠĠ Ġreturn Ġgroup . id ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetAll Users ( group : ĠGroup ): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgroup . user List . map Ġ{ Ġit . toString () Ġ}. toList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠgetAll Deb ts ( group : ĠGroup ): ĠList < De bt > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġgroup . de bt List . toList () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġminimize Deb ts ( group : ĠGroup ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġmaximum Ġone Ġde bt Ġfor Ġeach Ġperson ĊĠĠĠĠĠĠĠ Ġval Ġdeb ts Ġ= Ġgroup . de bt List . filter Ġ{ Ġit . status Ġ== ĠDeb t Status . ACTIVE Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġbalance Ġ= Ġmutable Map Of < Long , ĠInt >() ĊĠĠĠĠĠĠĠ Ġfor Ġ( de bt Ġin Ġdeb ts ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbalance . compute ( de bt . loan er _ id ) Ġ{ Ġ_, Ġv Ġ-> Ġ( v Ġ?: Ġ 0 ) Ġ- Ġde bt . amount Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbalance . compute ( de bt . l ender _ id ) Ġ{ Ġ_, Ġv Ġ-> Ġ( v Ġ?: Ġ 0 ) Ġ+ Ġde bt . amount Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġusers Ġ= Ġbalance . keys . toList (). sorted By Ġ{ Ġbalance [ it ] Ġ} ĊĠĠĠĠĠĠĠ Ġvar Ġi Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġvar Ġj Ġ= Ġusers . size Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġval Ġnew Deb ts Ġ= Ġmutable ListOf < De bt >() ĊĠĠĠĠĠĠĠ Ġwhile Ġ( i Ġ< Ġj ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġloan er Ġ= Ġusers [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl ender Ġ= Ġusers [ j ] ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( balance [ loan er ] Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( balance [ l ender ] Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj -- ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġloan er Amount Ġ= Ġbalance [ loan er ] Ġ?: Ġthrow ĠAssertionError () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġl ender Amount Ġ= Ġbalance [ l ender ] Ġ?: Ġthrow ĠAssertionError () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( loan er Amount Ġ< Ġ 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġassert ( l ender Amount Ġ> Ġ 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġamount Ġ= Ġmin Of (- loan er Amount , Ġl ender Amount ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ== Ġ- loan er Amount ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġi ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( amount Ġ== Ġl ender Amount ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj -- ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġde bt Ġ= ĠDeb t ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup _ id Ġ= Ġgroup . id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġamount Ġ= Ġamount , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl ender _ id Ġ= Ġl ender , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloan er _ id Ġ= Ġloan er , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġ" Art ificial Ġde bt Ġafter Ġminim ization ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠDeb t Status . ACTIVE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnew Deb ts . add ( de bt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġde bt Repository . save ( de bt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( de bt Ġin Ġdeb ts ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgroup . de bt List . remove If Ġ{ Ġit . id Ġ== Ġde bt . id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġde bt Repository . delete ( de bt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġgroup . de bt List . addAll ( new Deb ts ) ĊĠĠĠĠĠĠĠ Ġgroup Repository . save ( group ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġreduce Cycles ( group : ĠGroup ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġgets Ġrid Ġof Ġall Ġcycles ĊĠĠĠĠĠĠĠ Ġval Ġdeb ts Ġ= Ġgroup . de bt List . filter Ġ{ Ġit . status Ġ== ĠDeb t Status . ACTIVE Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġedges Ġ= Ġdeb ts . map Ġ{ ĠEdge ( it . loan er _ id , Ġit . l ender _ id , Ġit . amount ) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġgraph Ġ= ĠGraph ( edges ) ĊĠĠĠĠĠĠĠ Ġgraph . reduce All Cycles () ĊĠĠĠĠĠĠĠ Ġval Ġnew Deb ts Ġ= Ġgraph . edges . map Ġ{ Ġedge Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġde bt Ġ= ĠDeb t ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup _ id Ġ= Ġgroup . id , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġamount Ġ= Ġedge . weight , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġl ender _ id Ġ= Ġedge . b , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloan er _ id Ġ= Ġedge . a , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġ" Art ificial Ġde bt Ġafter Ġreducing Ġcycles ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstatus Ġ= ĠDeb t Status . ACTIVE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġde bt Repository . save ( de bt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( de bt Ġin Ġdeb ts ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgroup . de bt List . remove If Ġ{ Ġit . id Ġ== Ġde bt . id Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġde bt Repository . delete ( de bt ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġgroup . de bt List . addAll ( new Deb ts ) ĊĠĠĠĠĠĠĠ Ġgroup Repository . save ( group ) ĊĠĠĠ Ġ} Ċ } Ċ