$TOTAL = 0.0 PERSONS = {} PAYMENTS = {} PURPOSES = {} class Person def initialize(name) @name = name end def leave! PERSONS.delete @name end def pay(amount, comment) $TOTAL += amount (PURPOSES[@name] ||= []) << comment (PERSONS.keys-[@name]).each { |ot| pay = amount/PERSONS.size na = @name if na.to_i > ot.to_i other, name = na, ot pay = -pay else name, other = na, ot end PAYMENTS[name] ||= {} PAYMENTS[name][other] ||= 0 PAYMENTS[name][other] += pay } end end def person(name) Object.const_set name, PERSONS[name] = Person.new(name) end def cashing_up! puts PAYMENTS.map { |don, v| v.map { |rec, n| if n == 0 nil elsif n > 0 "%s -> %s: %.2f" % [rec, don, n] else "%s -> %s: %.2f" % [don, rec, -n] end } }.flatten.compact.sort puts PAYMENTS.each { |name, v| v.each { |other, w| v[other] = 0.0 } } end load ARGV.first avg = $TOTAL / PERSONS.size puts "%d people, %.2f pro person (Cashflow: %.2f)" % [PERSONS.size, avg, $TOTAL] PURPOSES.each { |name, purp| unless purp.empty? puts "#{name}: #{purp.join ', '}" end }