Friday, August 14, 2015

get the winning bid and final price

Bid has a price. It may also have an escalation where it goes up to a max price in some increment.

The ibid interface makes the code cleaner.
bid: ibid
    id //int order in which received
    price
    
    id():
        return id
    price():
        return price
    increment():
        return 0
    maxprice():
        return price

escalatingbid: ibid
    id //int order in which received
    price
    increment
    maxprice
    
    id():
        return id
    price():
        return price
    increment():
        return increment
    maxprice():
        return maxprice

ibid:
    id()
    price()
    increment()
    maxprice()
The bid with the highest maxprice() wins. To calculate the final price, the 2nd highest bid is also required.
//examples

300-325, +2 // 300
275-299, +3

300-325, +2 // 312
275-310, +3

300-325, +2 // 312
275-311, +3

320-325, +2 // 325
320-324, +3

320-325, +2 // 325
300-325, +3

// corner cases
300         // 300
300

300         // 300
275-300, +5

275-300, +5 // 300
300

winningbid(ibid[] bids):
    if bids == null:
        throw
    comparer = new bidcomparer()
    bid1, bid2 = top(bids, 2, comparer)
    if bid1 == null:
        // no winner
        return null
    finalprice = finalprice(bid1, bid2, comparer)
    return finalprice, bid1

finalprice(bid1, bid2, comparer):
    // bid1 cannot be null
    if comparer.compare(bid1, bid2) <= 0:
        throw
    if bid2 == null || bid2.maxprice() < bid1.price():
        price = bid1.price()
    else:
        if bid1.increment() > 0:
            escalation = 
                (((bid2.maxprice() - bid1.price()) / bid1.increment()) + 1)
                    * bid1.increment()
        price = bid1.price() + escalation
        if price > bid1.maxprice():
            price = bid1.maxprice()
    return price
When the maxprice() is same for 2 bids, the bid that came in first wins.
// quick and dirty
top2(bids, comparer):
    if bids == null || comparer == null:
        throw
    max1 = max2 = null
    for bid in bids:
        if comparer.compareto(bid, max1) > 0:
            max2 = max1
            max1 = bid
        else if comparer.compareto(bid, max2) > 0:
            max2 = bid
    return max1, max2

bidcomparer: icomparer{ibid}
    int compareto(bid1, bid2):
        if bid1 == null && bid2 == null:
            return 0
        if bid1 == null:
            return -1
        if bid2 == null:
            return 1
        compare = bid1.maxprice().compareto(bid2.maxprice())
        if compare == 0:
            // when maxprice() is same, pick the one that came first
            compare == -1 * bid1.id().compareto(bid2.id())
        return compare

No comments:

Post a Comment