Averages/Median: Difference between revisions
→{{header|C sharp|C#}}
imported>Arakov |
RandomTask (talk | contribs) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 2,109:
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|10+}}
<syntaxhighlight lang="csharp">
double median(double[] arr)
{
var sorted = arr.OrderBy(x => x).ToList();
var mid = arr.Length / 2;
return arr.Length % 2 == 0
? (sorted[mid] + sorted[mid-1]) / 2
: sorted[mid];
}
var write = (double[] x) =>
Console.WriteLine($"[{string.Join(", ", x)}]: {median(x)}");
write(new double[] { 1, 5, 3, 6, 4, 2 }); //even
write(new double[] { 1, 5, 3, 6, 4, 2, 7 }); //odd
write(new double[] { 5 }); //single
</syntaxhighlight>
{{output}}
<pre>
[1, 5, 3, 6, 4, 2]: 3.5
[1, 5, 3, 6, 4, 2, 7]: 4
[5]: 5
</pre>
=={{header|C++}}==
Line 5,250 ⟶ 5,239:
calcmedian x
display r(p50)</syntaxhighlight>
=={{header|Swift}}==
===A full implementation===
<syntaxhighlight lang="swift">
// Utility to aid easy type conversion
extension Double {
init(withNum v: any Numeric) {
switch v {
case let ii as any BinaryInteger: self.init(ii)
case let ff as any BinaryFloatingPoint: self.init(ff)
default: self.init()
}
}
}
extension Array where Element: Numeric & Comparable {
// Helper func for random element in range
func randomElement(within: Range<Int>) -> Element {
return self[.random(in: within)]
}
mutating func median() -> Double? {
switch self.count {
case 0: return nil
case 1: return Double(withNum: self[0])
case 2: return self.reduce(0, {sum,this in sum + Double(withNum: this)/2.0})
default: break
}
let pTarget: Int = self.count / 2 + 1
let resultSetLen: Int = self.count.isMultiple(of: 2) ? 2 : 1
func divideAndConquer(bottom: Int, top: Int, goal: Int) -> Int {
var (lower,upper) = (bottom,top)
while true {
let splitVal = self.randomElement(within: lower..<upper)
let partitionIndex = self.partition(subrange: lower..<upper, by: {$0 > splitVal})
switch partitionIndex {
case goal: return partitionIndex
case ..<goal: lower = partitionIndex
default: upper = partitionIndex
}
}
}
// Split just above the 'median point'
var pIndex = divideAndConquer(bottom: 0, top: self.count, goal: pTarget)
// Shove the highest 'low' values into the result slice
pIndex = divideAndConquer(bottom: 0, top: pIndex, goal: pIndex - resultSetLen)
// Average the contents of the result slice
return self[pIndex..<pIndex + resultSetLen]
.reduce(0.0, {sum,this in sum + Double(withNum: this)/Double(withNum: resultSetLen)})
}
}
</syntaxhighlight>
Usage:
<syntaxhighlight lang="swift">
var c: [Double] = (0...100).map {_ in Double.random(in: 0...100)}
print(c.median())
</syntaxhighlight>
=={{header|Tcl}}==
|