Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .agents/skills/complexity-analysis/skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Complexity Analysis

Analyze the time and space complexity of the current file's implementation. Write the result as a `@complexity` JSDoc block, and add inline comments on the lines that drive the complexity.

put breakdown and steps on complexity analysis before the final time or space complexity to help understanding, e.g in case with 3 separate loop o(n) + o(n) + o(n), explain it become o(3 n) and 3 dropped, so finalized into o(n)
39 changes: 39 additions & 0 deletions .agents/skills/write-intuitions/skill.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Write Intuitions

Add step-by-step intuition comments directly inline in the current file's implementation.

## Target file

Resolve in this priority order — stop at the first match. Check **the current message first**, then earlier conversation history:

1. **IDE open file**: The current user message or any prior message contains an `<ide_opened_file>` tag. Extract the path from inside the tag and use it directly — do NOT ask the user. Example tag: `<ide_opened_file>The user opened the file /abs/path/to/file.js in the IDE...</ide_opened_file>` → path is `/abs/path/to/file.js`.
2. **User-selected code**: If `<ide_selection>` is present in the current or prior messages, derive the file path from it.
3. **Explicitly named file**: A file path the user typed in this message or earlier in the conversation.
4. **Only if none of the above**: Ask the user which file to target.

Once resolved, read the file before writing any comments.

## What to write

For each logical phase of the algorithm, add a comment block above it that explains:

1. **What** is happening at this step in plain English
2. **Why** — what problem it solves or what insight drives it
3. A concrete **example** showing what the data looks like at this point (e.g. input → output of this step)

## Format

Use `// Step N: ...` labels only when steps are long. Example:

```javascript
// Step 1: count how many times each value appears across all lists
// e.g. [1->4->5], [1->3->4] => Map { 1:2, 4:2, 5:1 }
```

## Rules

- Comments can go above the code or inline on the same line — whichever fits without making the line too long
- Keep each comment to 1-2 lines max — no paragraphs
- Use concrete small examples, not abstract descriptions
- Do not restate what the code literally does — explain the _insight_ or _intent_
- Do not remove or alter existing `@complexity` or other JSDoc blocks
1 change: 1 addition & 0 deletions .claude/skills
4 changes: 2 additions & 2 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ build_injected_file() {

if [ -n "$classes" ]; then
printf '%s\n\n' "$classes" > "$out_file"
cat "$ref_file" >> "$out_file"
grep -v "^export" "$ref_file" >> "$out_file"
else
cat "$ref_file" > "$out_file"
grep -v "^export" "$ref_file" > "$out_file"
fi

local export_line
Expand Down
10 changes: 9 additions & 1 deletion leetcode-playground/0019-remove-nth-node-from-end-of-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {

class ListNode {
constructor(val = 0, next = null) {
this.val = val;
this.next = next;
}
}

var removeNthFromEnd = function (head, n) {
// implement
};

export { removeNthFromEnd };
6 changes: 5 additions & 1 deletion leetcode-playground/0021-merge-two-sorted-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ class ListNode {
* Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the two lists.
* Return the head of the merged linked list.
*
* - [Test case]({@link ./tests/0021-merge-two-sorted-lists.test.js})
*
*
* https://leetcode.com/problems/merge-two-sorted-lists/description/
*
* @param {ListNode} list1
* @param {ListNode} list2
* @return {ListNode}
*/
var mergeTwoLists = function (list1, list2) {

// implement
};

export { mergeTwoLists };
10 changes: 9 additions & 1 deletion leetcode-playground/0023-merge-k-sorted-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function(lists) {

class ListNode {
constructor(val, next = null) {
this.val = val;
this.next = next;
}
}

var mergeKLists = function (lists) {
// implement
};

export { mergeKLists };
30 changes: 3 additions & 27 deletions leetcode-playground/0076-minimum-window-substring.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,8 @@
* @param {string} t
* @return {string}
*/
var minWindow = function(s, t) {
const values = new Array(128).fill(0);
let [start, end] = [-Infinity, Infinity];

for (let i = 0; i < t.length; i++) {
values[t.charCodeAt(i)]++;
}

for (let i = 0, j = 0, total = t.length; i < s.length; i++) {
if (values[s.charCodeAt(i)] > 0) {
total--;
}
values[s.charCodeAt(i)]--;
while (!total) {
if (end - start > i - j) {
[start, end] = [j, i];
}
values[s.charCodeAt(j)]++;
if (values[s.charCodeAt(j)] > 0) {
total++;
}
j++;
}
}

return end !== Infinity ? s.slice(start, end + 1) : '';
var minWindow = function (s, t) {
// implementation
};

export { minWindow }
export { minWindow };
53 changes: 45 additions & 8 deletions leetcode-playground/0102-binary-tree-level-order-traversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,52 @@
*/

class TreeNode {
constructor(val, left, right) {
this.val = val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
constructor(val, left, right) {
this.val = val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}

var levelOrder = function(root) {
// Solution implementation
var levelOrder = function (root) {
// 3
// 9 20
// 15 7
// [3], [9, 20], [15, 7]
// perform breath first search,
// normally use queue.

let q = [];
let result = [];
q.push(root);

while (q.length > 0) {
// start processing the queue,

// push left and right into the queue for later processed

// then pop the queue to put it into level

let level = []; // 9 , 20 , 15, 7

let currentQueueLength = q.length;

for (let i = 0; i < currentQueueLength; i++) {
// process item in queue
const node = q.shift();
if (node) {
level.push(node.val);
q.push(node.left);
q.push(node.right);
}
}

if (level.length > 0) {
result.push(level);
}
}

return result;
};

export { levelOrder, TreeNode }
export { levelOrder, TreeNode };
29 changes: 21 additions & 8 deletions leetcode-playground/0104-maximum-depth-of-binary-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,28 @@
*/

class TreeNode {
constructor(val, left, right) {
this.val = val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
constructor(val, left, right) {
this.val = val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}

var maxDepth = function(root) {
// Solution implementation
var maxDepth = function (root) {
// base case — a missing node contributes 0 depth, stopping the recursion
// e.g. leaf.left is null => returns 0
if (!root) return 0;

// recurse into both subtrees to find each side's depth independently
// e.g. root=[1,2,3], root.left=2 => maxLeft = maxDepth(2) = 1
let maxLeft = maxDepth(root.left);
let maxRight = maxDepth(root.right);

// depth at this node = deepest child + 1 (counting the current node itself)
// e.g. maxLeft=2, maxRight=1 => max(2,1)+1 = 3
let maximum = Math.max(maxLeft, maxRight) + 1;

return maximum;
};

export { maxDepth, TreeNode }
export { maxDepth, TreeNode };
21 changes: 20 additions & 1 deletion leetcode-playground/0128-longest-consecutive-sequence.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@
* @param {number[]} nums
* @return {number}
*/
var longestConsecutive = function (nums) {};
var longestConsecutive = function (nums) {
let numSet = new Set(nums); // O(n) — build set
let longestStreak = 0;
for (let num of nums) {
// O(n) outer
if (!numSet.has(num - 1)) {
// only start of a sequence enters — amortizes the while to O(n) total
// its start of new chain,
let currentNum = num;
let currentStreak = 1;
while (numSet.has(currentNum + 1)) {
// O(sequence length) — each element visited at most once across all iterations
currentNum++;
currentStreak++;
}
longestStreak = Math.max(currentStreak, longestStreak);
}
}
return longestStreak;
};

export { longestConsecutive };
11 changes: 6 additions & 5 deletions leetcode-playground/0141-linked-list-cycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
* @return {boolean}
*/
class ListNode {
constructor(val) {
this.val = val;
this.next = null;
}
constructor(val) {
this.val = val;
this.next = null;
}
}

var hasCycle = function(head) {
var hasCycle = function (head) {
// implement
};

export { hasCycle, ListNode };
11 changes: 6 additions & 5 deletions leetcode-playground/0143-reorder-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
* @return {void} Do not return anything, modify head in-place instead.
*/
class ListNode {
constructor(val, next) {
this.val = (val === undefined ? 0 : val);
this.next = (next === undefined ? null : next);
}
constructor(val, next) {
this.val = val === undefined ? 0 : val;
this.next = next === undefined ? null : next;
}
}

var reorderList = function(head) {
var reorderList = function (head) {
// implement
};

export { reorderList, ListNode };
11 changes: 6 additions & 5 deletions leetcode-playground/0206-reverse-linked-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
*/

class ListNode {
constructor(val, next) {
this.val = (val === undefined ? 0 : val);
this.next = (next === undefined ? null : next);
}
constructor(val, next) {
this.val = val === undefined ? 0 : val;
this.next = next === undefined ? null : next;
}
}

var reverseList = function(head) {
var reverseList = function (head) {
// implementation
};

export { ListNode, reverseList };
16 changes: 8 additions & 8 deletions leetcode-playground/0226-invert-binary-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
*/

class TreeNode {
constructor(val, left, right) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}
constructor(val, left, right) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}

var invertTree = function(root) {

var invertTree = function (root) {
// implement
};

export { invertTree, TreeNode }
export { invertTree, TreeNode };
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* @param {number} k - Maximum number of replacements allowed
* @return {number} - Length of longest substring with same letter after at most k replacements
*/
var characterReplacement = function(s, k) {
// stub
var characterReplacement = function (s, k) {
// stub
};

export { characterReplacement };
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ describe('0019-remove-nth-node-from-end-of-list', () => {
it('should handle removing from larger list', () => {
const head = createList([1, 2, 3, 4, 5, 6, 7]);
const result = removeNthFromEnd(head, 3);
expect(listToArray(result)).toEqual([1, 2, 3, 4, 5, 7]);
expect(listToArray(result)).toEqual([1, 2, 3, 4, 6, 7]);
});

it('should handle removing first element in larger list', () => {
Expand Down
Loading