Add solution notes scaffold and sub-heading format

- roadmap.org: problems now have *** Python and *** C++ sub-headings,
  plus Notes: links to per-problem org files
- scaffold-notes.mjs: creates 199 note files in org/cpp/dsa/<topic>/
  with backlinks to roadmap.org
- 18 topic folders under org/cpp/dsa/ for NeetCode 150 problems
- Updated AGENTS.md with new conventions and workflow
This commit is contained in:
2026-06-01 02:33:30 +08:00
parent 7371b2617d
commit eabb433ec6
204 changed files with 2686 additions and 403 deletions
+22 -3
View File
@@ -68,9 +68,28 @@ Arrays & Hashing
## Org-Mode Format
Each topic is a `* TODO` heading with a `[/]` cookie for progress.
Problems are `- [ ] TODO` items with difficulty tags (`:easy:`,
`:medium:`, `:hard:`). Python and C++ solution links are nested
`- [ ] TODO` sub-items. LeetCode and video links are plain list items.
Problems are `** TODO` sub-headings with difficulty tags (`:easy:`,
`:medium:`, `:hard:`). Python and C++ solution links are `***` sub-headings
under each problem. Each problem also links to a notes file at
`org/cpp/dsa/<topic>/<problem>.org` for personal solutions and flashcards.
### Notes Files
`org/cpp/dsa/<topic>/<code>.org` — one per NeetCode 150 problem (199 total).
Scaffolded by `scaffold-notes.mjs`. Template:
```org
* TODO 0217. Contains Duplicate :easy:
:PROPERTIES:
:NEETCODE: [[../../../../leetcode/out/roadmap.org::*0217. Contains Duplicate][Roadmap]]
:END:
#+begin_src cpp
#+end_src
```
Run `node scaffold-notes.mjs` to create missing note files (skips existing).
## Updating
+15 -2
View File
@@ -207,10 +207,19 @@ function buildOrg(sortedNodes, problemsByTopic) {
const difficultyTag = (d) =>
d === "Easy" ? "easy" : d === "Medium" ? "medium" : "hard";
const topicSlug = (name) =>
name
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)/g, "");
const notesRoot = "../../org/cpp/dsa";
for (const node of sortedNodes) {
const topicProblems = (problemsByTopic[node.name] || []).filter(
(p) => p.neetcode150
);
const slug = topicSlug(node.name);
lines.push(`* TODO ${node.name} [/]`);
lines.push("");
@@ -224,14 +233,18 @@ function buildOrg(sortedNodes, problemsByTopic) {
const tag = difficultyTag(p.difficulty);
const lcUrl = `${LEETCODE_BASE}${p.link}`;
const num = p.code.split("-")[0];
const notesFile = `${notesRoot}/${slug}/${p.code}.org`;
lines.push(`** TODO ${num}. ${p.name} :${tag}:`);
lines.push(`- Python: [[${GITHUB_SOLUTIONS}python/${p.code}.py][${p.code}.py]]`);
lines.push(`- C++: [[${GITHUB_SOLUTIONS}cpp/${p.code}.cpp][${p.code}.cpp]]`);
lines.push(`*** Python`);
lines.push(`- [[${GITHUB_SOLUTIONS}python/${p.code}.py][${p.code}.py]]`);
lines.push(`*** C++`);
lines.push(`- [[${GITHUB_SOLUTIONS}cpp/${p.code}.cpp][${p.code}.cpp]]`);
lines.push(`- LeetCode: [[${lcUrl}][${p.link}]]`);
if (p.video)
lines.push(
`- Video: [[https://youtube.com/watch?v=${p.video}][explanation]]`
);
lines.push(`- Notes: [[${notesFile}][My Solution]]`);
}
lines.push("");
}
+995 -398
View File
File diff suppressed because it is too large Load Diff
+55
View File
@@ -0,0 +1,55 @@
import { readFileSync, writeFileSync, existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const roadmap = readFileSync(join(__dirname, "out/roadmap.org"), "utf8");
const dsaDir = join(__dirname, "../org/cpp/dsa");
const topicSlug = (name) =>
name
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)/g, "");
let currentTopic = "";
let count = 0;
for (const line of roadmap.split("\n")) {
const topicMatch = line.match(/^\* TODO (.+?) \[/);
if (topicMatch) {
currentTopic = topicSlug(topicMatch[1]);
continue;
}
const problemMatch = line.match(
/^\*\* TODO (\d+)\. (.+?) :(easy|medium|hard):$/
);
if (problemMatch) {
const [, num, name, diff] = problemMatch;
const slug = name
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)/g, "");
const code = `${num}-${slug}`;
const filePath = join(dsaDir, currentTopic, `${code}.org`);
if (existsSync(filePath)) continue;
const relPath = `../../../../leetcode/out/roadmap.org::*${num}. ${name}`;
const content = `* TODO ${num}. ${name} :${diff}:
:PROPERTIES:
:NEETCODE: [[${relPath}][Roadmap]]
:END:
#+begin_src cpp
#+end_src
`;
writeFileSync(filePath, content);
count++;
}
}
console.log(`Created ${count} note files`);