From d24b82d4606e6e2d5b6b209c2814fc9fd6ded5df Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Wed, 10 Jan 2024 13:44:34 +0000 Subject: [PATCH 1/2] refactor(data_structures): prepare for `noUncheckedIndexedAccess` --- data_structures/binary_heap.ts | 18 +- data_structures/binary_heap_test.ts | 14 +- data_structures/binary_search_tree.ts | 2 +- data_structures/binary_search_tree_test.ts | 252 ++++++++++----------- data_structures/red_black_tree_test.ts | 250 ++++++++++---------- 5 files changed, 268 insertions(+), 268 deletions(-) diff --git a/data_structures/binary_heap.ts b/data_structures/binary_heap.ts index 8b9a974e900e..4bdcbb9eeb8a 100644 --- a/data_structures/binary_heap.ts +++ b/data_structures/binary_heap.ts @@ -5,9 +5,9 @@ import { descend } from "./comparators.ts"; /** Swaps the values at two indexes in an array. */ function swap(array: T[], a: number, b: number) { - const temp: T = array[a]; - array[a] = array[b]; - array[b] = temp; + const temp = array[a]; + array[a] = array[b]!; + array[b] = temp!; } /** Returns the parent index for a child index. */ @@ -132,11 +132,11 @@ export class BinaryHeap implements Iterable { let right: number = 2 * (parent + 1); let left: number = right - 1; while (left < size) { - const greatestChild = - right === size || this.compare(this.#data[left], this.#data[right]) <= 0 - ? left - : right; - if (this.compare(this.#data[greatestChild], this.#data[parent]) < 0) { + const greatestChild = right === size || + this.compare(this.#data[left]!, this.#data[right]!) <= 0 + ? left + : right; + if (this.compare(this.#data[greatestChild]!, this.#data[parent]!) < 0) { swap(this.#data, parent, greatestChild); parent = greatestChild; } else { @@ -155,7 +155,7 @@ export class BinaryHeap implements Iterable { let parent: number = getParentIndex(index); this.#data.push(value); while ( - index !== 0 && this.compare(this.#data[index], this.#data[parent]) < 0 + index !== 0 && this.compare(this.#data[index]!, this.#data[parent]!) < 0 ) { swap(this.#data, parent, index); index = parent; diff --git a/data_structures/binary_heap_test.ts b/data_structures/binary_heap_test.ts index bacd19a289fb..af366b3960b0 100644 --- a/data_structures/binary_heap_test.ts +++ b/data_structures/binary_heap_test.ts @@ -13,8 +13,8 @@ Deno.test("BinaryHeap works with default descend comparator", () => { assertEquals(maxHeap.length, 0); assertEquals(maxHeap.isEmpty(), true); assertEquals(maxHeap.peek(), undefined); - for (let i = 0; i < values.length; i++) { - assertEquals(maxHeap.push(values[i]), i + 1); + for (const [i, value] of values.entries()) { + assertEquals(maxHeap.push(value), i + 1); } assertEquals(maxHeap.length, values.length); assertEquals(maxHeap.isEmpty(), false); @@ -50,8 +50,8 @@ Deno.test("BinaryHeap works with ascend comparator", () => { assertEquals(minHeap.length, 0); assertEquals(minHeap.isEmpty(), true); assertEquals(minHeap.peek(), undefined); - for (let i = 0; i < values.length; i++) { - assertEquals(minHeap.push(values[i]), i + 1); + for (const [i, value] of values.entries()) { + assertEquals(minHeap.push(value), i + 1); } assertEquals(minHeap.length, values.length); assertEquals(minHeap.isEmpty(), false); @@ -85,8 +85,8 @@ Deno.test("BinaryHeap contains objects", () => { ) => ascend(a.id, b.id)); const ids: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; - for (let i = 0; i < ids.length; i++) { - const newContainer: Container = { id: ids[i], values: [] }; + for (const [i, id] of ids.entries()) { + const newContainer: Container = { id, values: [] }; assertEquals(heap.push(newContainer), i + 1); newContainer.values.push(i - 1, i, i + 1); assertEquals(heap.length, i + 1); @@ -101,7 +101,7 @@ Deno.test("BinaryHeap contains objects", () => { const expectedContainer = { id: expected[i], - values: [expectedValue[i] - 1, expectedValue[i], expectedValue[i] + 1], + values: [expectedValue[i]! - 1, expectedValue[i], expectedValue[i]! + 1], }; assertEquals(heap.peek(), expectedContainer); assertEquals(heap.pop(), expectedContainer); diff --git a/data_structures/binary_search_tree.ts b/data_structures/binary_search_tree.ts index 0d4e9ba7008d..9fc588682b4a 100644 --- a/data_structures/binary_search_tree.ts +++ b/data_structures/binary_search_tree.ts @@ -378,7 +378,7 @@ export class BinarySearchTree implements Iterable { nodes.push(node); node = node.left; } else { - const lastNode: BinarySearchNode = nodes[nodes.length - 1]; + const lastNode: BinarySearchNode = nodes.at(-1)!; if (lastNode.right && lastNode.right !== lastNodeVisited) { node = lastNode.right; } else { diff --git a/data_structures/binary_search_tree_test.ts b/data_structures/binary_search_tree_test.ts index f1860737437b..502e41e4e414 100644 --- a/data_structures/binary_search_tree_test.ts +++ b/data_structures/binary_search_tree_test.ts @@ -20,10 +20,10 @@ interface Container { } Deno.test("BinarySearchTree handles default ascend comparator", () => { - const trees: BinarySearchTree[] = [ + const trees = [ new BinarySearchTree(), new BinarySearchTree(), - ]; + ] as const; const values: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; const expectedMin: number[][] = [ @@ -34,49 +34,49 @@ Deno.test("BinarySearchTree handles default ascend comparator", () => { [-10, 9, 9, 100, 100, 100, 100, 100, 100], [-9, 10, 10, 10, 10, 100, 100, 100, 100], ]; - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].find(values[j]), null); - assertEquals(trees[i].insert(values[j]), true); - assertEquals(trees[i].find(values[j]), values[j]); - assertEquals(trees[i].size, j + 1); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), expectedMin[i][j]); - assertEquals(trees[i].max(), expectedMax[i][j]); + for (const [i, tree] of trees.entries()) { + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); + for (const [j, value] of values.entries()) { + assertEquals(tree.find(value), null); + assertEquals(tree.insert(value), true); + assertEquals(tree.find(value), value); + assertEquals(tree.size, j + 1); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), expectedMin?.[i]?.[j]); + assertEquals(tree.max(), expectedMax?.[i]?.[j]); } - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].insert(values[j]), false); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), -100); - assertEquals(trees[i].max(), 100); + for (const value of values) { + assertEquals(tree.insert(value), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), -100); + assertEquals(tree.max(), 100); } values.reverse(); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { assertEquals( - [...trees[i].lnrValues()], + [...tree.lnrValues()], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i]], + [...tree], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i].rnlValues()], + [...tree.rnlValues()], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -87,9 +87,9 @@ Deno.test("BinarySearchTree handles default ascend comparator", () => { [...trees[1].nlrValues()], [-9, -100, -10, 10, 0, -1, 1, 9, 100], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -100,9 +100,9 @@ Deno.test("BinarySearchTree handles default ascend comparator", () => { [...trees[1].lrnValues()], [-10, -100, -1, 9, 1, 0, 100, 10, -9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -113,37 +113,37 @@ Deno.test("BinarySearchTree handles default ascend comparator", () => { [...trees[1].lvlValues()], [-9, -100, 10, -10, 0, 100, -1, 1, 9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { const expected: number[] = [-100, -10, -9, -1, 0, 1, 9, 10, 100]; - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].size, values.length - j); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].find(values[j]), values[j]); - - assertEquals(trees[i].remove(values[j]), true); - expected.splice(expected.indexOf(values[j]), 1); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); - - assertEquals(trees[i].remove(values[j]), false); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); + for (const [j, value] of values.entries()) { + assertEquals(tree.size, values.length - j); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.find(value), value); + + assertEquals(tree.remove(value), true); + expected.splice(expected.indexOf(value), 1); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); + + assertEquals(tree.remove(value), false); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); } - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); } }); Deno.test("BinarySearchTree handles descend comparator", () => { - const trees: BinarySearchTree[] = [ + const trees = [ new BinarySearchTree(descend), new BinarySearchTree(descend), - ]; + ] as const; const values: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; const expectedMin: number[][] = [ @@ -154,49 +154,49 @@ Deno.test("BinarySearchTree handles descend comparator", () => { [-10, -10, -10, -10, -10, -10, -100, -100, -100], [-9, -9, -100, -100, -100, -100, -100, -100, -100], ]; - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].find(values[j]), null); - assertEquals(trees[i].insert(values[j]), true); - assertEquals(trees[i].find(values[j]), values[j]); - assertEquals(trees[i].size, j + 1); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), expectedMin[i][j]); - assertEquals(trees[i].max(), expectedMax[i][j]); + for (const [i, tree] of trees.entries()) { + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); + for (const [j, value] of values.entries()) { + assertEquals(tree.find(value), null); + assertEquals(tree.insert(value), true); + assertEquals(tree.find(value), value); + assertEquals(tree.size, j + 1); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), expectedMin?.[i]?.[j]); + assertEquals(tree.max(), expectedMax?.[i]?.[j]); } - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].insert(values[j]), false); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), 100); - assertEquals(trees[i].max(), -100); + for (const value of values) { + assertEquals(tree.insert(value), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), 100); + assertEquals(tree.max(), -100); } values.reverse(); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { assertEquals( - [...trees[i].lnrValues()], + [...tree.lnrValues()], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i]], + [...tree], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i].rnlValues()], + [...tree.rnlValues()], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -207,9 +207,9 @@ Deno.test("BinarySearchTree handles descend comparator", () => { [...trees[1].nlrValues()], [-9, 10, 100, 0, 1, 9, -1, -100, -10], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -220,9 +220,9 @@ Deno.test("BinarySearchTree handles descend comparator", () => { [...trees[1].lrnValues()], [100, 9, 1, -1, 0, 10, -10, -100, -9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -233,29 +233,29 @@ Deno.test("BinarySearchTree handles descend comparator", () => { [...trees[1].lvlValues()], [-9, 10, -100, 100, 0, -10, 1, -1, 9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { const expected: number[] = [100, 10, 9, 1, 0, -1, -9, -10, -100]; - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].size, values.length - j); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].find(values[j]), values[j]); - - assertEquals(trees[i].remove(values[j]), true); - expected.splice(expected.indexOf(values[j]), 1); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); - - assertEquals(trees[i].remove(values[j]), false); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); + for (const [j, value] of values.entries()) { + assertEquals(tree.size, values.length - j); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.find(value), value); + + assertEquals(tree.remove(value), true); + expected.splice(expected.indexOf(value), 1); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); + + assertEquals(tree.remove(value), false); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); } - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); } }); @@ -264,27 +264,27 @@ Deno.test("BinarySearchTree contains objects", () => { a: Container, b: Container, ) => ascend(a.id, b.id)); - const ids: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; + const ids = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; - for (let i = 0; i < ids.length; i++) { - const newContainer: Container = { id: ids[i], values: [] }; + for (const [i, id] of ids.entries()) { + const newContainer: Container = { id, values: [] }; assertEquals(tree.find(newContainer), null); assertEquals(tree.insert(newContainer), true); newContainer.values.push(i - 1, i, i + 1); - assertStrictEquals(tree.find({ id: ids[i], values: [] }), newContainer); + assertStrictEquals(tree.find({ id, values: [] }), newContainer); assertEquals(tree.size, i + 1); assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < ids.length; i++) { - const newContainer: Container = { id: ids[i], values: [] }; + for (const [i, id] of ids.entries()) { + const newContainer: Container = { id, values: [] }; assertEquals( - tree.find({ id: ids[i] } as Container), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id } as Container), + { id, values: [i - 1, i, i + 1] }, ); assertEquals(tree.insert(newContainer), false); assertEquals( - tree.find({ id: ids[i], values: [] }), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id, values: [] }), + { id, values: [i - 1, i, i + 1] }, ); assertEquals(tree.size, ids.length); assertEquals(tree.isEmpty(), false); @@ -298,22 +298,22 @@ Deno.test("BinarySearchTree contains objects", () => { assertEquals(tree.isEmpty(), false); const expected: number[] = [-100, -10, -9, -1, 0, 1, 9, 10, 100]; - for (let i = 0; i < ids.length; i++) { + for (const [i, id] of ids.entries()) { assertEquals(tree.size, ids.length - i); assertEquals(tree.isEmpty(), false); assertEquals( - tree.find({ id: ids[i], values: [] }), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id, values: [] }), + { id, values: [i - 1, i, i + 1] }, ); - assertEquals(tree.remove({ id: ids[i], values: [] }), true); - expected.splice(expected.indexOf(ids[i]), 1); + assertEquals(tree.remove({ id, values: [] }), true); + expected.splice(expected.indexOf(id), 1); assertEquals([...tree].map((container) => container.id), expected); - assertEquals(tree.find({ id: ids[i], values: [] }), null); + assertEquals(tree.find({ id, values: [] }), null); - assertEquals(tree.remove({ id: ids[i], values: [] }), false); + assertEquals(tree.remove({ id, values: [] }), false); assertEquals([...tree].map((container) => container.id), expected); - assertEquals(tree.find({ id: ids[i], values: [] }), null); + assertEquals(tree.find({ id, values: [] }), null); } assertEquals(tree.size, 0); assertEquals(tree.isEmpty(), true); diff --git a/data_structures/red_black_tree_test.ts b/data_structures/red_black_tree_test.ts index aad0ca939ba7..9441525046d5 100644 --- a/data_structures/red_black_tree_test.ts +++ b/data_structures/red_black_tree_test.ts @@ -5,10 +5,10 @@ import { ascend, descend } from "./comparators.ts"; import { Container, MyMath } from "./_test_utils.ts"; Deno.test("RedBlackTree works as expected with default ascend comparator", () => { - const trees: RedBlackTree[] = [ + const trees = [ new RedBlackTree(), new RedBlackTree(), - ]; + ] as const; const values: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; const expectedMin: number[][] = [ @@ -19,49 +19,49 @@ Deno.test("RedBlackTree works as expected with default ascend comparator", () => [-10, 9, 9, 100, 100, 100, 100, 100, 100], [-9, 10, 10, 10, 10, 100, 100, 100, 100], ]; - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].find(values[j]), null); - assertEquals(trees[i].insert(values[j]), true); - assertEquals(trees[i].find(values[j]), values[j]); - assertEquals(trees[i].size, j + 1); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), expectedMin[i][j]); - assertEquals(trees[i].max(), expectedMax[i][j]); + for (const [i, tree] of trees.entries()) { + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); + for (const [j, value] of values.entries()) { + assertEquals(tree.find(value), null); + assertEquals(tree.insert(value), true); + assertEquals(tree.find(value), value); + assertEquals(tree.size, j + 1); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), expectedMin?.[i]?.[j]); + assertEquals(tree.max(), expectedMax?.[i]?.[j]); } - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].insert(values[j]), false); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), -100); - assertEquals(trees[i].max(), 100); + for (const value of values) { + assertEquals(tree.insert(value), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), -100); + assertEquals(tree.max(), 100); } values.reverse(); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { assertEquals( - [...trees[i].lnrValues()], + [...tree.lnrValues()], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i]], + [...tree], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i].rnlValues()], + [...tree.rnlValues()], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -72,9 +72,9 @@ Deno.test("RedBlackTree works as expected with default ascend comparator", () => [...trees[1].nlrValues()], [-9, -100, -10, 1, 0, -1, 10, 9, 100], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -85,9 +85,9 @@ Deno.test("RedBlackTree works as expected with default ascend comparator", () => [...trees[1].lrnValues()], [-10, -100, -1, 0, 9, 100, 10, 1, -9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -98,37 +98,37 @@ Deno.test("RedBlackTree works as expected with default ascend comparator", () => [...trees[1].lvlValues()], [-9, -100, 1, -10, 0, 10, -1, 9, 100], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { const expected: number[] = [-100, -10, -9, -1, 0, 1, 9, 10, 100]; - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].size, values.length - j); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].find(values[j]), values[j]); - - assertEquals(trees[i].remove(values[j]), true); - expected.splice(expected.indexOf(values[j]), 1); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); - - assertEquals(trees[i].remove(values[j]), false); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); + for (const [j, value] of values.entries()) { + assertEquals(tree.size, values.length - j); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.find(value), value); + + assertEquals(tree.remove(value), true); + expected.splice(expected.indexOf(value), 1); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); + + assertEquals(tree.remove(value), false); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); } - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); } }); Deno.test("RedBlackTree works as exepcted with descend comparator", () => { - const trees: RedBlackTree[] = [ + const trees = [ new RedBlackTree(descend), new RedBlackTree(descend), - ]; + ] as const; const values: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; const expectedMin: number[][] = [ @@ -139,49 +139,49 @@ Deno.test("RedBlackTree works as exepcted with descend comparator", () => { [-10, -10, -10, -10, -10, -10, -100, -100, -100], [-9, -9, -100, -100, -100, -100, -100, -100, -100], ]; - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].find(values[j]), null); - assertEquals(trees[i].insert(values[j]), true); - assertEquals(trees[i].find(values[j]), values[j]); - assertEquals(trees[i].size, j + 1); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), expectedMin[i][j]); - assertEquals(trees[i].max(), expectedMax[i][j]); + for (const [i, tree] of trees.entries()) { + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); + for (const [j, value] of values.entries()) { + assertEquals(tree.find(value), null); + assertEquals(tree.insert(value), true); + assertEquals(tree.find(value), value); + assertEquals(tree.size, j + 1); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), expectedMin?.[i]?.[j]); + assertEquals(tree.max(), expectedMax?.[i]?.[j]); } - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].insert(values[j]), false); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].min(), 100); - assertEquals(trees[i].max(), -100); + for (const value of values) { + assertEquals(tree.insert(value), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.min(), 100); + assertEquals(tree.max(), -100); } values.reverse(); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { assertEquals( - [...trees[i].lnrValues()], + [...tree.lnrValues()], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i]], + [...tree], [100, 10, 9, 1, 0, -1, -9, -10, -100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); assertEquals( - [...trees[i].rnlValues()], + [...tree.rnlValues()], [-100, -10, -9, -1, 0, 1, 9, 10, 100], ); - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -192,9 +192,9 @@ Deno.test("RedBlackTree works as exepcted with descend comparator", () => { [...trees[1].nlrValues()], [-9, 1, 10, 100, 9, 0, -1, -100, -10], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -205,9 +205,9 @@ Deno.test("RedBlackTree works as exepcted with descend comparator", () => { [...trees[1].lrnValues()], [100, 9, 10, -1, 0, 1, -10, -100, -9], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } assertEquals( @@ -218,29 +218,29 @@ Deno.test("RedBlackTree works as exepcted with descend comparator", () => { [...trees[1].lvlValues()], [-9, 1, -100, 10, 0, -10, 100, 9, -1], ); - for (let i = 0; i < 2; i++) { - assertEquals(trees[i].size, values.length); - assertEquals(trees[i].isEmpty(), false); + for (const tree of trees) { + assertEquals(tree.size, values.length); + assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < 2; i++) { + for (const tree of trees) { const expected: number[] = [100, 10, 9, 1, 0, -1, -9, -10, -100]; - for (let j = 0; j < values.length; j++) { - assertEquals(trees[i].size, values.length - j); - assertEquals(trees[i].isEmpty(), false); - assertEquals(trees[i].find(values[j]), values[j]); - - assertEquals(trees[i].remove(values[j]), true); - expected.splice(expected.indexOf(values[j]), 1); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); - - assertEquals(trees[i].remove(values[j]), false); - assertEquals([...trees[i]], expected); - assertEquals(trees[i].find(values[j]), null); + for (const [j, value] of values.entries()) { + assertEquals(tree.size, values.length - j); + assertEquals(tree.isEmpty(), false); + assertEquals(tree.find(value), value); + + assertEquals(tree.remove(value), true); + expected.splice(expected.indexOf(value), 1); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); + + assertEquals(tree.remove(value), false); + assertEquals([...tree], expected); + assertEquals(tree.find(value), null); } - assertEquals(trees[i].size, 0); - assertEquals(trees[i].isEmpty(), true); + assertEquals(tree.size, 0); + assertEquals(tree.isEmpty(), true); } }); @@ -251,25 +251,25 @@ Deno.test("RedBlackTree works with object items", () => { ) => ascend(a.id, b.id)); const ids: number[] = [-10, 9, -1, 100, 1, 0, -100, 10, -9]; - for (let i = 0; i < ids.length; i++) { - const newContainer: Container = { id: ids[i], values: [] }; + for (const [i, id] of ids.entries()) { + const newContainer: Container = { id, values: [] }; assertEquals(tree.find(newContainer), null); assertEquals(tree.insert(newContainer), true); newContainer.values.push(i - 1, i, i + 1); - assertStrictEquals(tree.find({ id: ids[i], values: [] }), newContainer); + assertStrictEquals(tree.find({ id, values: [] }), newContainer); assertEquals(tree.size, i + 1); assertEquals(tree.isEmpty(), false); } - for (let i = 0; i < ids.length; i++) { - const newContainer: Container = { id: ids[i], values: [] }; + for (const [i, id] of ids.entries()) { + const newContainer: Container = { id, values: [] }; assertEquals( - tree.find({ id: ids[i] } as Container), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id } as Container), + { id, values: [i - 1, i, i + 1] }, ); assertEquals(tree.insert(newContainer), false); assertEquals( - tree.find({ id: ids[i], values: [] }), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id, values: [] }), + { id, values: [i - 1, i, i + 1] }, ); assertEquals(tree.size, ids.length); assertEquals(tree.isEmpty(), false); @@ -283,22 +283,22 @@ Deno.test("RedBlackTree works with object items", () => { assertEquals(tree.isEmpty(), false); const expected: number[] = [-100, -10, -9, -1, 0, 1, 9, 10, 100]; - for (let i = 0; i < ids.length; i++) { + for (const [i, id] of ids.entries()) { assertEquals(tree.size, ids.length - i); assertEquals(tree.isEmpty(), false); assertEquals( - tree.find({ id: ids[i], values: [] }), - { id: ids[i], values: [i - 1, i, i + 1] }, + tree.find({ id, values: [] }), + { id, values: [i - 1, i, i + 1] }, ); - assertEquals(tree.remove({ id: ids[i], values: [] }), true); - expected.splice(expected.indexOf(ids[i]), 1); + assertEquals(tree.remove({ id, values: [] }), true); + expected.splice(expected.indexOf(id), 1); assertEquals([...tree].map((container) => container.id), expected); - assertEquals(tree.find({ id: ids[i], values: [] }), null); + assertEquals(tree.find({ id, values: [] }), null); - assertEquals(tree.remove({ id: ids[i], values: [] }), false); + assertEquals(tree.remove({ id, values: [] }), false); assertEquals([...tree].map((container) => container.id), expected); - assertEquals(tree.find({ id: ids[i], values: [] }), null); + assertEquals(tree.find({ id, values: [] }), null); } assertEquals(tree.size, 0); assertEquals(tree.isEmpty(), true); From 8d7761ecc0f599fd891becd07332981ab5b0f6d6 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Thu, 11 Jan 2024 07:16:31 +1100 Subject: [PATCH 2/2] tweak --- data_structures/binary_heap_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_structures/binary_heap_test.ts b/data_structures/binary_heap_test.ts index af366b3960b0..8321e66d160c 100644 --- a/data_structures/binary_heap_test.ts +++ b/data_structures/binary_heap_test.ts @@ -95,13 +95,13 @@ Deno.test("BinaryHeap contains objects", () => { const expected: number[] = [-100, -10, -9, -1, 0, 1, 9, 10, 100]; const expectedValue: number[] = [6, 0, 8, 2, 5, 4, 1, 7, 3]; - for (let i = 0; i < ids.length; i++) { + for (const [i, value] of expectedValue.entries()) { assertEquals(heap.length, ids.length - i); assertEquals(heap.isEmpty(), false); const expectedContainer = { id: expected[i], - values: [expectedValue[i]! - 1, expectedValue[i], expectedValue[i]! + 1], + values: [value - 1, value, value + 1], }; assertEquals(heap.peek(), expectedContainer); assertEquals(heap.pop(), expectedContainer);