David and Sharon Phillips
11/30/2007 11:25:00 PM
> Hi Sharon,
Everyone says that...
I'm actually Dave, but I use my wife's email :)
> Many many thanks for your kind response. As you guessed I'm new to
> programming. The code works fine. Only it doesn't display messages
> asking for user input, for instance "Enter the valuation" message
> doesn't appear.
What sort of environment are you running this on?
Perhaps you could alter get_num to include STDOUT.flush (like your
original)
def get_num msg
print "#{msg} >"
STDOUT.flush
gets.to_i
end
Probably the most important thing I'd like to get across is that
whenever you see yourself writing something like
a_margin = max_price_A - reservePrice
b_margin = max_price_B - reservePrice
c_margin = max_price_C - reservePrice
d_margin = max_price_D - reservePrice
e_margin = max_price_E - reservePrice
you're repeating yourself unnecessarily and making it difficult to
change the programme (what if we had an extra investor? what if we had
100?)
Ruby (unlike a number of other languages) makes it very simple to
manage lists of things.
Here's your original code again, but all I've done is put all the
a_margin (etc) bits into a list and change the bidding section to use
this list
Cheers,
Dave
# set up list (array) to hold our investor information
investors= []
# Change the number of bidders by changing this value
BIDDER_COUNT=5
#Get the valuation price i.e the Auctioneer's expected price of the
property
puts"Enter the valuation: "
STDOUT.flush
valuation = gets.to_i
#Get the Reserve price i.e. the minimum acceptable price of the property
puts "Enter the reserve price: "
STDOUT.flush
reservePrice = gets.to_i
# get the max_price for each investor
for index in (1..BIDDER_COUNT)
# we'll use a hash to keep all the information we need about this
investor
# much tidier than having sperate lists for bids, margins and
max_prices
this_investor= {:index => index}
#Each agent knows the maximun amount it can afford to pay for the
property
puts "How much is invester #{index} willing to spend? "
STDOUT.flush
this_investor[:max_price]= gets.to_i
# add the new investor to our list
investors << this_investor
end
investors.each do |investor|
#Calculate invester bid magins
#i.e. difference btw an agent's max willing price and the reserve
price
investor[:margin] = investor[:max_price] - reservePrice
#Initialize bids for the investers here. First bid is reserve price
plus half of the margin.
#The other half will be incrementally bidded at 50% per round of
bidding
investor[:bid] = reservePrice + investor[:margin]/2
end
=begin
Assumptions
1. Probability of two or more investers having the same max price is
negligible
2. Investers do not know each other's willing prices
3. A margin can't be zero...to be explained later
=end
#Continue bidding as long as the highest bid is less or equal to
valuation price.
#Trivially, the property will be sold to the agent that reaches or
exceeds the valuation price
# keep going untill we have a winner.
# NOTE ** this will continue forever if none of the bidders has a
max_price
# >= the valuation
# You'll need to add a check for this as well
# Hint: you'll reach a round where those_still_bidding will be empty
# (everyone has dropped out)
#initialize out winner as no one
winner= nil
while winner.nil? do
# check who should bid first
# we need to find the lowest bid that's not greater than that
investors'
# max_price
# To do this, let's take out list of investors, and narrow it down
to only
# those still bidding (bid <= max_price)
those_still_bidding= investors.select do |investor|
# if the following evaluates as true, this investor will join our
new list
investor[:bid] <= investor[:max_price]
end
# Now, from those let's find the lowest bidder.
# One way to do this is to sort the list by bid, then pick the
first one
# Step 1: sort them
those_still_bidding.sort! do |investor_a, investor_b|
investor_a[:bid] <=> investor_b[:bid]
end
# Step 2: get the first
lowest_bidder= those_still_bidding.first
puts "Investor #{lowest_bidder[:index]} is bidding
#{lowest_bidder[:bid]}"
# Two possibilities now:
# 1: This bid wins, and the action ends
# 2: This bid doesn't win, this investor raises their bid and we
continue
if lowest_bidder[:bid]>= valuation then
# Only need to set winner here.
# This will cause the while loop to stop (winner is no longer nil)
# We'll display the winning details at the end
winner= lowest_bidder
else
lowest_bidder[:bid]+= lowest_bidder[:margin] * 0.25
end
end # whle
# The programme will only get to here once a winner has been declared
puts "\nThis property has been sold to Invester #{winner[:index]} for
#{winner[:bid]}"