Last active
July 23, 2016 06:49
-
-
Save hmli/5b64d50a70da4d3d0c6eb088d2d6bcd4 to your computer and use it in GitHub Desktop.
算钱
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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