Skip to content
Open
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
59 changes: 59 additions & 0 deletions lua/leetcode-ui/group/page/blind75.lua
Original file line number Diff line number Diff line change
@@ -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

10 changes: 10 additions & 0 deletions lua/leetcode-ui/group/page/menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,23 @@ 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({
problems,
statistics,
cookie,
cache,
blind75,
exit,
}))

Expand Down
66 changes: 66 additions & 0 deletions lua/leetcode/command/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,68 @@ function cmd.problems(options)
picker.question(p, options)
end

---@param options table<string, string[]>
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")
Expand Down Expand Up @@ -634,6 +696,10 @@ cmd.commands = {
cmd.problems,
_args = arguments.list,
},
blind75 = {
cmd.blind75,
_args = arguments.list,
},
random = {
cmd.random_question,
_args = arguments.random,
Expand Down
127 changes: 127 additions & 0 deletions lua/leetcode/config/problem_lists.lua
Original file line number Diff line number Diff line change
@@ -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