Skip to content

Instantly share code, notes, and snippets.

@hmli
Last active July 23, 2016 06:49
Show Gist options
  • Save hmli/5b64d50a70da4d3d0c6eb088d2d6bcd4 to your computer and use it in GitHub Desktop.
Save hmli/5b64d50a70da4d3d0c6eb088d2d6bcd4 to your computer and use it in GitHub Desktop.
算钱
# -*- coding: utf8 -*-
from operator import attrgetter
class Member:
def __init__(self, name, paid=0):
self.name = name
self.paid = paid
def pay(self, num):
self.paid += num
def __repr__(self):
return "<Member> %s paid %.2f" % (self.name, self.paid)
class Payment:
def __init__(self, payer, receiver, amount):
self.payer = payer
self.receiver = receiver
self.amount = amount
def __repr__(self):
return "<Payment> %s should pay %.2f to %s" % (self.payer.name, self.amount, self.receiver.name)
def calc(members):
avg_paid = sum([e.paid for e in members])/len(members) # 平均支出
paid_more, paid_less = [],[]
payments = []
# 按支出大于小于平均, 分成两部分
for member in members:
temp = member
if member.paid < avg_paid:
paid_less.append(temp)
if member.paid > avg_paid:
paid_more.append(temp)
# 多支出的按从多到少排序, 少支出的从少到多排序.
paid_more.sort(key=attrgetter("paid"), reverse=True)
paid_less.sort(key=attrgetter("paid"))
print(paid_more)
print(paid_less)
for m_more in paid_more:
to_get = m_more.paid - avg_paid
# 少支出者依次向多支出者补钱.
current_paid_finished = False # 当前这个少支出者是否已经完成补钱. 如果是, 移出
for m_less in paid_less:
if to_get == 0: # 当前多支出者的钱已经补完
break
to_pay = avg_paid - m_less.paid
if to_get > to_pay: # 少支出者已补完自己那份, 轮那下一个人继续补钱. 而当前多支出者的钱还没补全, 需要下个人继续补给他
to_get -= to_pay
payment = Payment(m_less, m_more, to_pay)
payments.append(payment)
continue
if to_get == to_pay:
payment = Payment(m_less, m_more, to_pay)
payments.append(payment)
current_paid_finished = True
break
if to_get < to_pay: # 当前多支出者已经补完, 但少支出者还需要再补一部分, 补给下一个人
to_pay -= to_get
payment = Payment(m_less, m_more, to_get)
payments.append(payment)
break
if current_paid_finished:
paid_less = paid_less[1:]
for pay in payments:
print(pay)
if __name__ == "__main__":
mem1 = Member(name="Gary", paid=150)
mem2 = Member(name="Li", paid=90)
mem3 = Member(name="Hu")
members = [mem1, mem2, mem3]
calc(members)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment