แยกบิล


12

งาน

สมมติว่าppepole ต้องแยกบิล แต่ละคนจะถูกระบุโดยสาม(Name, n, k)ประกอบด้วย:

  • Name: ชื่อ ;
  • n: จำนวนเงินที่เธอ / เขามีการจ่าย ;
  • k: จำนวนเงินที่เธอ / เขาจ่ายจริง

ความท้าทายที่นี่คือการหาว่าใครเป็นหนี้ใคร

สมมติฐาน

  • อินพุตและเอาต์พุตสามารถอยู่ในรูปแบบที่สะดวก

  • p N,n N+, k N.

  • p >1.

  • ชื่อเป็นสตริงที่ไม่ซ้ำกันของความยาวโดยพลการประกอบด้วยตัวอักษรตัวพิมพ์เล็ก

วิธีการแก้

การแก้ปัญหาจะถูกแสดงด้วยชุดขั้นต่ำของการทำธุรกรรมในหมู่pประชาชน โดยเฉพาะอย่างยิ่งพวกเขาเป็นสามเท่า(from, to, amount)

  • from: nameของบุคคลที่ให้เงิน
  • to: nameของบุคคลที่รับเงิน
  • amount: จำนวนเงินของการทำธุรกรรม

หมายเหตุ : ผลรวมของหนี้ทั้งหมด ( n) อาจแตกต่างจากผลรวมของจำนวนเงินทั้งหมดที่ชำระไปแล้ว ( k) ในกรณีนี้คุณต้องเพิ่มในผลลัพธ์('owner', Name, amount)หรือ(Name, 'owner', amount)ในรูปแบบที่คุณเลือก ชื่อใด ๆ จะไม่เป็นownerสตริง 'เจ้าของ' ยืดหยุ่นได้

หากมีชุด mimimum หลายชุดให้เลือกชุดที่มีผลรวมขั้นต่ำของจำนวนธุรกรรมทั้งหมด (ค่าสัมบูรณ์); ในกรณีที่เสมอกันให้เลือกหนึ่งอัน

กรณีทดสอบ:

inputs(Name,n,k):
[('a',30,40),('b',40,50),('c',30,15)]
[('a',30,30),('b',20,20)]
[('a',30,100),('b',30,2),('c',40,0)]
[('a',344,333),('b',344,200),('c',2,2)]
[('a',450,400),('b',300,300),('c',35,55)]

outputs(from, to, amount):
[('c','a',10),('c','b',5),('owner','b',5)] or [('c','b',10),('c','a',5),('owner','a',5)]
[]
[('owner','a',2),('b','a',28),('c','a',40)] PS: [('owner','a',2),('b','a',68),('c','b',40)] has the same number of transactions, but it is not a valid answer, because the total amount of its transaction is greater than that of the proposed solution.
[('a','owner',11),('b','owner',144)]
[('a','owner',30),('a','c',20)]

นี่คือรหัสกอล์ฟ: สั้นที่สุดชนะรหัส


1
ฉันคิดว่าคุณควรเปลี่ยน "คุณต้องแสดงสถานการณ์ที่ง่ายที่สุดซึ่งต้องใช้จำนวนธุรกรรมน้อยที่สุด" ถึง "คุณต้องแสดงสถานการณ์ที่ต้องใช้จำนวนธุรกรรมน้อยที่สุดหากมีหลายสถานการณ์เช่นนั้นให้เลือกรายการที่มีจำนวนธุรกรรมน้อยที่สุด" เนื่องจากฉันเชื่อว่าชัดเจน
Jonathan Allan

1
ความท้าทายที่ดี แต่อาจจะต้องใช้กรณีทดสอบที่ซับซ้อนมากขึ้นเพื่อให้แน่ใจว่าโซลูชันนั้นดีที่สุดเสมอ
Arnauld

3
"จำนวนรวมน้อยที่สุด" คืออะไร
lirtosiast

1
@JanathanAllan ยังสับสนกับคำว่า "notional" มาจากไหน จากกรณีทดสอบ 3 ดูเหมือนว่าเราควรต้องการคำตอบที่คนคนเดียวกันไม่ได้ทั้งให้และรับ? ถูกต้องหรือไม่ ทำไมถึงเป็นอย่างนั้น
Jonah

1
@Jonah ฉันใช้ "total notional" เนื่องจากทิศทางของการทำธุรกรรมไม่ควรถูกนำมาพิจารณา (แค่ขนาดที่แน่นอน) ถึงแม้ว่าตอนนี้ฉันรู้แล้วว่ามันค่อนข้างซ้ำซ้อน !) [Notional เป็นเพียงคำศัพท์ที่ใช้ในด้านการเงิน]
Jonathan Allan

คำตอบ:


2

JavaScript (ES6),  252 227 223 222  215 ไบต์

[[n0, k0, name0], [n1, k1, name1], ...]จะเข้าเป็น

ธุรกรรมในโซลูชันอาจเป็นทั้งบวกหรือลบ เจ้าของจะเรียกว่าไม่ได้กำหนด

a=>(m=g=(B,t,s)=>B.some(x=>x)?B.map((b,x)=>B.map((c,y)=>b*c<0&b*b<=c*c&&g(C=[...B],[...t,[a[x][2],b,a[y][2]]],s+a.length-1/b/b,C[C[y]+=b,x]=0))):m<s||(r=t,m=s))([...a.map(([x,y])=>t-(t+=y-x),t=0),t],[],a.push(g))&&r

ลองออนไลน์!

แสดงความคิดเห็น

a => (                              // a[] = input array
  m =                               // initialize m to a non-numeric value
  g = (B, t, s) =>                  // g = function taking: B = balances, t = transactions,
                                    //     s = score of the current solution
    B.some(x => x) ?                // if at least one balance is not equal to 0:
      B.map((b, x) =>               //   for each balance b at position x:
        B.map((c, y) =>             //     for each balance c at position y:
          b * c < 0 &               //       if b and c are of opposite sign
          b * b <= c * c &&         //       and |b| <= |c|,
          g(                        //       do a recursive call to g:
            C = [...B],             //         - with a copy C of B
            [ ...t,                 //         - append the new transaction to t[]
              [a[x][2], b, a[y][2]] //           in [from_name, amount, to_name] format
            ],                      //
            s + a.length - 1/b/b,   //         - add (a.length - 1/b²) to s
            C[C[y] += b, x] = 0     //         - update C[y] and clear C[x]
          )                         //       end of recursive call
        )                           //     end of inner map()
      )                             //   end of outer map()
    :                               // else:
      m < s ||                      //   if the score of this solution is lower than m,
      (r = t, m = s)                //   update r to t and m to s
)(                                  // initial call to g:
  [                                 //   build the list of balances:
    ...a.map(([x, y]) =>            //     each balance is equal to:
      t - (t += y - x),             //     due_value - paid_value
      t = 0                         //     keep track of the total t ...
    ),                              //
    t                               //   ... which is appended at the end of this array
  ],                                //   (this is the balance of the owner)
  [],                               //   start with t = []
  a.push(g)                         //   append a dummy owner to a[]; start with s = 1
) && r                              // return r
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.