Skip to content

Instantly share code, notes, and snippets.

@mmertsock
Created March 11, 2021 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmertsock/1ddc55642e65dd8b897a552037ceeaf1 to your computer and use it in GitHub Desktop.
Save mmertsock/1ddc55642e65dd8b897a552037ceeaf1 to your computer and use it in GitHub Desktop.
xkcd’s Geothemic Meandian
// https://xkcd.com/2435/
// Usage: geothemic meandian = g(array, epsilon, [iterations = 3])
function g(a, epsilon, iterations) {
if (a.length < 1) { return NaN; }
iterations = (Number.isFinite(iterations) && iterations > 0) ? iterations : 3;
let geothmetic = Array.from(a);
while (range(geothmetic) > epsilon) {
geothmetic = f(geothmetic);
}
return geothmetic[0];
}
function f(a) {
return [amean(a), gmean(a), median(a)];
}
function range(a) {
if (a.length < 1) { return NaN; }
let min = Number.MAX_SAFE_INTEGER;
let max = Number.MIN_SAFE_INTEGER;
a.forEach(x => {
min = Math.min(min, x);
max = Math.max(max, x);
});
return max - min;
}
function amean(a) {
if (a.length < 1) { return NaN; }
let sum = 0;
a.forEach(x => { sum += x; });
return sum / a.length;
}
function gmean(a) {
if (a.length < 1) { return NaN; }
let prod = 1;
a.forEach(x => { prod = prod * x; });
return Math.pow(prod, 1 / a.length);
}
function median(a) {
if (a.length < 1) { return NaN; }
a.sort();
let pivot = Math.floor(a.length / 2);
if (a.length % 2 == 0) {
return (a[pivot - 1] + a[pivot]) / 2;
} else {
return a[pivot];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment