// HTML for this example: <pre id="output"></pre>
function compare(a/*: number*/, b/*: number*/)/*: ['compare', number, number]*/ {
return ['compare', a, b];
}
function swap(a/*: number*/, b/*: number*/)/*: ['swap', number, number]*/ {
return ['swap', a, b];
}
function* bubbleSort(from/*: number*/, to/*: number*/)/*: Generator<['swap' | 'compare', number, number], void, number> */ {
let swapped/*: boolean */;
do {
swapped = false;
to -= 1; // decrement by 1 EACH loop, as we know the last element will be in place
for (let j = from; j < to; j++) {
if ((yield compare(j, j + 1)) > 0) {
yield swap(j, j + 1);
swapped = true;
}
}
} while(swapped);
}
function log(text/*: string*/)/*: void */ {
console.log(text);
document.getElementById('output').innerText += text + '\n';
}
function test(array/*: number[] */)/*: void */ {
const generator = bubbleSort(0, array.length);
let latestArray = array;
let nextValue = 0;
while(true) {
const action = generator.next(nextValue);
if(action.done) {
log(JSON.stringify(latestArray) + ': Done')
return;
} else if (action.value[0] === 'compare') {
const a = latestArray[action.value[1]];
const b = latestArray[action.value[2]];
if(a > b) {
nextValue = 1;
} else if (a < b) {
nextValue = -1;
} else {
nextValue = 0;
}
log(JSON.stringify(latestArray) + `: Compared ${action.value[1]}: ${a} to ${action.value[2]}: ${b} resulting in ${nextValue}`);
} else if (action.value[0] === 'swap') {
latestArray = [...latestArray]
const tmp = latestArray[action.value[1]];
latestArray[action.value[1]] = latestArray[action.value[2]];
latestArray[action.value[2]] = tmp;
log(JSON.stringify(latestArray) + `: Swapped index ${action.value[1]} and ${action.value[2]}`);
} else {
throw new Error('What? ' + JSON.stringify(action.value));
}
}
}
const array = [9, 3, 4, 0, 7, 5, 2, 8, 1, 6];
test(array);