Implement weighted_median(values, weights): sort by value and return the first value at which the cumulative weight reaches at least half the total weight. If the cumulative weight hits exactly half at some value, return the average of that value and the next one.