Skip to content

Commit 5e2da1e

Browse files
authored
Add TypeScript goody for pre-order traversal of an N-ary tree (#518)
Closes #396.
1 parent 95f574e commit 5e2da1e

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { describe, expect, it } from "@jest/globals";
2+
3+
import { traversePreOrderNAry } from "./index.ts";
4+
5+
type Node = { val: number; children: Node[] };
6+
7+
describe("traversePreOrderNAry", () => {
8+
it("yields nothing for null/undefined root", () => {
9+
expect([...traversePreOrderNAry(null)]).toStrictEqual([]);
10+
expect([...traversePreOrderNAry(undefined)]).toStrictEqual([]);
11+
});
12+
13+
it("yields root only for single node", () => {
14+
const root: Node = { val: 1, children: [] };
15+
expect([...traversePreOrderNAry(root)].map((n) => n.val)).toStrictEqual([
16+
1,
17+
]);
18+
});
19+
20+
it("visits parent before children", () => {
21+
const root: Node = {
22+
val: 1,
23+
children: [
24+
{
25+
val: 2,
26+
children: [
27+
{ val: 5, children: [] },
28+
{ val: 6, children: [] },
29+
],
30+
},
31+
{ val: 3, children: [] },
32+
{
33+
val: 4,
34+
children: [{ val: 7, children: [] }],
35+
},
36+
],
37+
};
38+
expect([...traversePreOrderNAry(root)].map((n) => n.val)).toStrictEqual([
39+
1, 2, 5, 6, 3, 4, 7,
40+
]);
41+
});
42+
43+
it("traverses deeper trees in pre-order", () => {
44+
const root: Node = {
45+
val: 1,
46+
children: [
47+
{
48+
val: 2,
49+
children: [
50+
{ val: 4, children: [] },
51+
{ val: 5, children: [] },
52+
],
53+
},
54+
{ val: 3, children: [] },
55+
],
56+
};
57+
expect([...traversePreOrderNAry(root)].map((n) => n.val)).toStrictEqual([
58+
1, 2, 4, 5, 3,
59+
]);
60+
});
61+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export function* traversePreOrderNAry<T extends { children: T[] }>(
2+
root: T | null | undefined,
3+
): Generator<T, void, void> {
4+
if (root == null) {
5+
return;
6+
}
7+
8+
const stack: T[] = [root];
9+
10+
do {
11+
const node = stack.pop()!;
12+
yield node;
13+
// TODO: add an Array.prototype.valuesReversed() goody and use it here
14+
for (let i = node.children.length - 1; i >= 0; --i) {
15+
stack.push(node.children[i]);
16+
}
17+
} while (stack.length > 0);
18+
}

workspaces/adventure-pack/src/app/__tests__/__snapshots__/equip-test.ts.snap

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,6 +2724,31 @@ function* traversePreOrder(root) {
27242724
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
27252725
`;
27262726

2727+
exports[`App can equip single goody: JavaScript traversePreOrderNAry 1`] = `
2728+
"////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
2729+
// Adventure Pack commit fake-commit-hash
2730+
// Running at: https://example.com/
2731+
2732+
function* traversePreOrderNAry(root) {
2733+
if (root == null) {
2734+
return;
2735+
}
2736+
2737+
const stack = [root];
2738+
2739+
do {
2740+
const node = stack.pop();
2741+
yield node;
2742+
// TODO: add an Array.prototype.valuesReversed() goody and use it here
2743+
for (let i = node.children.length - 1; i >= 0; --i) {
2744+
stack.push(node.children[i]);
2745+
}
2746+
} while (stack.length > 0);
2747+
}
2748+
2749+
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
2750+
`;
2751+
27272752
exports[`App can equip single goody: Kotlin gcd(Int,Int) 1`] = `
27282753
"////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
27292754
// Adventure Pack commit fake-commit-hash
@@ -5509,3 +5534,30 @@ function* traversePreOrder<
55095534

55105535
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
55115536
`;
5537+
5538+
exports[`App can equip single goody: TypeScript traversePreOrderNAry 1`] = `
5539+
"////////////////////////// BEGIN ADVENTURE PACK CODE ///////////////////////////
5540+
// Adventure Pack commit fake-commit-hash
5541+
// Running at: https://example.com/
5542+
5543+
function* traversePreOrderNAry<T extends { children: T[] }>(
5544+
root: T | null | undefined,
5545+
): Generator<T, void, void> {
5546+
if (root == null) {
5547+
return;
5548+
}
5549+
5550+
const stack: T[] = [root];
5551+
5552+
do {
5553+
const node = stack.pop()!;
5554+
yield node;
5555+
// TODO: add an Array.prototype.valuesReversed() goody and use it here
5556+
for (let i = node.children.length - 1; i >= 0; --i) {
5557+
stack.push(node.children[i]);
5558+
}
5559+
} while (stack.length > 0);
5560+
}
5561+
5562+
/////////////////////////// END ADVENTURE PACK CODE ////////////////////////////"
5563+
`;

workspaces/adventure-pack/src/app/__tests__/__snapshots__/render-test.ts.snap

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,6 +1499,25 @@ exports[`App can render goody: JavaScript traversePreOrder 1`] = `
14991499
}"
15001500
`;
15011501
1502+
exports[`App can render goody: JavaScript traversePreOrderNAry 1`] = `
1503+
"export function* traversePreOrderNAry(root) {
1504+
if (root == null) {
1505+
return;
1506+
}
1507+
1508+
const stack = [root];
1509+
1510+
do {
1511+
const node = stack.pop();
1512+
yield node;
1513+
// TODO: add an Array.prototype.valuesReversed() goody and use it here
1514+
for (let i = node.children.length - 1; i >= 0; --i) {
1515+
stack.push(node.children[i]);
1516+
}
1517+
} while (stack.length > 0);
1518+
}"
1519+
`;
1520+
15021521
exports[`App can render goody: Kotlin gcd(Int,Int) 1`] = `
15031522
"package gcd_int_int
15041523
@@ -3159,3 +3178,24 @@ exports[`App can render goody: TypeScript traversePreOrder 1`] = `
31593178
} while (stack.length > 0);
31603179
}"
31613180
`;
3181+
3182+
exports[`App can render goody: TypeScript traversePreOrderNAry 1`] = `
3183+
"export function* traversePreOrderNAry<T extends { children: T[] }>(
3184+
root: T | null | undefined,
3185+
): Generator<T, void, void> {
3186+
if (root == null) {
3187+
return;
3188+
}
3189+
3190+
const stack: T[] = [root];
3191+
3192+
do {
3193+
const node = stack.pop()!;
3194+
yield node;
3195+
// TODO: add an Array.prototype.valuesReversed() goody and use it here
3196+
for (let i = node.children.length - 1; i >= 0; --i) {
3197+
stack.push(node.children[i]);
3198+
}
3199+
} while (stack.length > 0);
3200+
}"
3201+
`;

0 commit comments

Comments
 (0)