From b83a3ed5c315a0c2536c731bf047d951786f0607 Mon Sep 17 00:00:00 2001 From: Kistaro Windrider Date: Sat, 18 Nov 2023 18:03:28 -0800 Subject: [PATCH] Draft version of summary dumper --- auctionsim/summary.go | 131 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 auctionsim/summary.go diff --git a/auctionsim/summary.go b/auctionsim/summary.go new file mode 100644 index 0000000..f0e0956 --- /dev/null +++ b/auctionsim/summary.go @@ -0,0 +1,131 @@ +package auctionsim + +import ( + "strconv" +) + +/// Digits of precision in floating-point values in CSVs. +const CSVPrecision = 10 + +/** + * ResultSummary contains notable results of an auction. + */ +type ResultSummary struct { + /// The number of bidders in the auction. + Bidders int + /// The price the item sold for. + Price float64 + /// The amount of value the winner actually got out of the auctioned item. + WinnerValue float64 + /** + * The amount by which the winner's value of the item exceeded the price + * they paid. Often negative. + */ + WinnerProfit float64 + /** + * Number of losing bidders who had a "true value" of the item in excess + * of the price paid. + */ + LosersWithRegrets int + /// The most the item was genuinely worth to any bidder. + HighestValue float64 + /// The most the bidder with the highest value would have been willing to pay. + HighestValuatorBid float64 + /** + * How much the bidder with the highest value would have made in profit had + * they won the auction for the price the auction's actual winner paid. + * Often negative, indicating nobody would have made money on the auction. + * If this is zero or negative, there are 0 losers with regrets. + */ + MissedProfit float64 + /** + * How much more valuable the item was to the bidder with the highest value + * than it was to the auction's eventual winner, irrespective of winning bid. + */ + ValueDelta float64 + /** + * The rank of the bidder who actually had the highest value of the item. + * The winner of the auction has rank 1. + */ + HighestValueRank int +} + +/** + * Summarize takes an already-sorted list of bidders (see RunAuctionVerbosely) + * and the winning auction price, and calculates a ResultSummary for that auction. + */ +func Summarize(price float64, allBidders []Bidder) *ResultSummary { + regrets := 0 + maxValue := math.Inf(-1) + maxIdx := -1 + + for i, b := range allBidders { + if b.Value > maxValue { + maxValue = b.Value + maxIdx = i + } + if b.Value > price { + regrets++ + } + } + + winner := allBidders[len(allBidders) - 1] + rube := Bidder{} + if maxIdx >= 0 { + rube = allBidders[maxIdx] + } + return &ResultSummary { + Bidders: len(allbidders), + Price: price, + WinnerValue: winner.Value, + WinnerProfit: winner.Value - price, + LosersWithRegrets: regrets, + HighestValue: maxValue, + HighestValuatorBid: rube.BidCeiling(), + MissedProfit: rube.Value - price, + ValueDelta: maxValue - winner.Value, + HighestValueRank: len(allBidders) - maxIdx, + } +} + +/** + * ResultSummaryCSVHeader returns column labels for the records emitted by + * (*ResultSummary).CSVRecord(). + */ +func ResultSummaryCSVHeader() []string { + return []string{ + "Bidders", + "Price", + "WinnerValue", + "WinnerProfit", + "LosersWithRegrets", + "HighestValue", + "HighestValuatorBid", + "MissedProfit", + "ValueDelta", + "HighestValueRank", + } +} + +func csvFloat(f float64) string { + return strconv.FormatFloat(f, 'g', CSVPrecision) +} + +/** + * CSVRecord returns rows intended for use with encoding/csv.Writer, with + * columns in the order specified by ResultSummaryCSVHeader(). + */ +func (s *ResultSummary) CSVRecord() []string { + return []string{ + strconv.Itoa(s.Bidders), + csvFloat(s.Price), + csvFloat(s.WinnerValue), + csvFloat(s.WinnerProfit), + strconv.Itoa(LosersWithRegrets), + csvFloat(s.HighestValue), + csvFloat(s.HighestValuatorBid), + csvFloat(s.MissedProfit), + csvFloat(s.ValueDelta), + strconv.Itoa(HighestValueRank), + } +}