Compare commits
7 Commits
117a5e9f2b
...
16f718dcdc
Author | SHA1 | Date | |
---|---|---|---|
16f718dcdc | |||
049378518a | |||
a63608bac5 | |||
0f0349810f | |||
91ebe9ddc3 | |||
2ebc2f904f | |||
b83a3ed5c3 |
139
auctionsim/summary.go
Normal file
139
auctionsim/summary.go
Normal file
@ -0,0 +1,139 @@
|
||||
package auctionsim
|
||||
|
||||
import (
|
||||
"math"
|
||||
"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 highest bid the auction winner was willing to make.
|
||||
WinnerMaxBid 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. If all bidders had a true value of
|
||||
* negative infinity for the item, this will be greater than the number of
|
||||
* bidders.
|
||||
*/
|
||||
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{Value: math.Inf(-1)}
|
||||
if maxIdx >= 0 {
|
||||
rube = allBidders[maxIdx]
|
||||
}
|
||||
return &ResultSummary{
|
||||
Bidders: len(allBidders),
|
||||
Price: price,
|
||||
WinnerValue: winner.Value,
|
||||
WinnerMaxBid: winner.BidCeiling(),
|
||||
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",
|
||||
"WinnerMaxBid",
|
||||
"WinnerProfit",
|
||||
"LosersWithRegrets",
|
||||
"HighestValue",
|
||||
"HighestValuatorBid",
|
||||
"MissedProfit",
|
||||
"ValueDelta",
|
||||
"HighestValueRank",
|
||||
}
|
||||
}
|
||||
|
||||
func csvFloat(f float64) string {
|
||||
return strconv.FormatFloat(f, 'g', CSVPrecision, 64)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.WinnerMaxBid),
|
||||
csvFloat(s.WinnerProfit),
|
||||
strconv.Itoa(s.LosersWithRegrets),
|
||||
csvFloat(s.HighestValue),
|
||||
csvFloat(s.HighestValuatorBid),
|
||||
csvFloat(s.MissedProfit),
|
||||
csvFloat(s.ValueDelta),
|
||||
strconv.Itoa(s.HighestValueRank),
|
||||
}
|
||||
}
|
51
main/main.go
51
main/main.go
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"git.chromaticdragon.app/kistaro/auctionsim/auctionsim"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
@ -32,54 +31,30 @@ func main() {
|
||||
log.Fatalf("can't run an auction with %d bidders", num)
|
||||
}
|
||||
|
||||
price, allBidders := auctionsim.RunAuctionVerbosely(
|
||||
summary := auctionsim.Summarize(auctionsim.RunAuctionVerbosely(
|
||||
&auctionsim.CappedBidderGenerator{
|
||||
G: auctionsim.NormalestBidderGenerator(),
|
||||
Lim: num,
|
||||
},
|
||||
)
|
||||
bidder := allBidders[len(allBidders)-1]
|
||||
|
||||
fmt.Printf("The auction winner paid ¤%f. They have %s.\n", price, deltaStr(bidder.Value-price))
|
||||
fmt.Printf("The item was worth ¤%f to them.\n", bidder.Value)
|
||||
fmt.Printf("They would have paid up to ¤%f for it.\n", bidder.BidCeiling())
|
||||
))
|
||||
fmt.Printf("The auction winner paid ¤%f. They have %s.\n", summary.Price, deltaStr(summary.WinnerProfit))
|
||||
fmt.Printf("The item was worth ¤%f to them.\n", summary.WinnerValue)
|
||||
fmt.Printf("They would have paid up to ¤%f for it.\n", summary.WinnerMaxBid)
|
||||
|
||||
fmt.Println()
|
||||
i := len(allBidders) - 2
|
||||
for i >= 0 && allBidders[i].Value < price {
|
||||
i--
|
||||
}
|
||||
|
||||
if i < 0 {
|
||||
fmt.Printf("The item was not worth that to anybody.\n")
|
||||
if summary.LosersWithRegrets < 1 {
|
||||
fmt.Println("The item was not worth that to anybody.")
|
||||
} else {
|
||||
rube := allBidders[i]
|
||||
fmt.Printf("The highest bidder who would have made a profit at that price stopped bidding at ¤%f.\n", rube.BidCeiling())
|
||||
fmt.Printf("They should have kept bidding until ¤%f.\n", rube.Value)
|
||||
if rankDelta := len(allBidders) - i - 1; rankDelta == 1 {
|
||||
fmt.Println("They were outbid by 1 bidder.")
|
||||
} else {
|
||||
fmt.Printf("They were outbid by %d bidders.\n", rankDelta)
|
||||
}
|
||||
fmt.Printf("If they had paid the amount of the winning bid, they would have %s.\n", deltaStr(rube.Value-price))
|
||||
fmt.Printf("The item was worth that to %d bidders, who stopped bidding too soon.\n", summary.LosersWithRegrets)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
maxValue := math.Inf(-1)
|
||||
maxIdx := -1
|
||||
for i, b := range allBidders {
|
||||
if b.Value > maxValue {
|
||||
maxValue = b.Value
|
||||
maxIdx = i
|
||||
}
|
||||
}
|
||||
|
||||
if maxIdx == -1 {
|
||||
if summary.HighestValueRank > summary.Bidders {
|
||||
fmt.Println("Wow! It was infinitely beyond worthless to everybody.")
|
||||
} else {
|
||||
fmt.Printf("The bidder who would have gotten the most value was outbid by %d bidders.\n", len(allBidders)-maxIdx-1)
|
||||
rube := allBidders[maxIdx]
|
||||
fmt.Printf("The item was worth at most ¤%f to them. Their maximum bid was ¤%f.\n", rube.Value, rube.BidCeiling())
|
||||
fmt.Printf("If they had paid the winning bid, they would have %s.\n", deltaStr(rube.Value-price))
|
||||
fmt.Printf("The bidder who would have gotten the most value was outbid by %d bidders.\n", summary.HighestValueRank-1)
|
||||
fmt.Printf("The item was worth at most ¤%f to them. Their maximum bid was ¤%f.\n", summary.HighestValue, summary.HighestValuatorBid)
|
||||
fmt.Printf("If they had paid the winning bid, they would have %s.\n", deltaStr(summary.MissedProfit))
|
||||
fmt.Printf("They valued it ¤%f more than the winning bidder.\n", summary.ValueDelta)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user