Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2b9ec07
chore: add lint script to datatypes package
schoettler Jul 23, 2025
f6212ca
build: add vite build configuration for datatypes library
schoettler Jul 23, 2025
86a22f7
refactor: add type annotation to fileName function in vite config
schoettler Jul 23, 2025
e61e716
refactor: update vite config to resolve module imports without extens…
schoettler Jul 23, 2025
5ad23be
feat: add root alias to resolve imports without file extensions
schoettler Jul 23, 2025
78e3b92
chore: update package.json with module type and script name
schoettler Jul 23, 2025
a974d46
feat: add typecheck script to datatypes package
schoettler Jul 23, 2025
26744db
refactor: update import paths to use module aliases
schoettler Jul 23, 2025
517cc15
refactor: remove root alias configuration from vite and tsconfig
schoettler Jul 23, 2025
b469404
chore: configure tsconfig to include all .ts files except spec files
schoettler Jul 23, 2025
745aa4d
feat: adding dataypes:build
schoettler Jul 23, 2025
ebf49a0
chore: update scripts for algorithms package
schoettler Jul 23, 2025
304e981
feat: add Vite build configuration for algorithms library
schoettler Jul 23, 2025
1bbdd56
feat: add algorithms build script to package.json
schoettler Jul 23, 2025
b4e3a9e
refactor: improve Vite config type handling and formatting
schoettler Jul 23, 2025
4f4d713
fix: resolve Vite library build configuration for multiple inputs
schoettler Jul 23, 2025
a2aea26
feat: adding CI workflow
schoettler Jul 23, 2025
e2d418d
running via nx docs instead of custom github action
schoettler Jul 23, 2025
e0bc050
plugging out of nx:cloud
schoettler Jul 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,31 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
## 1. checkout & install
- uses: actions/checkout@v4
with:
filter: tree:0
fetch-depth: 0

# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Uncomment this line to enable task distribution
# - run: npx nx start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="build"

# Cache node_modules
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'

- run: npm ci --legacy-peer-deps

# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: npx nx-cloud record -- echo Hello World
# As your workspace grows, you can change this to use Nx Affected to run only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
- run: npx nx run-many -t lint test build
# Nx Cloud recommends fixes for failures to help you get CI green faster. Learn more: https://nx.dev/ci/features/self-healing-ci
- run: npx nx fix-ci
if: always()
node-version: 22
- name: Install deps
run: |
corepack enable
pnpm install --frozen-lockfile

## 2. cache Nx computation results
- uses: actions/cache@v4
with:
path: .nx/cache
key: nx-${{ github.sha }}

## 3. run tests (all projects)
- name: Nx tests
run: pnpm nx run-many --target=test --all

## 4. build (all projects)
- name: Nx build
run: pnpm nx run-many --target=build --all

## 5. generate PlantUML docs (SVG)
- name: Render PlantUML
run: pnpm nx run-many --target=docs --all
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ Thumbs.db
.nx/workspace-data
.cursor/rules/nx-rules.mdc
.github/instructions/nx.instructions.md

vite.config.*.timestamp*
vitest.config.*.timestamp*
3 changes: 2 additions & 1 deletion apps/cache-strategies/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"main": "index.js",
"private": true,
"scripts": {
"cache-strategies:test": "bun test *.spec.ts"
"cache-strategies:test": "bun test **/*.spec.ts",
"cache-strategies:lint": "prettier **/*.ts --write"
},
"author": "Roberto von Schoettler <rschoettler@proveo.ca>",
"license": "UNLICENSED",
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DoublyLinkedList } from '@proveo/cs-datatypes'
import { deleteNode } from '@proveo/cs-algorithms'
import { deleteNode } from 'libs/algorithms'
// Least Recent Use
// 1. Whenever a record is accessed, it's placed at the top of the cache.
// 2. Records at the bottom will be removed once the limit is reached.
Expand Down
File renamed without changes.
10 changes: 9 additions & 1 deletion apps/cache-strategies/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"extends": "../../tsconfig.json"
"extends": "../../tsconfig.json",
"references": [
{
"path": "../../libs/datatypes"
},
{
"path": "../../libs/algorithms"
}
]
}
12 changes: 12 additions & 0 deletions apps/discovery-strategies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Discovery Strategies

| Theme | Canonical algorithms | Typical questions they answer | Real‑world systems & examples |
| ------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **Connectivity & reachability** | DFS/BFS, Union‑Find, Tarjan’s SCC | “Are *A* and *B* connected?”<br>“How many components / islands exist?” | Link‑state routing (OSPF), social‑graph friend suggestions, detecting cycles in build dependency graphs. |
| **Shortest & cheapest paths** | Dijkstra, A\*, Bellman‑Ford, Floyd‑Warshall, bidirectional search | “What is the minimum‑cost route from X to Y?” | Google Maps, GPS nav, network QoS routing, robot path planning in warehouses. |
| **Spanning structures & clustering** | Kruskal / Prim MST, Borůvka, DSU‑based clustering | “Connect all nodes with the smallest total cost.” | Electrical grid layout, fiber/cable network design, image segmentation via minimal spanning forests. |
| **Scheduling & dependency ordering** | Topological sort (Kahn / DFS), Critical‑Path Method, DAG DP | “In which order can we compile packages?”<br>“What’s the longest path in a DAG (project duration)?” | `make`/Bazel build systems, course‑prerequisite planning, CI/CD job ordering, project management tools. |
| **Network flow & matching** | Ford‑Fulkerson, Edmonds‑Karp, Dinic, Hopcroft–Karp, Kuhn‑Munkres | “Max throughput between source & sink.”<br>“Assign tasks to workers optimally.” | Airline scheduling, bipartite job matching, sports tournament brackets, cloud resource allocation, image stitching (max‑flow min‑cut). |
| **Indexing & spatial search** | Binary‑Search Trees (AVL, Red‑Black), Segment / Fenwick / Interval trees, K‑d trees, R‑trees | “Store & query ordered or geometric data in log n or faster.” | Database indexes (B‑tree variants), text editors’ rope structures, collision detection in games, GIS range queries. |
| **Heuristics, AI & game search** | Min‑Max with α‑β pruning, Monte‑Carlo Tree Search | “Choose the best move given branching factor.” | Chess/Go engines, real‑time strategy AI, automated theorem proving. |
| **Graph analytics** | PageRank, HITS, Betweenness Centrality, community detection (Louvain, Girvan‑Newman) | “Which nodes are most influential?”<br>“How is the network clustered?” | Web‑search ranking, social‑network influence scores, fraud‑ring detection, recommendation engines. |
13 changes: 0 additions & 13 deletions libs/algorithms/PRIMER.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,3 @@ Probing Techniques:
* **Linear Probing:** Search sequentially for the next available slot. `index = (hash + i) % table_size`
* **Quadratic Probing:** Use quadratic intervals to find the next slot. `index = (hash + i^2) % table_size`
* **Double Hashing:** Use a second hash function to find the next slot. `index = (hash1 + i * hash2) % table_size`

#### What tree / graph algorithms shine at (the greatest hits)

| Theme | Canonical algorithms | Typical questions they answer | Real‑world systems & examples |
| ------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **Connectivity & reachability** | DFS/BFS, Union‑Find, Tarjan’s SCC | “Are *A* and *B* connected?”<br>“How many components / islands exist?” | Link‑state routing (OSPF), social‑graph friend suggestions, detecting cycles in build dependency graphs. |
| **Shortest & cheapest paths** | Dijkstra, A\*, Bellman‑Ford, Floyd‑Warshall, bidirectional search | “What is the minimum‑cost route from X to Y?” | Google Maps, GPS nav, network QoS routing, robot path planning in warehouses. |
| **Spanning structures & clustering** | Kruskal / Prim MST, Borůvka, DSU‑based clustering | “Connect all nodes with the smallest total cost.” | Electrical grid layout, fiber/cable network design, image segmentation via minimal spanning forests. |
| **Scheduling & dependency ordering** | Topological sort (Kahn / DFS), Critical‑Path Method, DAG DP | “In which order can we compile packages?”<br>“What’s the longest path in a DAG (project duration)?” | `make`/Bazel build systems, course‑prerequisite planning, CI/CD job ordering, project management tools. |
| **Network flow & matching** | Ford‑Fulkerson, Edmonds‑Karp, Dinic, Hopcroft–Karp, Kuhn‑Munkres | “Max throughput between source & sink.”<br>“Assign tasks to workers optimally.” | Airline scheduling, bipartite job matching, sports tournament brackets, cloud resource allocation, image stitching (max‑flow min‑cut). |
| **Indexing & spatial search** | Binary‑Search Trees (AVL, Red‑Black), Segment / Fenwick / Interval trees, K‑d trees, R‑trees | “Store & query ordered or geometric data in log n or faster.” | Database indexes (B‑tree variants), text editors’ rope structures, collision detection in games, GIS range queries. |
| **Heuristics, AI & game search** | Min‑Max with α‑β pruning, Monte‑Carlo Tree Search | “Choose the best move given branching factor.” | Chess/Go engines, real‑time strategy AI, automated theorem proving. |
| **Graph analytics** | PageRank, HITS, Betweenness Centrality, community detection (Louvain, Girvan‑Newman) | “Which nodes are most influential?”<br>“How is the network clustered?” | Web‑search ranking, social‑network influence scores, fraud‑ring detection, recommendation engines. |
2 changes: 1 addition & 1 deletion libs/algorithms/_docs/ARRAY_BASED_ALGORITHMS.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion libs/algorithms/_docs/PRIMITIVES_BASED_ALGORITHMS.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion libs/algorithms/_docs/TREE_GRAPH_BASED_ALGORITHMS.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion libs/algorithms/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { deleteNode } from './array-processing/203-remove-linked-list-elements/203-remove-linked-list-elements'
export * from './src/index.js'
10 changes: 9 additions & 1 deletion libs/algorithms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@
"description": "",
"main": "index.js",
"private": true,
"type": "module",
"scripts": {
"algorithms:test": "bun test **/*.spec.ts"
"algorithms:typecheck": "tsc --noEmit",
"algorithms:test": "bun test **/*.spec.ts",
"algorithms:lint": "npm run algorithms:typecheck && prettier **/*.ts --write",
"algorithms:build": "nx build"
},
"keywords": [],
"author": "",
"license": "UNLICENSED",
"dependencies": {
"@proveo/cs-datatypes": "workspace:*"
},
"devDependencies": {
"glob": "^11.0.3",
"vite": "^5.0.0"
}
}
21 changes: 21 additions & 0 deletions libs/algorithms/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "@proveo/cs-algorithms",
"projectType": "library",
"root": "libs/algorithms",
"sourceRoot": "libs/algorithms/src",
"namedInputs": {
"default": ["{projectRoot}/**/*"],
"puml": ["{projectRoot}/_docs/**/*.puml"]
},
"targets": {
"docs": {
"executor": "nx:run-commands",
"inputs": ["puml"],
"options": {
"command": "docker run --rm -v $(pwd)/libs/algorithms/_docs:/workspace ghcr.io/plantuml/plantuml -tsvg /workspace/*.puml",
"parallel": false
},
"outputs": ["{projectRoot}/_docs"]
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LinkedListNode } from 'libs/data-types/doubly-linked-list-node'
import { LinkedList } from 'data-types/linked-list'
import { LinkedListNode } from '@proveo/cs-datatypes'
import { LinkedList } from '@proveo/cs-datatypes'

function reverseHead (head) {
function reverseHead (head: LinkedListNode<any>) {
if (!head || !head.next) {
return head
}
Expand All @@ -14,13 +14,13 @@ function reverseHead (head) {
reversedHead.next = tail

tail = reversedHead
currentNode = currentNode.next
currentNode = currentNode.next!
}

return reversedHead
}

const reverse = function (head) {
const reverse = function (head: LinkedListNode<any>) {
const originalList = new LinkedList()
originalList.head = head

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, expect } from "bun:test";
import { productExceptSelf } from "./238-product-or-array-except-self.js";
import { productExceptSelf } from "./238-product-or-array-except-self";

describe("238. Product of Array Except Self", () => {
test("Example from the problem statement", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { describe, expect, it } from 'bun:test'
import { BinaryTree } from 'data-types/index.js'
import { breadthSearchIterator } from './102-binary-tree-level-order-traversal'
import { BinaryTree } from '@proveo/cs-datatypes'
import { breadthSearchIterator } from './102-binary-tree-level-order-traversal.js'

describe('Breadth Search Iterator (Level-order Traversal) tests', () => {
it('should handle a null tree', () => {
const tree = new BinaryTree(null)
it('should handle an undefined tree', () => {
const tree = new BinaryTree(undefined)

expect(breadthSearchIterator(tree.root)).toBe('null')
expect(breadthSearchIterator(tree.root)).toBe('undefined')
})
it('should handle a single node binary tree: ', () => {
const tree = new BinaryTree([100])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Queue } from 'data-types/queue'
import { BinaryTreeNode } from 'data-types/binary-tree-node'
import { Queue } from '@proveo/cs-datatypes'
import { BinaryTreeNode } from '@proveo/cs-datatypes'

// For a breadth search iterations, we'll use 2 queues.
// The current queue describes the current level, and we'll be enqueuing children
// Onto the next queue, until the current level is empty. We'll swap the queues references
// To iterate, until the current queue is empty:
export const breadthSearchIterator = function (root: BinaryTreeNode) {
export const breadthSearchIterator = function (root: BinaryTreeNode<any> | null) {
let treeString = ''

if (!root || (!root.data && !root.left && !root.right)) {
treeString += 'null'
treeString += 'undefined'
} else {
let queues = [
new Queue<BinaryTreeNode>(),
new Queue<BinaryTreeNode>(),
new Queue<BinaryTreeNode<any>>(),
new Queue<BinaryTreeNode<any>>(),
]

let currentQueue = queues[0]
Expand All @@ -22,7 +22,7 @@ export const breadthSearchIterator = function (root: BinaryTreeNode) {

currentQueue.enqueue(root)
// Printing nodes in level-order until the current queue remains empty
while (currentQueue._items.length > 0) {
while (currentQueue.size() > 0) {
let currentNode = currentQueue.dequeue()
treeString += String(currentNode.data)

Expand All @@ -37,9 +37,9 @@ export const breadthSearchIterator = function (root: BinaryTreeNode) {

// When the current queue is empty, we increase the level, print a new line
// and swap the current and next queues
if (currentQueue._items.length == 0) {
if (currentQueue.size() == 0) {
++levelNumber
if (nextQueue._items.length != 0) {
if (nextQueue.size() != 0) {
treeString += ' : '
}
currentQueue = queues[levelNumber % 2]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { describe, expect, it } from 'bun:test'
import { BinaryTree } from 'data-types/binary-tree'
import { depthSearchIterator } from './173-binary-search-tree-iterator'
import { BinaryTree } from '@proveo/cs-datatypes'
import { depthSearchIterator } from './173-binary-search-tree-iterator.js'

describe('Depth Search Iterator (In-Order Trasversal) tests', () => {
it('should handle null values', () => {
const tree = new BinaryTree(null)
it('should handle undefined values', () => {
const tree = new BinaryTree(undefined)

expect(depthSearchIterator(tree.root)).toBe('null')
expect(depthSearchIterator(tree.root)).toBe('undefined')
})
it('should handle single nodes', () => {
const tree = new BinaryTree([100])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import { Stack } from 'data-types/stack'
import { BinaryTreeNode } from 'data-types/binary-tree-node'
import { Stack } from '@proveo/cs-datatypes'
import { BinaryTreeNode } from '@proveo/cs-datatypes'

// Depth search first:
// A stack will be filled from the root to the leftmost node, then at every node popped out
// we check if it has a right node, and stack all the way to its leftmost node
class InOrderIterator {
depthStack: Stack
depthStack: Stack<any>

constructor(root: BinaryTreeNode) {
constructor(root: BinaryTreeNode<any>) {
this.depthStack = new Stack()
// Assuming that when iterator is initialized
// it is always at the first element of tree in its in-order
this.populateStack(root)
}

// Function to populate the stack from the root till the left-most node
populateStack(root) {
populateStack(root: BinaryTreeNode<any>) {
while (root) {
this.depthStack.push(root)
root = root.left
root = root.left!
}
}

// This function checks if there is a node next in line inside the iterator
hasNext() {
if (!this.depthStack || this.depthStack._items.length === 0) {
if (!this.depthStack || this.depthStack.size() === 0) {
return false
} else {
return true
Expand All @@ -34,7 +34,7 @@ class InOrderIterator {
// getNext returns null if there are no more elements in tree
getNext() {
// Return null if there's no succeeding node to return
if (!this.depthStack || this.depthStack._items.length === 0) {
if (!this.depthStack || this.depthStack.size() === 0) {
return null
}

Expand All @@ -51,9 +51,13 @@ class InOrderIterator {

// This function returns the in-order list of nodes using the hasNext() and
// getNext() methods
export const depthSearchIterator = function (root: BinaryTreeNode): string {
const iterator = new InOrderIterator(root)
export const depthSearchIterator = function (root: BinaryTreeNode<any> | null): string {
let treeString = ''

if (!root || (!root.data && !root.left && !root.right)) {
treeString += 'undefined'
}
const iterator = new InOrderIterator(root!)
while (iterator.hasNext()) {
const currentTreeNode = iterator.getNext()
if (iterator.hasNext()) {
Expand All @@ -63,7 +67,7 @@ export const depthSearchIterator = function (root: BinaryTreeNode): string {
}
}
if (treeString === '') {
treeString = 'null'
treeString = 'undefined'
}
return treeString
}
Loading