Horse racing
- Background
In three recent races at Rosetta Park, the results have been:
Race 1
Pos | Horse | Weight | Dist | Sex |
---|---|---|---|---|
1 | A | 9.00 | 0.0 | Colt |
2 | B | 8.06 | 2.0 | Filly |
3 | C | 9.04 | 1.5 | Colt |
Time 1 minute 36.0 seconds
Race 2
Pos | Horse | Weight | Dist | Sex |
---|---|---|---|---|
1 | D | 8.10 | 0.0 | Filly |
2 | E | 9.03 | 1.0 | Colt |
3 | F | 9.07 | 3.0 | Colt |
(F was slowly away and lost 2 lengths at the finish as a result)
Time 1 minute 36.4 seconds
Race 3
Pos | Horse | Weight | Dist | Sex |
---|---|---|---|---|
1 | G | 8.04 | 0.0 | Colt |
2 | H | 8.10 | 1.5 | Colt |
3 | I | 9.05 | 0.5 | Filly |
Time 1 minute 35.8 seconds
It is assumed that:
1. Weights carried are expressed in stones and pounds (traditional in US and UK racing) where 1 stone equals 14 pounds.
2. The distances are the actual distances between horses at the finish of the race.
3. All races are run at 1 mile in similar going and weather conditions and the time shown is the time taken by the winner to run the race.
4. 2 pounds slows a horse down by 1 length at the finish.
5. 1 second is equivalent to 5 lengths at the finish.
- Task
All 9 of these horses, plus a further horse J, are due to compete against each other in Race 4 at Rosetta Park again over 1 mile and in similar conditions to the earlier races. Colts will carry 9.00 and fillies 8.11.
Suppose that:
1. Horse B has been moving well on the galops and her trainer thinks she has improved 4 pounds since her last outing.
2. Horse C has had a setback in training and his trainer expects him to perform 4 pounds below his best.
3. Horse H is being ridden by the champion jockey which is expected to improve his performance by 3 pounds compared to what it would otherwise have been.
4. Horse J, a filly, has never run before but her performance on the galops suggests she can run 1 mile in 1 minute 35.8 seconds when carrying 8.11.
Other things being equal (which they seldom are in actual horse racing!) what would you expect the full result of Race 4 to be including the time of the winner?
FreeBASIC
' Ratings on past form, assuming a rating of 100 for horse A.
Dim As Double a = 100.0
Dim As Double b = a - 8 - 2 * 2 ' carried 8 lbs less, finished 2 lengths behind.
Dim As Double c = a + 4 - 2 * 3.5
Dim As Double d = a - 4 - 10 * 0.4 ' based on relative weight and time.
Dim As Double e = d + 7 - 2 * 1
Dim As Double f = d + 11 - 2 * (4 - 2)
Dim As Double g = a - 10 + 10 * 0.2
Dim As Double h = g + 6 - 2 * 1.5
Dim As Double i = g + 15 - 2 * 2
' Adjustments to ratings for current race.
b += 4
c -= 4
h += 3
Dim As Double j = a - 3 + 10 * 0.2
' Filly's allowance to give weight adjusted weighting.
b += 3
d += 3
i += 3
j += 3
' Create table mapping horse to its weight adjusted rating and whether colt.
Type Pair
key As String*1
rating As Double
colt As Boolean
End Type
Dim As Pair list(9)
list(0).key = "A": list(0).rating = a: list(0).colt = True
list(1).key = "B": list(1).rating = b: list(1).colt = False
list(2).key = "C": list(2).rating = c: list(2).colt = True
list(3).key = "D": list(3).rating = d: list(3).colt = False
list(4).key = "E": list(4).rating = e: list(4).colt = True
list(5).key = "F": list(5).rating = f: list(5).colt = True
list(6).key = "G": list(6).rating = g: list(6).colt = True
list(7).key = "H": list(7).rating = h: list(7).colt = True
list(8).key = "I": list(8).rating = i: list(8).colt = False
list(9).key = "J": list(9).rating = j: list(9).colt = False
' Sort in descending order of rating.
Dim As Integer n = Ubound(list)
For x As Integer = 0 To n - 1
For y As Integer = 0 To n - x - 1
If list(y).rating < list(y + 1).rating Then Swap list(y), list(y + 1)
Next y
Next x
' Show expected result of race.
Print !"Race 4\n"
Print "Pos Horse Weight Dist Sex"
Dim As String posic = ""
For x As Integer = Lbound(list) To Ubound(list)
Dim As Double wt = Iif(list(x).colt, 9.00, 8.11)
Dim As Double dist = 0.0
If x > 0 Then dist = (list(x-1).rating - list(x).rating) * 0.5
posic = Iif(x = 0 Or dist > 0, Str(x + 1), Iif(Right(posic, 1) <> "=", Str(x) & "=", posic))
Dim As String sx = Iif(list(x).colt, "colt", "filly")
Print Using "\\ ! ##.## #.# \ \"; posic; list(x).key; wt; dist; sx
Next x
' Weight adjusted rating of winner.
Dim As Double wr = list(0).rating
' Expected time of winner (relative to A's time in Race 1).
Dim As Double t = 96 - (wr - 100) / 10
Dim As Integer min = Int(t / 60)
Dim As Integer sec = t Mod 60
Print
Print Using "Time ## minute ##.# seconds"; min; sec
Sleep
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 B 8.11 1.0 filly 7= D 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1 minute 35.0 seconds
Go
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
// ratings on past form, assuming a rating of 100 for horse A
a := 100
b := a - 8 - 2*2 // carried 8 lbs less, finished 2 lengths behind
c := a + 4 - 2*3.5
d := a - 4 - 10*0.4 // based on relative weight and time
e := d + 7 - 2*1
f := d + 11 - 2*(4-2)
g := a - 10 + 10*0.2
h := g + 6 - 2*1.5
i := g + 15 - 2*2
// adjustments to ratings for current race
b += 4
c -= 4
h += 3
j := a - 3 + 10*0.2
// filly's allowance to give weight adjusted weighting
b += 3
d += 3
i += 3
j += 3
// create map of horse to its weight adjusted rating and whether colt (1 == yes, 0 == no)
m := map[string][2]int{
"A": {a, 1},
"B": {b, 0},
"C": {c, 1},
"D": {d, 0},
"E": {e, 1},
"F": {f, 1},
"G": {g, 1},
"H": {h, 1},
"I": {i, 0},
"J": {j, 0},
}
type kv struct {
key string
value [2]int
}
// convert to slice of kv
l := make([]kv, len(m))
x := 0
for k, v := range m {
l[x] = kv{k, v}
x++
}
// sort in descending order of rating
sort.Slice(l, func(i, j int) bool { return l[i].value[0] > l[j].value[0] })
// show expected result of race
fmt.Println("Race 4\n")
fmt.Println("Pos Horse Weight Dist Sex")
pos := ""
for x := 0; x < len(l); x++ {
wt := "9.00"
if l[x].value[1] == 0 {
wt = "8.11"
}
dist := 0.0
if x > 0 {
dist = float64(l[x-1].value[0]-l[x].value[0]) * 0.5
}
if x == 0 || dist > 0.0 {
pos = fmt.Sprintf("%d", x+1)
} else if !strings.HasSuffix(pos, "=") {
pos = fmt.Sprintf("%d=", x)
}
sx := "colt"
if l[x].value[1] == 0 {
sx = "filly"
}
fmt.Printf("%-2s %s %s %3.1f %s\n", pos, l[x].key, wt, dist, sx)
}
// weight adjusted rating of winner
wr := float64(l[0].value[0])
// expected time of winner (relative to A's time in Race 1)
t := 96.0 - (wr-100)/10
min := int(t / 60)
sec := t - float64(min)*60
fmt.Printf("\nTime %d minute %3.1f seconds\n", min, sec)
}
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 D 8.11 1.0 filly 7= B 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1 minute 35.4 seconds
Julia
function main()
# ratings on past form, assuming a rating of 100 for horse A
a = 100
b = a - 8 - 2*2 # carried 8 lbs less, finished 2 lengths behind
c = a + 4 - 2*3.5
d = a - 4 - 10*0.4 # based on relative weight and time
e = d + 7 - 2*1
f = d + 11 - 2*(4-2)
g = a - 10 + 10*0.2
h = g + 6 - 2*1.5
i = g + 15 - 2*2
# adjustments to ratings for current race
b += 4
c -= 4
h += 3
j = a - 3 + 10*0.2
# filly's allowance to give weight adjusted weighting
b += 3
d += 3
i += 3
j += 3
# create vector of pairs of horse to pair of weight adjusted rating and whether colt (1 == yes, 0 == no)
m = ["A" => a => 1,
"B" => b => 0,
"C" => c => 1,
"D" => d => 0,
"E" => e => 1,
"F" => f => 1,
"G" => g => 1,
"H" => h => 1,
"I" => i => 0,
"J" => j => 0]
# sort in descending order of rating
sort!(m, lt = (x, y) -> first(last(x)) > first(last(y)))
# show expected result of race
println("Race 4\n")
println("Pos Horse Weight Dist Sex")
pos = ""
for x in eachindex(m)
wt = last(last(m[x])) == 0 ? "8.11" : "9.00"
dist = x == 1 ? 0.0 : (first(last(m[x - 1])) - first(last(m[x]))) * 0.5
if x == 1 || dist > 0.0
pos = "$x"
elseif !occursin("=", pos)
pos = "$(x - 1)="
end
sx = last(last(m[x])) == 0 ? "filly" : "colt"
println(rpad(pos, 4), rpad(first(m[x]), 7), rpad(wt, 8), rpad(round(dist, digits=1), 6), sx)
end
# expected time of winner (relative to A's weight adjusted time rating in first race)
t = 96.0 - (first(last(first(m))) - 100) / 10
min, sec = divrem(t, 60.0)
println("\nTime $min minutes and ", round(sec, digits=1), " seconds.")
end
main()
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 B 8.11 1.0 filly 7= D 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1.0 minutes and 35.4 seconds.
Nim
import algorithm, math, strformat, strutils
# Ratings on past form, assuming a rating of 100 for horse A.
var
a = 100.0
b = a - 8 - 2 * 2 # carried 8 lbs less, finished 2 lengths behind.
c = a + 4 - 2 * 3.5
d = a - 4 - 10 * 0.4 # based on relative weight and time.
e = d + 7 - 2 * 1
f = d + 11 - 2 * (4 - 2)
g = a - 10 + 10 * 0.2
h = g + 6 - 2 * 1.5
i = g + 15 - 2 * 2
# Adjustments to ratings for current race.
b += 4
c -= 4
h += 3
var j = a - 3 + 10 * 0.2
# Filly's allowance to give weight adjusted weighting.
b += 3
d += 3
i += 3
j += 3
# Create table mapping horse to its weight adjusted rating and whether colt.
type Pair = tuple[key: char; value: tuple[rating: float; colt: bool]]
let list: array[10, Pair] = {'A': (a, true), 'B': (b, false),
'C': (c, true), 'D': (d, false),
'E': (e, true), 'F': (f, true),
'G': (g, true), 'H': (h, true),
'I': (i, false), 'J': (j, false)}
# Sort in descending order of rating.
let slist = list.sortedByIt(-it.value.rating)
# Show expected result of race.
echo "Race 4\n"
echo "Pos Horse Weight Dist Sex"
var pos = ""
for i, (key, value) in slist:
let wt = if value.colt: "9.00" else: "8.11"
var dist = 0.0
if i > 0: dist = (slist[i-1].value.rating - value.rating) * 0.5
pos = if i == 0 or dist > 0: $(i + 1)
elif not pos.endsWith("="): $i & '='
else: pos
let sx = if value.colt: "colt" else: "filly"
echo &"{pos:<2} {key} {wt} {dist:3.1f} {sx}"
# Weight adjusted rating of winner.
let wr = slist[0].value.rating
# Expected time of winner (relative to A's time in Race 1).
let t = 96 - (wr - 100) / 10
var min = int(t / 60)
var sec = t mod 60
echo &"\nTime {min} minute {sec:.1f} seconds"
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 B 8.11 1.0 filly 7= D 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1 minute 35.4 seconds
Perl
use strict;
use warnings;
my %card;
$card{a} = { name => 'Alberta Clipper', sex => 'M', rating => 100 };
$card{b} = { name => 'Beetlebaum', sex => 'F', rating => $card{a}{rating} - 8 - 2*2 };
$card{c} = { name => 'Canyonero', sex => 'M', rating => $card{a}{rating} + 4 - 2*3.5 };
$card{d} = { name => 'Donnatello', sex => 'F', rating => $card{a}{rating} - 4 - 10*0.4 };
$card{e} = { name => 'Exterminator', sex => 'M', rating => $card{d}{rating} + 7 - 2*1 };
$card{f} = { name => 'Frequent Flyer', sex => 'M', rating => $card{d}{rating} + 11 - 2*(4-2) };
$card{g} = { name => 'Grindstone', sex => 'M', rating => $card{a}{rating} - 10 + 10*0.2 };
$card{h} = { name => 'His Honor', sex => 'M', rating => $card{g}{rating} + 6 - 2*1.5 };
$card{i} = { name => 'Iphigenia in Brooklyn', sex => 'F', rating => $card{g}{rating} + 15 - 2*2 };
$card{j} = { name => 'Josephine', sex => 'F' };
# adjustments to ratings for current race
$card{b}{rating} += 4;
$card{c}{rating} -= 4;
$card{h}{rating} += 3;
$card{j}{rating} = $card{a}{rating} - 3 + 10*0.2;
# initialize carry weights
for (keys %card) {
$card{$_}{rating} += 3 if $card{$_}{sex} eq 'F';
$card{$_}{weight} = $card{$_}{sex} eq 'M' ? 9.00 : 8.11
}
print "Pos Horse Name Weight Back Sex Time\n";
my($previous, $position, $leader, @predictions) = 0;
for (sort { $card{$b}{rating} <=> $card{$a}{rating} } keys %card) {
$leader = $_ unless $leader;
++$position if $previous != $card{$_}{rating};
$previous = $card{$_}{rating};
$card{$_}{back} = ($card{$leader}{rating} - $card{$_}{rating}) / 2;
$card{$_}{time} = 96 - ($card{$_}{rating} - 100) / 10;
push @predictions, sprintf "%2d %s %-22s %.2f %.1f %-6s %s\n", $position, $_, $card{$_}{name}, $card{$_}{weight},
$card{$_}{back}, $card{$_}{sex} eq 'M' ? 'colt' : 'filly', sprintf '%1d:%.1f', int($card{$_}{time}/60), $card{$_}{time}-60;
}
print for sort @predictions;
- Output:
1 i Iphigenia in Brooklyn 8.11 0.0 filly 1:35.4 2 j Josephine 8.11 2.0 filly 1:35.8 3 a Alberta Clipper 9.00 3.0 colt 1:36.0 4 f Frequent Flyer 9.00 3.5 colt 1:36.1 5 h His Honor 9.00 4.0 colt 1:36.2 6 e Exterminator 9.00 4.5 colt 1:36.3 7 b Beetlebaum 8.11 5.5 filly 1:36.5 7 d Donnatello 8.11 5.5 filly 1:36.5 8 c Canyonero 9.00 6.5 colt 1:36.7 9 g Grindstone 9.00 7.0 colt 1:36.8
Phix
Disclaimer: I know nothing about horse racing, all calculations were reverse-engineered from those in the Go entry.
Made table-based so you can plug in different races and adjustments, but any horse appearing in more than one race input would too in the output.
with javascript_semantics requires ("1.0.1") // [else sort_columns() needs a deep_copy()] enum Runners, Time constant races = { // (with F adjusted, plus the prediction) {{{"A", 9,00, 0.0, "colt"}, {"B", 8,06, 2.0, "filly"}, {"C", 9,04, 1.5, "colt"}},"1min 36s"}, {{{"D", 8,10, 0.0, "filly"}, {"E", 9,03, 1.0, "colt"}, {"F", 9,07, 3.0-2, "colt"}},"1min 36.4s"}, {{{"G", 8,04, 0.0, "colt"}, {"H", 8,10, 1.5, "colt"}, {"I", 9,05, 0.5, "filly"}},"1min 35.8s"}, {{{"J", 8,11, 0.0, "filly"}},"1min 35.8s"}} constant adjusts = columnize({{"B",+4}, {"C",-4}, {"H",+3}}) function str2time(string t) sequence r = scanf(t,"%dmin %fs")[1] return r[1]*60+r[2] end function sequence horses = {} string name, pos, sex integer stone, pounds atom wt, dist, rating for i=1 to length(races) do sequence runners = races[i][Runners] atom s = str2time(races[i][Time]), distt = 0 for j=1 to length(runners) do {name, stone, pounds, dist, sex} = runners[j] distt += dist pounds += stone*14 rating = pounds+934-10*s-distt*2 -- (make "A" a nominal 100) integer k = find(name,adjusts[1]) if k then rating += adjusts[2][k] end if if sex="filly" then rating += 3 end if horses = append(horses,{name,sex,rating}) end for end for horses = sort_columns(horses,{-3}) printf(1,"Race 4\n\nPos Horse Weight Dist Sex\n") for i=1 to length(horses) do {name,sex,rating} = horses[i] wt = iff(sex="colt"?9.00:8.11) dist = iff(i=1?0:(horses[i-1][3]-rating)*0.5) if i=1 or dist>0 then pos = sprintf("%d",i) elsif not find('=',pos) then pos &= '=' end if printf(1,"%-2s %s %.2f %3.1f %s\n", {pos, name, wt, dist, sex}) end for // weight adjusted rating of winner rating = horses[1][3] // expected time of winner (relative to A's time in Race 1) atom t = str2time(races[1][Time]) - (rating-100)/10 string m = elapsed(floor(t/60)*60), s = elapsed(remainder(t,60)) printf(1,"\nTime %s %s\n", {m,s})
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 B 8.11 1.0 filly 7= D 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1 minute 35.4s
Raku
I know nothing about horse racing and/or handicapping. This is mostly a straightforward translation of the logic from Go though I did take certain liberties with formatting and layout.
my %card;
%card<a> = { name => 'Alberta Clipper', :sex<M>, rating => 100 };
%card<b> = { name => 'Beetlebaum', :sex<F>, rating => %card<a><rating> - 8 - 2*2 };
%card<c> = { name => 'Canyonero', :sex<M>, rating => %card<a><rating> + 4 - 2*3.5 };
%card<d> = { name => 'Donnatello', :sex<F>, rating => %card<a><rating> - 4 - 10*0.4 };
%card<e> = { name => 'Exterminator', :sex<M>, rating => %card<d><rating> + 7 - 2*1 };
%card<f> = { name => 'Frequent Flyer', :sex<M>, rating => %card<d><rating> + 11 - 2*(4-2) };
%card<g> = { name => 'Grindstone', :sex<M>, rating => %card<a><rating> - 10 + 10*0.2 };
%card<h> = { name => 'His Honor', :sex<M>, rating => %card<g><rating> + 6 - 2*1.5 };
%card<i> = { name => 'Iphigenia in Brooklyn', :sex<F>, rating => %card<g><rating> + 15 - 2*2 };
%card<j> = { name => 'Josephine', :sex<F>, rating => Nil };
# adjustments to ratings for current race
%card<b><rating> += 4;
%card<c><rating> -= 4;
%card<h><rating> += 3;
%card<j><rating> = %card<a><rating> - 3 + 10*0.2;
# adjust filly's allowance
# initialize carry weights
for %card {
.value<rating> += 3 if .value<sex> eq 'F';
.value<weight> = (.value<sex> eq 'M') ?? 9.00 !! 8.11
}
my ($previous, $position, $leader) = 0;
say "Pos Horse Name Weight Back Sex Time";
for %card.sort( -*.value.<rating> ) {
FIRST $leader = $_;
++$position if $previous != .value.<rating>;
$previous = .value.<rating>;
.value<back> = ($leader.value<rating> - .value<rating>) / 2;
.value<time> = 96 - (.value.<rating> - 100) / 10;
printf "%2d %s %-22s %.2f %.1f %-6s %s\n", $position, .key, .value<name>, .value<weight>,
.value<back>, .value<sex> eq 'M' ?? 'colt' !! 'filly', .value.<time>.polymod(60 xx*).reverse.join: ':';
}
- Output:
Pos Horse Name Weight Back Sex Time 1 i Iphigenia in Brooklyn 8.11 0.0 filly 1:35.4 2 j Josephine 8.11 2.0 filly 1:35.8 3 a Alberta Clipper 9.00 3.0 colt 1:36 4 f Frequent Flyer 9.00 3.5 colt 1:36.1 5 h His Honor 9.00 4.0 colt 1:36.2 6 e Exterminator 9.00 4.5 colt 1:36.3 7 d Donnatello 8.11 5.5 filly 1:36.5 7 b Beetlebaum 8.11 5.5 filly 1:36.5 8 c Canyonero 9.00 6.5 colt 1:36.7 9 g Grindstone 9.00 7.0 colt 1:36.8
V (Vlang)
struct Kv {
key string
value []f64
}
fn main() {
// ratings on past form, assuming a rating of 100 for horse A
a := 100.0
mut b := a - 8 - 2*2 // carried 8 lbs less, finished 2 lengths behind
mut c := a + 4 - 2*3.5
mut d := a - 4 - 10*0.4 // based on relative weight and time
e := d + 7 - 2*1
f := d + 11 - 2*(4-2)
g := a - 10 + 10*0.2
mut h := g + 6 - 2*1.5
mut i := g + 15 - 2*2
// adjustments to ratings for current race
b += 4
c -= 4
h += 3
mut j := a - 3 + 10*0.2
// filly's allowance to give weight adjusted weighting
b += 3
d += 3
i += 3
j += 3
// create map of horse to its weight adjusted rating and whether colt (1 == yes, 0 == no)
m := {
"A": [a, 1],
"B": [b, 0],
"C": [c, 1],
"D": [d, 0],
"E": [e, 1],
"F": [f, 1],
"G": [g, 1],
"H": [h, 1],
"I": [i, 0],
"J": [j, 0],
}
// convert to slice of Kv
mut l := []Kv{ len: m.len}
mut x := 0
for k, v in m {
l[x] = Kv{k, v}
x++
}
// sort in descending order of rating
//sort.Slice(l, func(i, j int) bool { return l[i].value[0] > l[j].value[0] })
l.sort_with_compare(fn(a &Kv, b &Kv) int {
if a.value[0] < b.value[0] {
return 1
}else if a.value[0] > b.value[0] {
return -1
}
return 0
})
// show expected result of race
println("Race 4\n")
println("Pos Horse Weight Dist Sex")
mut pos := ""
for v in 0..l.len {
mut wt := "9.00"
if l[v].value[1] == 0 {
wt = "8.11"
}
mut dist := 0.0
if v > 0 {
dist = (l[v-1].value[0]-l[v].value[0]) * 0.5
}
if v == 0 || dist > 0.0 {
pos = "${v+1}"
} else {
if pos.index('=') or {-1} < 0{
pos = "${v}="
}
}
mut sx := "colt"
if l[v].value[1] == 0 {
sx = "filly"
}
println("${pos:-2} ${l[v].key} $wt ${dist:3.1f} $sx")
}
// weight adjusted rating of winner
wr := l[0].value[0]
// expected time of winner (relative to A's time in Race 1)
t := 96.0 - (wr-100)/10
min := int(t / 60)
sec := t - f64(min)*60
println("\nTime $min minute ${sec:3.1f} seconds")
}
- Output:
Same as go entry
Wren
import "./fmt" for Fmt
// ratings on past form, assuming a rating of 100 for horse A
var a = 100
var b = a - 8 - 2 * 2 // carried 8 lbs less, finished 2 lengths behind
var c = a + 4 - 2 * 3.5
var d = a - 4 - 10 * 0.4 // based on relative weight and time
var e = d + 7 - 2 * 1
var f = d + 11 - 2 * (4 - 2)
var g = a - 10 + 10 * 0.2
var h = g + 6 - 2 * 1.5
var i = g + 15 - 2 * 2
// adjustments to ratings for current race
b = b + 4
c = c - 4
h = h + 3
var j = a - 3 + 10 * 0.2
// filly's allowance to give weight adjusted weighting
b = b + 3
d = d + 3
i = i + 3
j = j + 3
// create map of horse to its weight adjusted rating and whether colt
var m = {
"A": [a, true],
"B": [b, false],
"C": [c, true],
"D": [d, false],
"E": [e, true],
"F": [f, true],
"G": [g, true],
"H": [h, true],
"I": [i, false],
"J": [j, false]
}
// convert to list of {key, value} map entries
var l = m.toList
// sort in descending order of rating
l.sort{ |i, j| i.value[0] >= j.value[0] }
// show expected result of race
System.print("Race 4\n")
System.print("Pos Horse Weight Dist Sex")
var pos = ""
for (x in 0...l.count) {
var wt = l[x].value[1] ? "9.00" : "8.11"
var dist = 0
if (x > 0) dist = (l[x-1].value[0] - l[x].value[0]) * 0.5
pos = (x == 0 || dist > 0) ? (x+1).toString : (!pos.endsWith("=") ? x.toString + "=" : pos)
var sx = l[x].value[1] ? "colt" : "filly"
Fmt.print("$-2s $s $s $3.1f $s", pos, l[x].key, wt, dist, sx)
}
// weight adjusted rating of winner
var wr = l[0].value[0]
// expected time of winner (relative to A's time in Race 1)
var t = 96 - (wr - 100) / 10
var min = (t/60).floor
var sec = t % 60
System.print("\nTime %(min) minute %(sec) seconds")
- Output:
Race 4 Pos Horse Weight Dist Sex 1 I 8.11 0.0 filly 2 J 8.11 2.0 filly 3 A 9.00 1.0 colt 4 F 9.00 0.5 colt 5 H 9.00 0.5 colt 6 E 9.00 0.5 colt 7 B 8.11 1.0 filly 7= D 8.11 0.0 filly 9 C 9.00 1.0 colt 10 G 9.00 0.5 colt Time 1 minute 35.4 seconds