Skip to content

Instantly share code, notes, and snippets.

@artalar
Last active November 9, 2021 11:27
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 artalar/a21d2b771c6c65e1ba5564531ed16061 to your computer and use it in GitHub Desktop.
Save artalar/a21d2b771c6c65e1ba5564531ed16061 to your computer and use it in GitHub Desktop.
const getPrev = (n, list) => (n > 0 ? n - 1 : list.length - 1);
function shake(input) {
const result = input.slice(0);
let debug_CyclesCount = 0;
result.forEach((el, i) => {
const next = result[i + 1];
if (el !== next) return;
let iTarget = i;
while (true) {
iTarget = getPrev(iTarget, result);
if (iTarget === i) throw new Error("We're stuck here :)");
const iTargetBorder = getPrev(iTarget, result);
const target = result[iTarget];
if (
target !== el &&
result[iTargetBorder] !== el &&
result[iTarget + 1] !== el
) {
debug_CyclesCount++;
result[iTarget] = el;
result[i] = target;
break;
}
}
});
const count = input.length
const countSet = new Set(input).size
console.log(
{ input: input.toString(), result: result.toString() },
`For ~random elements distribution, where ${count} elements and ` +
`${countSet} unique elements, the number of reordering is: ` +
debug_CyclesCount
);
}
shake([1, 1, 2, 3, 4, 5, 5, 5, 5, 6, 7, 8, 7, 9, 10]);
shake([1, 1, 2, 3, 2, 5, 5, 5, 5, 2, 7, 8, 2, 9, 2]);
shake([1, 1, 2, 3, 2, 5, 5, 5]);
shake([1, 1, 2, 3, 2, 5, 5, 5].join('').repeat(3).split(''));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment