diff --git a/lua/leetcode-ui/group/page/blind75.lua b/lua/leetcode-ui/group/page/blind75.lua new file mode 100644 index 00000000..d42231ad --- /dev/null +++ b/lua/leetcode-ui/group/page/blind75.lua @@ -0,0 +1,59 @@ +local cmd = require("leetcode.command") + +local Title = require("leetcode-ui.lines.title") +local Button = require("leetcode-ui.lines.button.menu") +local BackButton = require("leetcode-ui.lines.button.menu.back") +local Buttons = require("leetcode-ui.group.buttons.menu") +local Page = require("leetcode-ui.group.page") + +local footer = require("leetcode-ui.lines.footer") +local header = require("leetcode-ui.lines.menu-header") + +local page = Page() + +page:insert(header) + +page:insert(Title({ "Menu" }, "Blind 75")) + +-- Define all 18 sections in order +local sections = { + { name = "Arrays & Hashing", key = "arrays-hashing", sc = "1" }, + { name = "Two Pointers", key = "two-pointers", sc = "2" }, + { name = "Sliding Window", key = "sliding-window", sc = "3" }, + { name = "Stack", key = "stack", sc = "4" }, + { name = "Binary Search", key = "binary-search", sc = "5" }, + { name = "Linked List", key = "linked-list", sc = "6" }, + { name = "Trees", key = "trees", sc = "7" }, + { name = "Heap / Priority Queue", key = "heap", sc = "8" }, + { name = "Backtracking", key = "backtracking", sc = "9" }, + { name = "Tries", key = "tries", sc = "a" }, + { name = "Graphs", key = "graphs", sc = "b" }, + { name = "Advanced Graphs", key = "advanced-graphs", sc = "c" }, + { name = "1-D Dynamic Programming", key = "1d-dp", sc = "d" }, + { name = "2-D Dynamic Programming", key = "2d-dp", sc = "e" }, + { name = "Greedy", key = "greedy", sc = "f" }, + { name = "Intervals", key = "intervals", sc = "g" }, + { name = "Math & Geometry", key = "math-geometry", sc = "h" }, + { name = "Bit Manipulation", key = "bit-manipulation", sc = "i" }, +} + +local buttons = {} +for _, section in ipairs(sections) do + table.insert(buttons, Button(section.name, { + icon = "󰓹", + sc = section.sc, + on_press = function() + cmd.blind75_section(section.key) + end, + expandable = true, + })) +end + +table.insert(buttons, BackButton("menu")) + +page:insert(Buttons(buttons)) + +page:insert(footer) + +return page + diff --git a/lua/leetcode-ui/group/page/menu.lua b/lua/leetcode-ui/group/page/menu.lua index bc87ead7..072bece1 100644 --- a/lua/leetcode-ui/group/page/menu.lua +++ b/lua/leetcode-ui/group/page/menu.lua @@ -51,6 +51,15 @@ local cache = Button("Cache", { expandable = true, }) +local blind75 = Button("Blind 75", { + icon = "󰓹", + sc = "b", + on_press = function() + cmd.set_menu_page("blind75") + end, + expandable = true, +}) + local exit = ExitButton() page:insert(Buttons({ @@ -58,6 +67,7 @@ page:insert(Buttons({ statistics, cookie, cache, + blind75, exit, })) diff --git a/lua/leetcode/command/init.lua b/lua/leetcode/command/init.lua index 11824456..edeaf463 100644 --- a/lua/leetcode/command/init.lua +++ b/lua/leetcode/command/init.lua @@ -30,6 +30,68 @@ function cmd.problems(options) picker.question(p, options) end +---@param options table +function cmd.blind75(options) + require("leetcode.utils").auth_guard() + + local problem_lists = require("leetcode.config.problem_lists") + local problemlist = require("leetcode.cache.problemlist") + local all_problems = problemlist.get() + + -- Create a map of slug -> problem for quick lookup + local problems_map = {} + for _, problem in ipairs(all_problems) do + problems_map[problem.title_slug] = problem + end + + -- Build filtered list maintaining the exact order from blind75 list + local filtered = {} + for _, slug in ipairs(problem_lists.blind75) do + local problem = problems_map[slug] + if problem then + table.insert(filtered, problem) + end + end + + local picker = require("leetcode.picker") + picker.question(filtered, options) +end + +---@param section_key string +function cmd.blind75_section(section_key) + require("leetcode.utils").auth_guard() + + local problem_lists = require("leetcode.config.problem_lists") + local problemlist = require("leetcode.cache.problemlist") + local all_problems = problemlist.get() + + -- Get problems for the specific section (in order) + local section_slugs = problem_lists.get_blind75_section(section_key) + if not section_slugs or #section_slugs == 0 then + log.warn(("No problems found for section: %s"):format(section_key)) + return + end + + -- Create a map of slug -> problem for quick lookup + local problems_map = {} + for _, problem in ipairs(all_problems) do + problems_map[problem.title_slug] = problem + end + + -- Build filtered list maintaining the exact order from section_slugs + local filtered = {} + for _, slug in ipairs(section_slugs) do + local problem = problems_map[slug] + if problem then + table.insert(filtered, problem) + end + end + + local picker = require("leetcode.picker") + picker.question(filtered, {}) +end + + ---@param cb? function function cmd.cookie_prompt(cb) local cookie = require("leetcode.cache.cookie") @@ -634,6 +696,10 @@ cmd.commands = { cmd.problems, _args = arguments.list, }, + blind75 = { + cmd.blind75, + _args = arguments.list, + }, random = { cmd.random_question, _args = arguments.random, diff --git a/lua/leetcode/config/problem_lists.lua b/lua/leetcode/config/problem_lists.lua new file mode 100644 index 00000000..12c81aa0 --- /dev/null +++ b/lua/leetcode/config/problem_lists.lua @@ -0,0 +1,127 @@ +---@class lc.ProblemLists +local ProblemLists = {} + +-- Section mapping for Blind75 +local blind75_sections = { + ["arrays-hashing"] = { + "contains-duplicate", + "valid-anagram", + "two-sum", + "group-anagrams", + "top-k-frequent-elements", + "encode-and-decode-strings", + "product-of-array-except-self", + "longest-consecutive-sequence", + }, + ["two-pointers"] = { + "valid-palindrome", + "3sum", + "container-with-most-water", + }, + ["sliding-window"] = { + "best-time-to-buy-and-sell-stock", + "longest-substring-without-repeating-characters", + "longest-repeating-character-replacement", + "minimum-window-substring", + }, + ["stack"] = { + "valid-parentheses", + }, + ["binary-search"] = { + "find-minimum-in-rotated-sorted-array", + "search-in-rotated-sorted-array", + }, + ["linked-list"] = { + "reverse-linked-list", + "merge-two-sorted-lists", + "linked-list-cycle", + "reorder-list", + "remove-nth-node-from-end-of-list", + "merge-k-sorted-lists", + }, + ["trees"] = { + "invert-binary-tree", + "maximum-depth-of-binary-tree", + "same-tree", + "subtree-of-another-tree", + "lowest-common-ancestor-of-a-binary-search-tree", + "binary-tree-level-order-traversal", + "validate-binary-search-tree", + "kth-smallest-element-in-a-bst", + "construct-binary-tree-from-preorder-and-inorder-traversal", + "binary-tree-maximum-path-sum", + "serialize-and-deserialize-binary-tree", + }, + ["heap"] = { + "find-median-from-data-stream", + }, + ["backtracking"] = { + "combination-sum", + "word-search", + }, + ["tries"] = { + "implement-trie-prefix-tree", + "design-add-and-search-words-data-structure", + "word-search-ii", + }, + ["graphs"] = { + "number-of-islands", + "clone-graph", + "pacific-atlantic-water-flow", + "course-schedule", + "graph-valid-tree", + "number-of-connected-components-in-an-undirected-graph", + }, + ["advanced-graphs"] = { + "alien-dictionary", + }, + ["1d-dp"] = { + "climbing-stairs", + "house-robber", + "house-robber-ii", + "longest-palindromic-substring", + "palindromic-substrings", + "decode-ways", + "coin-change", + "maximum-product-subarray", + "word-break", + "longest-increasing-subsequence", + }, + ["2d-dp"] = { + "unique-paths", + "longest-common-subsequence", + }, + ["greedy"] = { + "maximum-subarray", + "jump-game", + }, + ["intervals"] = { + "insert-interval", + "merge-intervals", + "non-overlapping-intervals", + "meeting-rooms", + "meeting-rooms-ii", + }, + ["math-geometry"] = { + "rotate-image", + "spiral-matrix", + "set-matrix-zeroes", + }, + ["bit-manipulation"] = { + "number-of-1-bits", + "counting-bits", + "reverse-bits", + "missing-number", + "sum-of-two-integers", + }, +} + +---Get problems for a specific Blind75 section +---@param section_key string +---@return string[] +function ProblemLists.get_blind75_section(section_key) + return blind75_sections[section_key] or {} +end + +return ProblemLists +