Skip to content

Instantly share code, notes, and snippets.

@msepcot
Last active April 6, 2021 03:16
Show Gist options
  • Save msepcot/91e3ab02c04595d0c58ea534298585e7 to your computer and use it in GitHub Desktop.
Save msepcot/91e3ab02c04595d0c58ea534298585e7 to your computer and use it in GitHub Desktop.
A port of the Runner's World Age Grading Calculator to Swift
import Foundation
enum Gender {
case male, female // no non-binary data :/
}
enum Distance {
case fiveKm, sixKm, fourMi, eightKm, fiveM, tenKm, twelveKm, fifteenKm, tenMi, twentyKm, halfMarathon, twentyFiveKm, thirtyKm, marathon, fiftyKm, fiftyMi, oneHundredKm, oneHundredFiftyKm, oneHundredMi, twoHundredKm
}
enum Level {
case local, regional, national, world
}
struct RaceTime: CustomStringConvertible, Equatable {
let hours: Int
let minutes: Int
let seconds: Int
var inSeconds: Int {
return hours * 3600 + minutes * 60 + seconds
}
var description: String {
if hours > 0 {
return String(format: "%02i:%02i:%02i", hours, minutes, seconds)
} else {
return String(format: "%02i:%02i", minutes, seconds)
}
}
init(_ hours: Int = 0, _ minutes: Int = 0, _ seconds: Int = 0) {
self.hours = hours
self.minutes = minutes
self.seconds = seconds
}
init(seconds: Int = 0) {
self.hours = seconds / 3600
self.seconds = seconds % 60
self.minutes = (seconds - (self.hours * 3600)) / 60
}
}
struct Runner {
let age: Int
let gender: Gender
init(age: Int, gender: Gender) {
guard age > 4 && age < 101 else { fatalError("Age must be between 5-100") }
self.age = age
self.gender = gender
}
func goalsForDistance(_ distance: Distance) -> [Level: RaceTime] {
let optimalTime = Double(LookupTable[gender]![distance]![age])
return [
.local: RaceTime(seconds: Int(optimalTime / 0.6)),
.regional: RaceTime(seconds: Int(optimalTime / 0.7)),
.national: RaceTime(seconds: Int(optimalTime / 0.8)),
.world: RaceTime(seconds: Int(optimalTime / 0.9)),
]
}
}
struct Event {
let runner: Runner
let distance: Distance
let time: RaceTime
var ageGradedScore: Double {
let optimalTime = Double(LookupTable[runner.gender]![distance]![runner.age])
return optimalTime / Double(time.inSeconds)
}
var ageGradedTime: RaceTime {
let record = Double(LookupTable[runner.gender]![distance]![0])
return RaceTime(seconds: Int(record / ageGradedScore))
}
}
// Runner's World lookup table starts at age 5, goes to 100. Using index 0 for the distance record and padding 0s for the index to match the age.
let LookupTable: [Gender: [Distance: [Int]]] = [
.male: [
.fiveKm: [779, 0, 0, 0, 0, 1286, 1181, 1098, 1031, 977, 932, 895, 866, 842, 822, 807, 795, 786, 780, 779, 779, 779, 779, 779, 779, 779, 779, 779, 779, 780, 781, 783, 785, 788, 792, 796, 800, 805, 811, 817, 823, 828, 834, 840, 846, 853, 859, 865, 872, 878, 885, 892, 899, 906, 913, 920, 927, 935, 943, 950, 958, 966, 974, 982, 991, 999, 1008, 1017, 1026, 1037, 1048, 1061, 1075, 1090, 1107, 1125, 1145, 1166, 1190, 1216, 1244, 1275, 1308, 1345, 1386, 1431, 1480, 1535, 1597, 1665, 1743, 1830, 1930, 2044, 2177, 2332, 2517, 2739, 3012, 3353, 3794],
.sixKm: [942, 0, 0, 0, 0, 1555, 1428, 1328, 1247, 1181, 1127, 1083, 1047, 1018, 994, 976, 962, 950, 943, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 944, 945, 948, 951, 954, 959, 964, 970, 976, 983, 990, 998, 1005, 1012, 1020, 1028, 1036, 1044, 1052, 1060, 1068, 1076, 1085, 1094, 1103, 1112, 1121, 1130, 1139, 1149, 1159, 1169, 1179, 1189, 1199, 1210, 1221, 1232, 1243, 1256, 1270, 1285, 1302, 1320, 1340, 1362, 1386, 1413, 1441, 1473, 1507, 1545, 1586, 1631, 1681, 1736, 1797, 1865, 1940, 2025, 2120, 2228, 2352, 2494, 2660, 2854, 3085, 3365, 3712, 4146, 4715],
.fourMi: [1014, 0, 0, 0, 0, 1674, 1537, 1429, 1342, 1271, 1213, 1166, 1127, 1096, 1070, 1050, 1035, 1023, 1015, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1017, 1019, 1022, 1026, 1031, 1036, 1042, 1049, 1057, 1064, 1072, 1080, 1088, 1096, 1105, 1113, 1122, 1131, 1139, 1148, 1158, 1167, 1176, 1186, 1196, 1206, 1216, 1226, 1237, 1247, 1258, 1269, 1280, 1292, 1303, 1315, 1327, 1339, 1353, 1368, 1385, 1403, 1423, 1445, 1469, 1495, 1524, 1555, 1589, 1626, 1667, 1712, 1761, 1815, 1875, 1941, 2015, 2098, 2190, 2294, 2412, 2547, 2703, 2884, 3098, 3352, 3661, 4041, 4525, 5155],
.eightKm: [1272, 0, 0, 0, 0, 2100, 1928, 1793, 1683, 1595, 1522, 1463, 1414, 1374, 1342, 1317, 1298, 1283, 1273, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1273, 1274, 1276, 1279, 1283, 1288, 1294, 1301, 1309, 1318, 1328, 1338, 1348, 1358, 1369, 1380, 1391, 1402, 1413, 1424, 1436, 1448, 1460, 1472, 1484, 1497, 1510, 1523, 1536, 1550, 1564, 1578, 1592, 1606, 1621, 1636, 1652, 1667, 1683, 1700, 1719, 1739, 1762, 1787, 1814, 1844, 1876, 1912, 1951, 1994, 2040, 2091, 2148, 2209, 2277, 2352, 2435, 2528, 2631, 2747, 2878, 3026, 3197, 3393, 3622, 3891, 4212, 4602, 5086, 5699, 6500],
.fiveM: [1279, 0, 0, 0, 0, 2112, 1939, 1802, 1693, 1604, 1531, 1471, 1422, 1382, 1350, 1325, 1306, 1290, 1280, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1280, 1281, 1283, 1286, 1290, 1295, 1301, 1308, 1316, 1325, 1335, 1345, 1355, 1366, 1376, 1387, 1398, 1409, 1420, 1432, 1444, 1456, 1468, 1480, 1493, 1505, 1518, 1531, 1545, 1558, 1572, 1586, 1601, 1615, 1630, 1645, 1661, 1676, 1692, 1709, 1728, 1749, 1771, 1797, 1824, 1854, 1887, 1922, 1962, 2005, 2051, 2103, 2159, 2221, 2289, 2365, 2448, 2541, 2645, 2762, 2894, 3043, 3214, 3411, 3641, 3911, 4234, 4626, 5112, 5725, 6532],
.tenKm: [1603, 0, 0, 0, 0, 2647, 2430, 2259, 2121, 2010, 1918, 1843, 1782, 1732, 1692, 1660, 1636, 1617, 1604, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1604, 1606, 1608, 1613, 1618, 1624, 1632, 1641, 1651, 1663, 1676, 1689, 1702, 1716, 1730, 1744, 1758, 1773, 1787, 1803, 1818, 1833, 1849, 1865, 1882, 1898, 1915, 1932, 1950, 1968, 1986, 2005, 2024, 2043, 2063, 2083, 2103, 2124, 2146, 2169, 2194, 2223, 2254, 2288, 2326, 2367, 2412, 2461, 2515, 2574, 2639, 2710, 2788, 2874, 2970, 3075, 3193, 3325, 3473, 3640, 3830, 4048, 4300, 4594, 4941, 5356, 5863, 6490, 7293, 8349],
.twelveKm: [1942, 0, 0, 0, 0, 3207, 2944, 2737, 2570, 2435, 2324, 2233, 2159, 2098, 2049, 2011, 1982, 1958, 1943, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1944, 1947, 1952, 1958, 1965, 1974, 1984, 1997, 2010, 2025, 2041, 2058, 2074, 2091, 2108, 2126, 2143, 2162, 2180, 2199, 2217, 2237, 2256, 2276, 2297, 2317, 2338, 2360, 2382, 2404, 2427, 2450, 2473, 2497, 2522, 2547, 2573, 2598, 2626, 2657, 2690, 2728, 2769, 2814, 2863, 2918, 2977, 3042, 3113, 3190, 3276, 3370, 3475, 3590, 3717, 3860, 4019, 4198, 4401, 4630, 4894, 5199, 5557, 5977, 6482, 7098, 7862, 8839, 10130],
.fifteenKm: [2455, 0, 0, 0, 0, 4054, 3722, 3460, 3249, 3078, 2938, 2823, 2729, 2652, 2591, 2542, 2506, 2476, 2457, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2456, 2460, 2465, 2472, 2480, 2491, 2503, 2518, 2534, 2553, 2573, 2594, 2615, 2637, 2658, 2681, 2703, 2726, 2749, 2773, 2797, 2822, 2847, 2872, 2898, 2925, 2952, 2979, 3007, 3035, 3064, 3094, 3124, 3155, 3186, 3218, 3250, 3283, 3318, 3356, 3398, 3445, 3496, 3552, 3614, 3682, 3756, 3837, 3926, 4024, 4132, 4250, 4382, 4526, 4687, 4866, 5067, 5293, 5548, 5840, 6173, 6559, 7010, 7542, 8183, 8963, 9935, 11179, 12827],
.tenMi: [2640, 0, 0, 0, 0, 4359, 4002, 3720, 3494, 3310, 3159, 3036, 2935, 2852, 2786, 2734, 2695, 2662, 2642, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2641, 2645, 2650, 2657, 2666, 2677, 2690, 2705, 2723, 2743, 2765, 2787, 2810, 2833, 2857, 2880, 2905, 2929, 2955, 2980, 3006, 3033, 3059, 3087, 3115, 3143, 3172, 3202, 3232, 3262, 3294, 3326, 3358, 3391, 3425, 3460, 3494, 3530, 3567, 3608, 3653, 3703, 3757, 3818, 3884, 3956, 4035, 4123, 4219, 4324, 4439, 4566, 4707, 4862, 5034, 5228, 5443, 5685, 5959, 6272, 6630, 7044, 7530, 8103, 8788, 9628, 10675, 12011, 13779],
.twentyKm: [3315, 0, 0, 0, 0, 5474, 5026, 4672, 4387, 4156, 3967, 3812, 3685, 3581, 3498, 3433, 3384, 3343, 3317, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3315, 3316, 3319, 3324, 3332, 3343, 3356, 3372, 3390, 3411, 3435, 3461, 3490, 3518, 3548, 3578, 3608, 3638, 3669, 3701, 3734, 3767, 3800, 3834, 3869, 3905, 3940, 3977, 4014, 4053, 4091, 4131, 4171, 4212, 4254, 4297, 4341, 4386, 4431, 4477, 4527, 4583, 4644, 4712, 4786, 4869, 4958, 5057, 5165, 5285, 5415, 5559, 5717, 5893, 6087, 6303, 6544, 6813, 7117, 7459, 7850, 8300, 8819, 9426, 10147, 11010, 12063, 13378, 15061, 17293],
.halfMarathon: [3503, 0, 0, 0, 0, 5784, 5311, 4937, 4636, 4392, 4192, 4028, 3894, 3785, 3697, 3628, 3576, 3533, 3505, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3503, 3504, 3507, 3512, 3521, 3531, 3545, 3561, 3580, 3602, 3627, 3655, 3685, 3716, 3747, 3778, 3810, 3842, 3875, 3909, 3943, 3978, 4014, 4050, 4087, 4124, 4162, 4201, 4240, 4281, 4321, 4363, 4406, 4450, 4494, 4539, 4586, 4633, 4681, 4731, 4783, 4841, 4906, 4977, 5056, 5142, 5237, 5341, 5455, 5581, 5718, 5870, 6038, 6222, 6426, 6653, 6908, 7192, 7511, 7874, 8285, 8758, 9307, 9946, 10703, 11611, 12724, 14108, 15879, 18235],
.twentyFiveKm: [4205, 0, 0, 0, 0, 6944, 6375, 5926, 5565, 5272, 5032, 4836, 4674, 4543, 4438, 4355, 4293, 4241, 4208, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4206, 4210, 4216, 4226, 4239, 4255, 4275, 4298, 4324, 4354, 4388, 4424, 4460, 4497, 4535, 4573, 4612, 4652, 4693, 4733, 4775, 4818, 4861, 4906, 4950, 4996, 5043, 5090, 5139, 5188, 5238, 5289, 5342, 5395, 5449, 5505, 5561, 5619, 5679, 5741, 5811, 5889, 5975, 6069, 6172, 6286, 6411, 6548, 6699, 6864, 7046, 7248, 7469, 7714, 7987, 8292, 8633, 9016, 9452, 9946, 10513, 11172, 11939, 12848, 13938, 15274, 16935, 19062, 21890],
.thirtyKm: [5110, 0, 0, 0, 0, 8438, 7747, 7201, 6763, 6407, 6115, 5876, 5680, 5521, 5393, 5292, 5216, 5153, 5114, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5110, 5111, 5116, 5124, 5136, 5151, 5171, 5195, 5223, 5254, 5291, 5332, 5376, 5420, 5465, 5511, 5557, 5605, 5653, 5702, 5752, 5803, 5855, 5908, 5961, 6015, 6071, 6128, 6186, 6245, 6304, 6365, 6428, 6491, 6556, 6622, 6689, 6758, 6829, 6901, 6977, 7062, 7157, 7261, 7375, 7500, 7639, 7791, 7957, 8141, 8341, 8562, 8807, 9076, 9374, 9706, 10077, 10491, 10956, 11486, 12086, 12775, 13576, 14509, 15613, 16937, 18562, 20580, 23164, 26601],
.marathon: [7377, 0, 0, 0, 0, 12181, 11184, 10396, 9763, 9249, 8828, 8483, 8200, 7970, 7785, 7640, 7531, 7439, 7382, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7377, 7378, 7385, 7397, 7414, 7436, 7465, 7499, 7540, 7586, 7638, 7697, 7760, 7825, 7890, 7955, 8023, 8091, 8161, 8232, 8304, 8377, 8452, 8528, 8606, 8684, 8764, 8846, 8930, 9015, 9101, 9189, 9279, 9371, 9465, 9559, 9657, 9757, 9858, 9962, 10072, 10195, 10332, 10482, 10647, 10828, 11029, 11247, 11487, 11752, 12042, 12361, 12715, 13103, 13533, 14011, 14547, 15145, 15817, 16581, 17448, 18443, 19599, 20945, 22539, 24451, 26796, 29710, 33441, 38402],
.fiftyKm: [8970, 0, 0, 0, 0, 14812, 13599, 12641, 11871, 11246, 10735, 10315, 9971, 9691, 9466, 9290, 9157, 9046, 8976, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8970, 8972, 8980, 8994, 9015, 9042, 9077, 9119, 9168, 9224, 9288, 9359, 9436, 9514, 9594, 9673, 9755, 9839, 9924, 10010, 10097, 10186, 10277, 10370, 10464, 10559, 10657, 10757, 10858, 10962, 11066, 11173, 11283, 11395, 11509, 11624, 11742, 11864, 11987, 12113, 12247, 12396, 12563, 12745, 12946, 13166, 13410, 13676, 13968, 14290, 14643, 15030, 15460, 15933, 16456, 17037, 17689, 18415, 19232, 20162, 21216, 22425, 23831, 25468, 27406, 29732, 32583, 36126, 40662, 46694],
.fiftyMi: [16080, 0, 0, 0, 0, 26552, 24378, 22661, 21281, 20160, 19244, 18491, 17875, 17373, 16969, 16653, 16415, 16216, 16091, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16080, 16083, 16098, 16124, 16161, 16210, 16272, 16346, 16435, 16535, 16649, 16778, 16916, 17056, 17198, 17341, 17488, 17637, 17790, 17944, 18100, 18260, 18423, 18590, 18759, 18929, 19104, 19283, 19465, 19650, 19837, 20030, 20226, 20427, 20631, 20837, 21050, 21267, 21489, 21715, 21955, 22222, 22521, 22847, 23207, 23602, 24039, 24516, 25039, 25617, 26249, 26944, 27715, 28561, 29499, 30541, 31710, 33012, 34477, 36143, 38032, 40200, 42721, 45656, 49129, 53298, 58409, 64760, 72892, 83706],
.oneHundredKm: [21360, 0, 0, 0, 0, 35271, 32383, 30101, 28269, 26780, 25562, 24563, 23744, 23077, 22541, 22121, 21805, 21541, 21375, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21360, 21364, 21384, 21418, 21467, 21532, 21615, 21714, 21832, 21964, 22116, 22287, 22470, 22656, 22845, 23035, 23230, 23429, 23631, 23837, 24043, 24256, 24473, 24694, 24918, 25144, 25377, 25615, 25856, 26103, 26351, 26607, 26868, 27134, 27406, 27679, 27962, 28250, 28545, 28845, 29164, 29519, 29916, 30350, 30827, 31352, 31933, 32566, 33261, 34029, 34868, 35791, 36815, 37940, 39185, 40570, 42122, 43851, 45798, 48011, 50520, 53400, 56748, 60647, 65261, 70799, 77588, 86025, 96827, 111192],
.oneHundredFiftyKm: [36300, 0, 0, 0, 0, 59941, 55033, 51156, 48041, 45512, 43442, 41743, 40351, 39218, 38307, 37593, 37056, 36608, 36325, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36300, 36307, 36340, 36398, 36482, 36593, 36733, 36901, 37101, 37326, 37585, 37876, 38186, 38502, 38824, 39146, 39478, 39816, 40159, 40509, 40860, 41222, 41590, 41965, 42347, 42731, 43127, 43530, 43941, 44360, 44782, 45217, 45660, 46113, 46574, 47039, 47519, 48010, 48510, 49021, 49563, 50166, 50840, 51577, 52389, 53280, 54268, 55344, 56524, 57830, 59256, 60824, 62565, 64476, 66593, 68946, 71584, 74523, 77830, 81591, 85856, 90750, 96440, 103066, 110907, 120318, 131856, 146194, 164551, 188964],
.oneHundredMi: [39850, 0, 0, 0, 0, 65803, 60415, 56158, 52740, 49962, 47690, 45826, 44297, 43053, 42054, 41270, 40680, 40188, 39878, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39850, 39858, 39894, 39958, 40050, 40171, 40326, 40510, 40730, 40977, 41261, 41580, 41921, 42268, 42620, 42974, 43339, 43710, 44087, 44470, 44856, 45253, 45658, 46069, 46489, 46910, 47345, 47788, 48239, 48699, 49161, 49639, 50126, 50622, 51129, 51639, 52167, 52705, 53254, 53815, 54410, 55072, 55812, 56621, 57512, 58491, 59575, 60756, 62052, 63486, 65051, 66773, 68683, 70782, 73106, 75689, 78584, 81811, 85442, 89571, 94253, 99625, 105871, 113146, 121754, 132085, 144751, 160491, 180644, 207444],
.twoHundredKm: [52800, 0, 0, 0, 0, 87186, 80049, 74408, 69878, 66199, 63188, 60718, 58693, 57044, 55720, 54681, 53900, 53247, 52837, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52800, 52811, 52858, 52943, 53065, 53226, 53430, 53675, 53966, 54293, 54670, 55092, 55544, 56003, 56471, 56940, 57423, 57914, 58414, 58922, 59433, 59959, 60495, 61040, 61596, 62154, 62730, 63317, 63915, 64524, 65137, 65770, 66415, 67073, 67744, 68420, 69119, 69832, 70560, 71303, 72092, 72968, 73950, 75021, 76201, 77499, 78936, 80500, 82217, 84117, 86190, 88472, 91003, 93783, 96863, 100285, 104121, 108397, 113208, 118678, 124882, 132000, 140276, 149915, 161320, 175008, 191791, 212646, 239347, 274857]
],
.female: [
.fiveKm: [886, 0, 0, 0, 0, 1264, 1207, 1157, 1114, 1076, 1043, 1014, 989, 967, 947, 931, 915, 900, 890, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 886, 887, 888, 890, 892, 894, 898, 901, 905, 910, 915, 921, 928, 935, 943, 951, 960, 970, 981, 991, 1002, 1013, 1025, 1036, 1048, 1061, 1073, 1086, 1099, 1112, 1126, 1140, 1155, 1169, 1184, 1200, 1216, 1232, 1249, 1267, 1284, 1303, 1322, 1341, 1361, 1382, 1403, 1425, 1448, 1473, 1502, 1535, 1572, 1613, 1659, 1711, 1771, 1837, 1913, 2000, 2099, 2214, 2348, 2506, 2695, 2923, 3205, 3560, 4020, 4641],
.sixKm: [1071, 0, 0, 0, 0, 1545, 1475, 1413, 1360, 1314, 1273, 1238, 1206, 1179, 1155, 1135, 1116, 1097, 1083, 1074, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1072, 1073, 1076, 1078, 1081, 1085, 1090, 1095, 1101, 1107, 1115, 1123, 1132, 1141, 1152, 1163, 1175, 1188, 1201, 1215, 1229, 1243, 1257, 1272, 1287, 1303, 1319, 1335, 1352, 1369, 1387, 1405, 1423, 1442, 1462, 1482, 1502, 1523, 1545, 1568, 1591, 1615, 1639, 1664, 1691, 1717, 1745, 1774, 1807, 1844, 1886, 1933, 1986, 2045, 2112, 2188, 2274, 2372, 2484, 2613, 2764, 2940, 3148, 3399, 3705, 4086, 4573, 5214, 6099],
.fourMi: [1152, 0, 0, 0, 0, 1643, 1586, 1520, 1463, 1413, 1369, 1331, 1298, 1268, 1243, 1220, 1200, 1180, 1164, 1155, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1153, 1155, 1157, 1160, 1163, 1168, 1172, 1178, 1184, 1192, 1199, 1208, 1218, 1228, 1240, 1252, 1265, 1279, 1294, 1308, 1323, 1339, 1354, 1371, 1387, 1404, 1421, 1439, 1457, 1476, 1495, 1515, 1535, 1555, 1577, 1599, 1621, 1644, 1668, 1693, 1718, 1744, 1771, 1798, 1827, 1856, 1887, 1919, 1955, 1996, 2042, 2093, 2152, 2217, 2291, 2374, 2469, 2577, 2701, 2844, 3011, 3206, 3439, 3719, 4061, 4489, 5042, 5772, 6788],
.eightKm: [1442, 0, 0, 0, 0, 2057, 1985, 1903, 1831, 1769, 1714, 1666, 1624, 1587, 1555, 1528, 1502, 1477, 1458, 1446, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1443, 1445, 1448, 1452, 1457, 1462, 1468, 1475, 1484, 1493, 1503, 1514, 1526, 1540, 1555, 1570, 1588, 1606, 1624, 1643, 1663, 1682, 1703, 1724, 1745, 1767, 1790, 1812, 1836, 1860, 1885, 1911, 1937, 1964, 1992, 2021, 2050, 2081, 2112, 2144, 2177, 2211, 2246, 2283, 2321, 2359, 2400, 2442, 2491, 2546, 2608, 2677, 2755, 2843, 2942, 3055, 3183, 3330, 3499, 3695, 3924, 4194, 4519, 4913, 5403, 6021, 6834, 7936, 9524],
.fiveM: [1452, 0, 0, 0, 0, 2071, 1999, 1916, 1844, 1781, 1726, 1678, 1636, 1598, 1566, 1538, 1513, 1488, 1468, 1456, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1453, 1455, 1458, 1462, 1467, 1472, 1478, 1486, 1494, 1503, 1513, 1525, 1537, 1551, 1565, 1581, 1599, 1617, 1636, 1655, 1674, 1694, 1715, 1736, 1757, 1779, 1802, 1825, 1849, 1874, 1899, 1924, 1951, 1978, 2006, 2035, 2065, 2096, 2127, 2159, 2193, 2227, 2263, 2300, 2337, 2377, 2417, 2461, 2510, 2565, 2627, 2697, 2776, 2864, 2965, 3079, 3208, 3356, 3527, 3724, 3955, 4230, 4556, 4956, 5448, 6075, 6895, 8013, 9622],
.tenKm: [1820, 0, 0, 0, 0, 2596, 2506, 2402, 2311, 2233, 2163, 2103, 2050, 2004, 1963, 1928, 1896, 1865, 1840, 1825, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1820, 1822, 1825, 1828, 1833, 1839, 1846, 1854, 1863, 1874, 1886, 1899, 1913, 1929, 1947, 1966, 1986, 2009, 2032, 2056, 2081, 2106, 2132, 2159, 2186, 2214, 2243, 2272, 2302, 2333, 2365, 2398, 2432, 2466, 2502, 2538, 2576, 2615, 2655, 2696, 2739, 2783, 2828, 2875, 2924, 2974, 3026, 3080, 3137, 3204, 3278, 3361, 3455, 3561, 3680, 3816, 3969, 4146, 4347, 4581, 4852, 5172, 5552, 6013, 6578, 7289, 8202, 9430, 11145, 13736],
.twelveKm: [2194, 0, 0, 0, 0, 3130, 3021, 2895, 2786, 2691, 2608, 2535, 2471, 2415, 2367, 2324, 2285, 2248, 2218, 2200, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2194, 2196, 2199, 2204, 2209, 2217, 2225, 2235, 2246, 2259, 2273, 2289, 2307, 2326, 2347, 2370, 2395, 2422, 2450, 2479, 2509, 2539, 2571, 2603, 2635, 2669, 2704, 2739, 2775, 2813, 2851, 2891, 2931, 2973, 3016, 3060, 3105, 3152, 3201, 3250, 3302, 3355, 3409, 3466, 3524, 3585, 3648, 3714, 3788, 3872, 3965, 4071, 4189, 4321, 4471, 4639, 4832, 5051, 5301, 5591, 5930, 6326, 6801, 7372, 8078, 8962, 10106, 11645, 13807, 17074],
.fifteenKm: [2755, 0, 0, 0, 0, 3930, 4317, 4056, 3838, 3655, 3501, 3369, 3257, 3162, 3081, 3013, 2951, 2892, 2841, 2803, 2776, 2760, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2756, 2758, 2762, 2767, 2774, 2783, 2793, 2805, 2818, 2833, 2850, 2869, 2890, 2913, 2938, 2965, 2994, 3026, 3060, 3096, 3133, 3171, 3210, 3250, 3290, 3332, 3375, 3419, 3464, 3510, 3558, 3607, 3657, 3709, 3762, 3817, 3873, 3931, 3991, 4053, 4116, 4182, 4250, 4320, 4392, 4467, 4544, 4626, 4717, 4818, 4931, 5058, 5199, 5358, 5535, 5735, 5961, 6216, 6508, 6843, 7231, 7683, 8214, 8850, 9619, 10572, 11774, 13341, 15460, 18478, 23132],
.tenMi: [2961, 0, 0, 0, 0, 4224, 4276, 4056, 3868, 3706, 3567, 3447, 3343, 3253, 3176, 3109, 3048, 2989, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2961, 2962, 2964, 2968, 2974, 2982, 2991, 3002, 3014, 3029, 3045, 3063, 3084, 3106, 3131, 3157, 3186, 3218, 3252, 3289, 3328, 3367, 3408, 3450, 3493, 3536, 3581, 3627, 3675, 3723, 3773, 3824, 3877, 3931, 3986, 4043, 4102, 4163, 4225, 4289, 4356, 4424, 4495, 4567, 4643, 4720, 4801, 4884, 4973, 5073, 5183, 5307, 5445, 5599, 5772, 5965, 6182, 6427, 6705, 7022, 7384, 7804, 8294, 8871, 9561, 10393, 11424, 12730, 14423, 16719, 19993, 25030],
.twentyKm: [3700, 0, 0, 0, 0, 5278, 5344, 5068, 4833, 4631, 4458, 4308, 4178, 4065, 3968, 3885, 3809, 3735, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3700, 3701, 3704, 3709, 3716, 3726, 3737, 3751, 3767, 3785, 3805, 3828, 3853, 3881, 3912, 3945, 3981, 4021, 4064, 4110, 4158, 4208, 4259, 4311, 4364, 4419, 4475, 4533, 4592, 4652, 4715, 4779, 4844, 4912, 4981, 5053, 5126, 5202, 5280, 5360, 5443, 5528, 5616, 5707, 5801, 5898, 5999, 6106, 6224, 6354, 6500, 6662, 6842, 7041, 7265, 7514, 7794, 8109, 8465, 8871, 9336, 9872, 10496, 11233, 12111, 13172, 14481, 16136, 18290, 21191, 25325, 31651],
.halfMarathon: [3912, 0, 0, 0, 0, 5581, 6130, 5759, 5450, 5190, 4971, 4784, 4625, 4490, 4375, 4278, 4191, 4107, 4035, 3980, 3942, 3919, 3912, 3912, 3912, 3912, 3912, 3912, 3912, 3912, 3913, 3916, 3922, 3929, 3939, 3951, 3966, 3982, 4002, 4023, 4047, 4074, 4104, 4136, 4171, 4210, 4252, 4297, 4345, 4396, 4449, 4503, 4558, 4614, 4672, 4731, 4792, 4855, 4919, 4985, 5052, 5122, 5193, 5267, 5342, 5420, 5500, 5582, 5667, 5755, 5845, 5938, 6034, 6134, 6236, 6342, 6457, 6584, 6724, 6879, 7051, 7243, 7457, 7695, 7959, 8257, 8592, 8972, 9404, 9896, 10465, 11129, 11912, 12843, 13966, 15353, 17105, 19386, 22457, 26813, 33493],
.twentyFiveKm: [4665, 0, 0, 0, 0, 6655, 6737, 6390, 6093, 5839, 5620, 5431, 5268, 5126, 5003, 4898, 4802, 4710, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4665, 4666, 4670, 4677, 4686, 4698, 4713, 4730, 4750, 4773, 4799, 4828, 4861, 4896, 4935, 4978, 5025, 5075, 5130, 5189, 5250, 5314, 5379, 5446, 5514, 5584, 5657, 5730, 5806, 5883, 5964, 6046, 6130, 6217, 6306, 6398, 6493, 6590, 6690, 6794, 6901, 7011, 7124, 7243, 7364, 7489, 7619, 7761, 7919, 8093, 8287, 8503, 8744, 9011, 9310, 9642, 10017, 10441, 10923, 11470, 12101, 12834, 13692, 14707, 15922, 17413, 19269, 21647, 24801, 29156, 35584, 46006],
.thirtyKm: [5660, 0, 0, 0, 0, 8074, 8174, 7752, 7393, 7085, 6819, 6590, 6391, 6219, 6070, 5942, 5826, 5714, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5660, 5661, 5666, 5674, 5686, 5701, 5720, 5742, 5768, 5798, 5831, 5870, 5911, 5958, 6008, 6065, 6125, 6191, 6262, 6338, 6416, 6495, 6576, 6659, 6745, 6832, 6922, 7014, 7109, 7206, 7306, 7408, 7515, 7624, 7735, 7851, 7970, 8093, 8218, 8349, 8483, 8623, 8766, 8915, 9069, 9229, 9405, 9603, 9821, 10062, 10332, 10633, 10967, 11340, 11760, 12230, 12765, 13371, 14066, 14867, 15797, 16896, 18199, 19776, 21719, 24167, 27330, 31585, 37633, 46777, 62404],
.marathon: [8125, 0, 0, 0, 0, 11591, 11187, 10722, 10319, 9967, 9658, 9389, 9152, 8944, 8764, 8607, 8464, 8325, 8213, 8147, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8125, 8127, 8134, 8146, 8163, 8186, 8213, 8245, 8284, 8327, 8377, 8433, 8495, 8563, 8638, 8720, 8809, 8907, 9012, 9123, 9237, 9354, 9474, 9597, 9724, 9853, 9986, 10123, 10264, 10409, 10557, 10711, 10868, 11030, 11198, 11370, 11548, 11731, 11920, 12116, 12318, 12527, 12743, 12967, 13199, 13448, 13725, 14033, 14375, 14757, 15181, 15655, 16185, 16780, 17451, 18209, 19073, 20062, 21203, 22532, 24095, 25958, 28212, 30988, 34486, 39025, 45139, 53808, 67038, 89680, 137247],
.fiftyKm: [9820, 0, 0, 0, 0, 14009, 13521, 12959, 12471, 12046, 11672, 11347, 11061, 10810, 10592, 10403, 10229, 10061, 9926, 9847, 9820, 9820, 9820, 9820, 9820, 9820, 9820, 9820, 9820, 9820, 9820, 9822, 9831, 9846, 9866, 9893, 9926, 9965, 10012, 10065, 10125, 10192, 10267, 10349, 10440, 10539, 10647, 10765, 10892, 11026, 11164, 11306, 11451, 11599, 11752, 11909, 12070, 12235, 12405, 12580, 12760, 12945, 13135, 13332, 13534, 13742, 13957, 14178, 14407, 14644, 14888, 15140, 15402, 15672, 15952, 16253, 16588, 16960, 17374, 17835, 18348, 18921, 19562, 20281, 21091, 22008, 23052, 24247, 25626, 27232, 29122, 31374, 34097, 37452, 41681, 47166, 54556, 65033, 81023, 108389, 165878],
.fiftyMi: [17760, 0, 0, 0, 0, 25335, 24453, 23436, 22555, 21786, 21110, 20522, 20005, 19551, 19157, 18814, 18500, 18197, 17952, 17808, 17760, 17760, 17760, 17760, 17760, 17760, 17760, 17760, 17760, 17760, 17760, 17764, 17780, 17806, 17844, 17892, 17952, 18023, 18108, 18202, 18311, 18433, 18568, 18716, 18882, 19060, 19256, 19469, 19698, 19942, 20191, 20447, 20709, 20978, 21254, 21538, 21829, 22128, 22436, 22752, 23077, 23412, 23756, 24111, 24476, 24853, 25242, 25643, 26056, 26484, 26925, 27382, 27854, 28343, 28850, 29394, 30000, 30674, 31423, 32256, 33184, 34220, 35378, 36679, 38144, 39803, 41690, 43852, 46347, 49251, 52669, 56741, 61667, 67735, 75382, 85303, 98667, 117616, 146535, 196026, 300000],
.oneHundredKm: [23591, 0, 0, 0, 0, 33653, 32481, 31131, 29961, 28939, 28041, 27260, 26572, 25970, 25446, 24990, 24574, 24171, 23846, 23655, 23591, 23591, 23591, 23591, 23591, 23591, 23591, 23591, 23591, 23591, 23591, 23596, 23617, 23652, 23702, 23767, 23846, 23941, 24053, 24179, 24323, 24485, 24664, 24861, 25081, 25318, 25578, 25862, 26166, 26489, 26820, 27160, 27508, 27866, 28232, 28609, 28996, 29393, 29802, 30222, 30654, 31098, 31556, 32027, 32512, 33013, 33529, 34062, 34611, 35179, 35766, 36372, 37000, 37649, 38322, 39045, 39850, 40744, 41739, 42846, 44079, 45455, 46994, 48722, 50668, 52871, 55378, 58249, 61563, 65422, 69961, 75371, 81913, 89973, 100132, 113309, 131061, 156232, 194645, 260386, 398497],
.oneHundredFiftyKm: [39700, 0, 0, 0, 0, 56633, 54661, 52388, 50419, 48700, 47189, 45875, 44717, 43703, 42822, 42055, 41354, 40676, 40129, 39807, 39700, 39700, 39700, 39700, 39700, 39700, 39700, 39700, 39700, 39700, 39700, 39708, 39744, 39803, 39887, 39996, 40129, 40288, 40477, 40689, 40932, 41204, 41505, 41838, 42207, 42606, 43045, 43521, 44033, 44577, 45134, 45706, 46292, 46893, 47511, 48145, 48795, 49464, 50152, 50858, 51585, 52333, 53103, 53896, 54713, 55556, 56424, 57320, 58245, 59201, 60188, 61209, 62265, 63358, 64490, 65707, 67061, 68566, 70241, 72103, 74178, 76493, 79084, 81991, 85266, 88974, 93192, 98025, 103601, 110094, 117734, 126837, 137847, 151411, 168506, 190682, 220556, 262914, 327558, 438190, 670608],
.oneHundredMi: [43500, 0, 0, 0, 0, 62054, 59893, 57403, 55245, 53361, 51706, 50266, 48998, 47886, 46921, 46081, 45313, 44570, 43970, 43618, 43500, 43500, 43500, 43500, 43500, 43500, 43500, 43500, 43500, 43500, 43500, 43509, 43548, 43613, 43705, 43824, 43970, 44145, 44352, 44583, 44850, 45148, 45478, 45843, 46247, 46684, 47165, 47687, 48248, 48843, 49454, 50081, 50723, 51382, 52058, 52753, 53466, 54199, 54952, 55726, 56523, 57342, 58186, 59055, 59950, 60873, 61825, 62807, 63820, 64867, 65949, 67068, 68225, 69422, 70663, 71996, 73480, 75130, 76964, 79005, 81278, 83815, 86653, 89839, 93428, 97490, 102113, 107407, 113518, 120632, 129004, 138978, 151042, 165904, 184635, 208934, 241667, 288079, 358911, 480132, 734797],
.twoHundredKm: [57600, 0, 0, 0, 0, 82168, 79306, 76010, 73152, 70658, 68465, 66559, 64879, 63408, 62129, 61017, 60000, 59016, 58223, 57756, 57600, 57600, 57600, 57600, 57600, 57600, 57600, 57600, 57600, 57600, 57600, 57612, 57663, 57750, 57872, 58029, 58223, 58453, 58728, 59035, 59388, 59782, 60220, 60702, 61238, 61816, 62453, 63144, 63886, 64675, 65484, 66314, 67164, 68037, 68933, 69852, 70796, 71767, 72764, 73789, 74844, 75929, 77047, 78197, 79383, 80605, 81865, 83165, 84507, 85893, 87326, 88807, 90339, 91925, 93567, 95333, 97297, 99482, 101911, 104613, 107623, 110983, 114741, 118959, 123711, 129090, 135211, 142222, 150313, 159734, 170819, 184026, 200000, 219680, 244482, 276657, 320000, 381457, 475248, 635762, 972973]
]
]
let michael = Runner(age: 37, gender: .male)
let marathon = Event(runner: michael, distance: .marathon, time: RaceTime(3, 23, 19))
print("Marathon time of \(marathon.time) is age adjusted to \(marathon.ageGradedTime) with a score of \(Int(marathon.ageGradedScore * 100))%")
let marathonGoals = michael.goalsForDistance(.marathon)
print("Local Class: \(marathonGoals[.local]!)")
print("Regional Class: \(marathonGoals[.regional]!)")
print("National Class: \(marathonGoals[.national]!)")
print("World Class: \(marathonGoals[.world]!)")
let fiveK = Event(runner: michael, distance: .fiveKm, time: RaceTime(0, 19, 33))
print("5K time of \(fiveK.time) is age adjusted to \(fiveK.ageGradedTime) with a score of \(Int(fiveK.ageGradedScore * 100))%")
let fiveKGoals = michael.goalsForDistance(.fiveKm)
print("Local Class: \(fiveKGoals[.local]!)")
print("Regional Class: \(fiveKGoals[.regional]!)")
print("National Class: \(fiveKGoals[.national]!)")
print("World Class: \(fiveKGoals[.world]!)")
@msepcot
Copy link
Author

msepcot commented Apr 6, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment