Spaces:
Sleeping
Sleeping
| """ | |
| CodeDebugger Bug Dataset β 30 buggy Python problems. | |
| Schema per problem: id, difficulty, title, description, buggy_code, | |
| fixed_code, test_cases, error_type, hint. | |
| Each problem has exactly 4 test cases. | |
| """ | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # EASY BUGS (1β10) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| EASY_BUGS = [ | |
| # 1 | |
| { | |
| "id": "bug_001", | |
| "difficulty": "easy", | |
| "title": "Off-by-one in list index", | |
| "description": "Fix the bug in this function that retrieves the last element.", | |
| "buggy_code": ( | |
| "def get_last(lst):\n" | |
| " return lst[len(lst)]\n" | |
| ), | |
| "fixed_code": ( | |
| "def get_last(lst):\n" | |
| " return lst[len(lst) - 1]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3]", "expected": "3"}, | |
| {"input": "[10]", "expected": "10"}, | |
| {"input": "[5, 6, 7, 8]", "expected": "8"}, | |
| {"input": "[0]", "expected": "0"}, | |
| ], | |
| "error_type": "IndexError", | |
| "hint": "list indices are 0-based; the last valid index is len(lst)-1.", | |
| }, | |
| # 2 | |
| { | |
| "id": "bug_002", | |
| "difficulty": "easy", | |
| "title": "Wrong comparison operator (> instead of >=)", | |
| "description": "Fix the function that checks whether a score is passing (>= 50).", | |
| "buggy_code": ( | |
| "def is_passing(score):\n" | |
| " return score > 50\n" | |
| ), | |
| "fixed_code": ( | |
| "def is_passing(score):\n" | |
| " return score >= 50\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "75", "expected": "True"}, | |
| {"input": "50", "expected": "True"}, | |
| {"input": "49", "expected": "False"}, | |
| {"input": "100", "expected": "True"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "A score of exactly 50 should pass; use >= not >.", | |
| }, | |
| # 3 | |
| { | |
| "id": "bug_003", | |
| "difficulty": "easy", | |
| "title": "Missing return statement", | |
| "description": "Fix the function that should return the square of a number.", | |
| "buggy_code": ( | |
| "def square(n):\n" | |
| " result = n * n\n" | |
| ), | |
| "fixed_code": ( | |
| "def square(n):\n" | |
| " result = n * n\n" | |
| " return result\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "4", "expected": "16"}, | |
| {"input": "0", "expected": "0"}, | |
| {"input": "-3", "expected": "9"}, | |
| {"input": "10", "expected": "100"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "The function computes the result but never returns it.", | |
| }, | |
| # 4 | |
| { | |
| "id": "bug_004", | |
| "difficulty": "easy", | |
| "title": "Wrong variable name used", | |
| "description": "Fix the function that converts Celsius to Fahrenheit.", | |
| "buggy_code": ( | |
| "def celsius_to_fahrenheit(c):\n" | |
| " f = c * 9 / 5 + 32\n" | |
| " return c\n" | |
| ), | |
| "fixed_code": ( | |
| "def celsius_to_fahrenheit(c):\n" | |
| " f = c * 9 / 5 + 32\n" | |
| " return f\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "0", "expected": "32.0"}, | |
| {"input": "100", "expected": "212.0"}, | |
| {"input": "37", "expected": "98.6"}, | |
| {"input": "-40", "expected": "-40.0"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "The formula stores the result in `f` but the wrong variable is returned.", | |
| }, | |
| # 5 | |
| { | |
| "id": "bug_005", | |
| "difficulty": "easy", | |
| "title": "Wrong string method: split vs strip", | |
| "description": "Fix the function that removes leading/trailing whitespace from a string.", | |
| "buggy_code": ( | |
| "def clean(s):\n" | |
| " return s.split()\n" | |
| ), | |
| "fixed_code": ( | |
| "def clean(s):\n" | |
| " return s.strip()\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "' hello '", "expected": "hello"}, | |
| {"input": "'world'", "expected": "world"}, | |
| {"input": "' '", "expected": ""}, | |
| {"input": "' a b '", "expected": "a b"}, | |
| ], | |
| "error_type": "TypeError", | |
| "hint": "strip() removes whitespace; split() splits into a list.", | |
| }, | |
| # 6 | |
| { | |
| "id": "bug_006", | |
| "difficulty": "easy", | |
| "title": "Missing -1 in length calculation", | |
| "description": "Fix the function that returns the second-to-last element of a list.", | |
| "buggy_code": ( | |
| "def second_to_last(lst):\n" | |
| " return lst[len(lst) - 1]\n" | |
| ), | |
| "fixed_code": ( | |
| "def second_to_last(lst):\n" | |
| " return lst[len(lst) - 2]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3]", "expected": "2"}, | |
| {"input": "[10, 20]", "expected": "10"}, | |
| {"input": "[5, 6, 7, 8]", "expected": "7"}, | |
| {"input": "[0, 1]", "expected": "0"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "The second-to-last index is len(lst)-2, not len(lst)-1.", | |
| }, | |
| # 7 | |
| { | |
| "id": "bug_007", | |
| "difficulty": "easy", | |
| "title": "Wrong list method: append vs extend", | |
| "description": "Fix the function that adds all elements of one list into another.", | |
| "buggy_code": ( | |
| "def combine(base, items):\n" | |
| " base.append(items)\n" | |
| " return base\n" | |
| ), | |
| "fixed_code": ( | |
| "def combine(base, items):\n" | |
| " base.extend(items)\n" | |
| " return base\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2], [3, 4]", "expected": "[1, 2, 3, 4]"}, | |
| {"input": "[], [1]", "expected": "[1]"}, | |
| {"input": "[0], []", "expected": "[0]"}, | |
| {"input": "[1], [2, 3, 4]", "expected": "[1, 2, 3, 4]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "append() adds the list as a single element; extend() unpacks it.", | |
| }, | |
| # 8 | |
| { | |
| "id": "bug_008", | |
| "difficulty": "easy", | |
| "title": "Comparing to None with == instead of is", | |
| "description": "Fix the function that checks whether a value is None.", | |
| "buggy_code": ( | |
| "def is_empty(val):\n" | |
| " return val == None\n" | |
| ), | |
| "fixed_code": ( | |
| "def is_empty(val):\n" | |
| " return val is None\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "None", "expected": "True"}, | |
| {"input": "0", "expected": "False"}, | |
| {"input": "''", "expected": "False"}, | |
| {"input": "[]", "expected": "False"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Use `is None` for identity check, not `== None`.", | |
| }, | |
| # 9 | |
| { | |
| "id": "bug_009", | |
| "difficulty": "easy", | |
| "title": "Integer division instead of float division", | |
| "description": "Fix the function that calculates the average of a list.", | |
| "buggy_code": ( | |
| "def average(nums):\n" | |
| " return sum(nums) // len(nums)\n" | |
| ), | |
| "fixed_code": ( | |
| "def average(nums):\n" | |
| " return sum(nums) / len(nums)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3, 4]", "expected": "2.5"}, | |
| {"input": "[10, 20]", "expected": "15.0"}, | |
| {"input": "[7]", "expected": "7.0"}, | |
| {"input": "[1, 1, 1, 1]", "expected": "1.0"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Use / for true division; // performs floor division.", | |
| }, | |
| # 10 | |
| { | |
| "id": "bug_010", | |
| "difficulty": "easy", | |
| "title": "Wrong list index: -1 vs 0", | |
| "description": "Fix the function that returns the first element of a list.", | |
| "buggy_code": ( | |
| "def get_first(lst):\n" | |
| " return lst[-1]\n" | |
| ), | |
| "fixed_code": ( | |
| "def get_first(lst):\n" | |
| " return lst[0]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3]", "expected": "1"}, | |
| {"input": "[10]", "expected": "10"}, | |
| {"input": "[5, 6, 7, 8]", "expected": "5"}, | |
| {"input": "[99, 0]", "expected": "99"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Index 0 is the first element; -1 is the last.", | |
| }, | |
| ] | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # MEDIUM BUGS (11β20) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| MEDIUM_BUGS = [ | |
| # 11 | |
| { | |
| "id": "bug_011", | |
| "difficulty": "medium", | |
| "title": "Wrong loop termination condition", | |
| "description": "Fix the function that counts down from n to 1 and returns the sum.", | |
| "buggy_code": ( | |
| "def countdown_sum(n):\n" | |
| " total = 0\n" | |
| " while n > 1:\n" | |
| " total += n\n" | |
| " n -= 1\n" | |
| " return total\n" | |
| ), | |
| "fixed_code": ( | |
| "def countdown_sum(n):\n" | |
| " total = 0\n" | |
| " while n >= 1:\n" | |
| " total += n\n" | |
| " n -= 1\n" | |
| " return total\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "5", "expected": "15"}, | |
| {"input": "1", "expected": "1"}, | |
| {"input": "10", "expected": "55"}, | |
| {"input": "3", "expected": "6"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "`n > 1` stops too early and skips adding 1; use `n >= 1` to include it.", | |
| }, | |
| # 12 | |
| { | |
| "id": "bug_012", | |
| "difficulty": "medium", | |
| "title": "Wrong recursion base case value", | |
| "description": "Fix the recursive factorial function that returns the wrong result for n=0.", | |
| "buggy_code": ( | |
| "def factorial(n):\n" | |
| " if n == 0:\n" | |
| " return 0\n" | |
| " return n * factorial(n - 1)\n" | |
| ), | |
| "fixed_code": ( | |
| "def factorial(n):\n" | |
| " if n == 0:\n" | |
| " return 1\n" | |
| " return n * factorial(n - 1)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "0", "expected": "1"}, | |
| {"input": "1", "expected": "1"}, | |
| {"input": "5", "expected": "120"}, | |
| {"input": "7", "expected": "5040"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "0! is defined as 1, not 0. The base case must return 1.", | |
| }, | |
| # 13 | |
| { | |
| "id": "bug_013", | |
| "difficulty": "medium", | |
| "title": "Wrong sort order (missing reverse=True)", | |
| "description": "Fix the function that should return a list sorted in descending order.", | |
| "buggy_code": ( | |
| "def sort_desc(lst):\n" | |
| " return sorted(lst)\n" | |
| ), | |
| "fixed_code": ( | |
| "def sort_desc(lst):\n" | |
| " return sorted(lst, reverse=True)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[3, 1, 2]", "expected": "[3, 2, 1]"}, | |
| {"input": "[5, 5, 5]", "expected": "[5, 5, 5]"}, | |
| {"input": "[1]", "expected": "[1]"}, | |
| {"input": "[10, 3, 7, 1]", "expected": "[10, 7, 3, 1]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "sorted() returns ascending order by default; pass reverse=True for descending.", | |
| }, | |
| # 14 | |
| { | |
| "id": "bug_014", | |
| "difficulty": "medium", | |
| "title": "Missing edge case for empty list", | |
| "description": "Fix the function that returns the max of a list β it crashes on empty input.", | |
| "buggy_code": ( | |
| "def safe_max(lst):\n" | |
| " return max(lst)\n" | |
| ), | |
| "fixed_code": ( | |
| "def safe_max(lst):\n" | |
| " if not lst:\n" | |
| " return None\n" | |
| " return max(lst)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[]", "expected": "None"}, | |
| {"input": "[3]", "expected": "3"}, | |
| {"input": "[1, 5, 2]", "expected": "5"}, | |
| {"input": "[-1, -3, -2]", "expected": "-1"}, | |
| ], | |
| "error_type": "ValueError", | |
| "hint": "max() raises ValueError on an empty sequence; guard with an empty-list check.", | |
| }, | |
| # 15 | |
| { | |
| "id": "bug_015", | |
| "difficulty": "medium", | |
| "title": "Wrong string format (% vs .format)", | |
| "description": "Fix the function that formats a greeting using .format().", | |
| "buggy_code": ( | |
| "def greet(name, age):\n" | |
| " return 'Hello %s, you are %d years old' % (name,)\n" | |
| ), | |
| "fixed_code": ( | |
| "def greet(name, age):\n" | |
| " return 'Hello {}, you are {} years old'.format(name, age)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "'Alice', 30", "expected": "Hello Alice, you are 30 years old"}, | |
| {"input": "'Bob', 25", "expected": "Hello Bob, you are 25 years old"}, | |
| {"input": "'Z', 1", "expected": "Hello Z, you are 1 years old"}, | |
| {"input": "'Dev', 99", "expected": "Hello Dev, you are 99 years old"}, | |
| ], | |
| "error_type": "TypeError", | |
| "hint": "The % format string has two placeholders but only one argument is passed.", | |
| }, | |
| # 16 | |
| { | |
| "id": "bug_016", | |
| "difficulty": "medium", | |
| "title": "Wrong dictionary key access", | |
| "description": "Fix the function that retrieves a value from a dict safely.", | |
| "buggy_code": ( | |
| "def get_value(d, key):\n" | |
| " return d[key]\n" | |
| ), | |
| "fixed_code": ( | |
| "def get_value(d, key):\n" | |
| " return d.get(key, None)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "{'a': 1}, 'a'", "expected": "1"}, | |
| {"input": "{'b': 2}, 'x'", "expected": "None"}, | |
| {"input": "{}, 'k'", "expected": "None"}, | |
| {"input": "{'z': 0}, 'z'", "expected": "0"}, | |
| ], | |
| "error_type": "KeyError", | |
| "hint": "Use dict.get(key, default) to avoid KeyError on missing keys.", | |
| }, | |
| # 17 | |
| { | |
| "id": "bug_017", | |
| "difficulty": "medium", | |
| "title": "Wrong boolean logic (and vs or)", | |
| "description": "Fix the function that returns True only when both flags are True.", | |
| "buggy_code": ( | |
| "def both_true(a, b):\n" | |
| " return a or b\n" | |
| ), | |
| "fixed_code": ( | |
| "def both_true(a, b):\n" | |
| " return a and b\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "True, True", "expected": "True"}, | |
| {"input": "True, False", "expected": "False"}, | |
| {"input": "False, True", "expected": "False"}, | |
| {"input": "False, False", "expected": "False"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "`or` returns True if either is True; use `and` to require both.", | |
| }, | |
| # 18 | |
| { | |
| "id": "bug_018", | |
| "difficulty": "medium", | |
| "title": "Wrong range bounds (range(n) vs range(n+1))", | |
| "description": "Fix the function that sums integers from 0 to n inclusive.", | |
| "buggy_code": ( | |
| "def sum_to_n(n):\n" | |
| " return sum(range(n))\n" | |
| ), | |
| "fixed_code": ( | |
| "def sum_to_n(n):\n" | |
| " return sum(range(n + 1))\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "5", "expected": "15"}, | |
| {"input": "0", "expected": "0"}, | |
| {"input": "1", "expected": "1"}, | |
| {"input": "10", "expected": "55"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "range(n) stops before n; use range(n+1) to include n.", | |
| }, | |
| # 19 | |
| { | |
| "id": "bug_019", | |
| "difficulty": "medium", | |
| "title": "Missing int() type conversion", | |
| "description": "Fix the function that reads a number from a string and doubles it.", | |
| "buggy_code": ( | |
| "def double_str(s):\n" | |
| " return s * 2\n" | |
| ), | |
| "fixed_code": ( | |
| "def double_str(s):\n" | |
| " return int(s) * 2\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "'5'", "expected": "10"}, | |
| {"input": "'0'", "expected": "0"}, | |
| {"input": "'3'", "expected": "6"}, | |
| {"input": "'21'", "expected": "42"}, | |
| ], | |
| "error_type": "TypeError", | |
| "hint": "Multiplying a string by 2 repeats it; convert to int first.", | |
| }, | |
| # 20 | |
| { | |
| "id": "bug_020", | |
| "difficulty": "medium", | |
| "title": "Wrong list slicing ([1:] vs [:1])", | |
| "description": "Fix the function that returns all elements except the first.", | |
| "buggy_code": ( | |
| "def tail(lst):\n" | |
| " return lst[:1]\n" | |
| ), | |
| "fixed_code": ( | |
| "def tail(lst):\n" | |
| " return lst[1:]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3]", "expected": "[2, 3]"}, | |
| {"input": "[10]", "expected": "[]"}, | |
| {"input": "[5, 6, 7, 8]", "expected": "[6, 7, 8]"}, | |
| {"input": "[0, 0]", "expected": "[0]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "lst[:1] returns only the first element; lst[1:] skips it.", | |
| }, | |
| ] | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # HARD BUGS (21β30) | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| HARD_BUGS = [ | |
| # 21 | |
| { | |
| "id": "bug_021", | |
| "difficulty": "hard", | |
| "title": "Binary search off-by-one in mid update", | |
| "description": "Fix the binary search that infinite-loops when the target is absent.", | |
| "buggy_code": ( | |
| "def binary_search(arr, target):\n" | |
| " lo, hi = 0, len(arr) - 1\n" | |
| " while lo <= hi:\n" | |
| " mid = (lo + hi) // 2\n" | |
| " if arr[mid] == target:\n" | |
| " return mid\n" | |
| " elif arr[mid] < target:\n" | |
| " lo = mid\n" | |
| " else:\n" | |
| " hi = mid\n" | |
| " return -1\n" | |
| ), | |
| "fixed_code": ( | |
| "def binary_search(arr, target):\n" | |
| " lo, hi = 0, len(arr) - 1\n" | |
| " while lo <= hi:\n" | |
| " mid = (lo + hi) // 2\n" | |
| " if arr[mid] == target:\n" | |
| " return mid\n" | |
| " elif arr[mid] < target:\n" | |
| " lo = mid + 1\n" | |
| " else:\n" | |
| " hi = mid - 1\n" | |
| " return -1\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3, 4, 5], 3", "expected": "2"}, | |
| {"input": "[1, 2, 3, 4, 5], 6", "expected": "-1"}, | |
| {"input": "[10, 20, 30], 10", "expected": "0"}, | |
| {"input": "[7], 7", "expected": "0"}, | |
| ], | |
| "error_type": "InfiniteLoop", | |
| "hint": "lo and hi must actually shrink: use mid+1 and mid-1.", | |
| }, | |
| # 22 | |
| { | |
| "id": "bug_022", | |
| "difficulty": "hard", | |
| "title": "Wrong DP state transition (Fibonacci)", | |
| "description": "Fix the DP Fibonacci that stores the wrong value at each step.", | |
| "buggy_code": ( | |
| "def fib_dp(n):\n" | |
| " if n <= 1:\n" | |
| " return n\n" | |
| " dp = [0] * (n + 1)\n" | |
| " dp[1] = 1\n" | |
| " for i in range(2, n + 1):\n" | |
| " dp[i] = dp[i - 1] + dp[i - 1]\n" | |
| " return dp[n]\n" | |
| ), | |
| "fixed_code": ( | |
| "def fib_dp(n):\n" | |
| " if n <= 1:\n" | |
| " return n\n" | |
| " dp = [0] * (n + 1)\n" | |
| " dp[1] = 1\n" | |
| " for i in range(2, n + 1):\n" | |
| " dp[i] = dp[i - 1] + dp[i - 2]\n" | |
| " return dp[n]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "0", "expected": "0"}, | |
| {"input": "1", "expected": "1"}, | |
| {"input": "6", "expected": "8"}, | |
| {"input": "10", "expected": "55"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Fibonacci recurrence is dp[i-1] + dp[i-2], not dp[i-1] + dp[i-1].", | |
| }, | |
| # 23 | |
| { | |
| "id": "bug_023", | |
| "difficulty": "hard", | |
| "title": "Wrong graph traversal: visited check in wrong place", | |
| "description": "Fix BFS that revisits nodes because it marks them visited too late.", | |
| "buggy_code": ( | |
| "from collections import deque\n" | |
| "def bfs_count(graph, start):\n" | |
| " visited = set()\n" | |
| " queue = deque([start])\n" | |
| " count = 0\n" | |
| " while queue:\n" | |
| " node = queue.popleft()\n" | |
| " if node in visited:\n" | |
| " continue\n" | |
| " visited.add(node)\n" | |
| " count += 1\n" | |
| " for nb in graph.get(node, []):\n" | |
| " queue.append(nb)\n" | |
| " return count\n" | |
| ), | |
| "fixed_code": ( | |
| "from collections import deque\n" | |
| "def bfs_count(graph, start):\n" | |
| " visited = set([start])\n" | |
| " queue = deque([start])\n" | |
| " count = 0\n" | |
| " while queue:\n" | |
| " node = queue.popleft()\n" | |
| " count += 1\n" | |
| " for nb in graph.get(node, []):\n" | |
| " if nb not in visited:\n" | |
| " visited.add(nb)\n" | |
| " queue.append(nb)\n" | |
| " return count\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "{0:[1,2],1:[],2:[]}, 0", "expected": "3"}, | |
| {"input": "{0:[1],1:[0]}, 0", "expected": "2"}, | |
| {"input": "{0:[]}, 0", "expected": "1"}, | |
| {"input": "{0:[1,2],1:[2],2:[0]}, 0", "expected": "3"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Mark nodes visited when enqueuing, not when dequeuing.", | |
| }, | |
| # 24 | |
| { | |
| "id": "bug_024", | |
| "difficulty": "hard", | |
| "title": "Missing memoization causing exponential recursion", | |
| "description": "Fix the recursive function that recomputes overlapping subproblems.", | |
| "buggy_code": ( | |
| "def fib_memo(n, memo={}):\n" | |
| " if n <= 1:\n" | |
| " return n\n" | |
| " return fib_memo(n - 1) + fib_memo(n - 2)\n" | |
| ), | |
| "fixed_code": ( | |
| "def fib_memo(n, memo={}):\n" | |
| " if n <= 1:\n" | |
| " return n\n" | |
| " if n in memo:\n" | |
| " return memo[n]\n" | |
| " memo[n] = fib_memo(n - 1, memo) + fib_memo(n - 2, memo)\n" | |
| " return memo[n]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "0", "expected": "0"}, | |
| {"input": "1", "expected": "1"}, | |
| {"input": "10", "expected": "55"}, | |
| {"input": "20", "expected": "6765"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Check memo before recursing and store the result after computing.", | |
| }, | |
| # 25 | |
| { | |
| "id": "bug_025", | |
| "difficulty": "hard", | |
| "title": "Wrong two-pointer movement direction", | |
| "description": "Fix two-pointer sum that moves the wrong pointer.", | |
| "buggy_code": ( | |
| "def two_sum_sorted(arr, target):\n" | |
| " lo, hi = 0, len(arr) - 1\n" | |
| " while lo < hi:\n" | |
| " s = arr[lo] + arr[hi]\n" | |
| " if s == target:\n" | |
| " return [lo, hi]\n" | |
| " elif s < target:\n" | |
| " hi -= 1\n" | |
| " else:\n" | |
| " lo += 1\n" | |
| " return []\n" | |
| ), | |
| "fixed_code": ( | |
| "def two_sum_sorted(arr, target):\n" | |
| " lo, hi = 0, len(arr) - 1\n" | |
| " while lo < hi:\n" | |
| " s = arr[lo] + arr[hi]\n" | |
| " if s == target:\n" | |
| " return [lo, hi]\n" | |
| " elif s < target:\n" | |
| " lo += 1\n" | |
| " else:\n" | |
| " hi -= 1\n" | |
| " return []\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2, 3, 4, 6], 6", "expected": "[1, 3]"}, | |
| {"input": "[1, 3, 5, 7], 8", "expected": "[0, 3]"}, | |
| {"input": "[1, 2], 3", "expected": "[0, 1]"}, | |
| {"input": "[1, 2, 3], 10", "expected": "[]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Sum too small β move lo up (increase); sum too large β move hi down.", | |
| }, | |
| # 26 | |
| { | |
| "id": "bug_026", | |
| "difficulty": "hard", | |
| "title": "Wrong greedy choice (min vs max)", | |
| "description": "Fix the greedy function that should pick the largest item that fits.", | |
| "buggy_code": ( | |
| "def greedy_knapsack(weights, capacity):\n" | |
| " weights = sorted(weights)\n" | |
| " total = 0\n" | |
| " for w in weights:\n" | |
| " if total + w <= capacity:\n" | |
| " total += w\n" | |
| " return total\n" | |
| ), | |
| "fixed_code": ( | |
| "def greedy_knapsack(weights, capacity):\n" | |
| " weights = sorted(weights, reverse=True)\n" | |
| " total = 0\n" | |
| " for w in weights:\n" | |
| " if total + w <= capacity:\n" | |
| " total += w\n" | |
| " return total\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[4, 3, 1], 5", "expected": "5"}, | |
| {"input": "[1, 2, 3], 4", "expected": "4"}, | |
| {"input": "[5], 5", "expected": "5"}, | |
| {"input": "[3, 3, 3], 6", "expected": "6"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Sort descending to pick heaviest items first for max fill.", | |
| }, | |
| # 27 | |
| { | |
| "id": "bug_027", | |
| "difficulty": "hard", | |
| "title": "Off-by-one in sliding window boundary", | |
| "description": "Fix the sliding window that computes max sum of k consecutive elements.", | |
| "buggy_code": ( | |
| "def max_window_sum(arr, k):\n" | |
| " window = sum(arr[:k])\n" | |
| " best = window\n" | |
| " for i in range(1, len(arr) - k):\n" | |
| " window += arr[i + k - 1] - arr[i - 1]\n" | |
| " best = max(best, window)\n" | |
| " return best\n" | |
| ), | |
| "fixed_code": ( | |
| "def max_window_sum(arr, k):\n" | |
| " window = sum(arr[:k])\n" | |
| " best = window\n" | |
| " for i in range(1, len(arr) - k + 1):\n" | |
| " window += arr[i + k - 1] - arr[i - 1]\n" | |
| " best = max(best, window)\n" | |
| " return best\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 3, -1, -3, 5, 3], 3", "expected": "5"}, | |
| {"input": "[2, 1, 5, 1, 3, 2], 3", "expected": "9"}, | |
| {"input": "[1, 2, 3], 2", "expected": "5"}, | |
| {"input": "[5], 1", "expected": "5"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "The range should go to len(arr)-k+1 to include the last window.", | |
| }, | |
| # 28 | |
| { | |
| "id": "bug_028", | |
| "difficulty": "hard", | |
| "title": "Wrong merge logic in merge sort", | |
| "description": "Fix the merge step that uses the wrong comparison operator.", | |
| "buggy_code": ( | |
| "def merge(left, right):\n" | |
| " result = []\n" | |
| " i = j = 0\n" | |
| " while i < len(left) and j < len(right):\n" | |
| " if left[i] > right[j]:\n" | |
| " result.append(left[i])\n" | |
| " i += 1\n" | |
| " else:\n" | |
| " result.append(right[j])\n" | |
| " j += 1\n" | |
| " result.extend(left[i:])\n" | |
| " result.extend(right[j:])\n" | |
| " return result\n" | |
| ), | |
| "fixed_code": ( | |
| "def merge(left, right):\n" | |
| " result = []\n" | |
| " i = j = 0\n" | |
| " while i < len(left) and j < len(right):\n" | |
| " if left[i] <= right[j]:\n" | |
| " result.append(left[i])\n" | |
| " i += 1\n" | |
| " else:\n" | |
| " result.append(right[j])\n" | |
| " j += 1\n" | |
| " result.extend(left[i:])\n" | |
| " result.extend(right[j:])\n" | |
| " return result\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 3], [2, 4]", "expected": "[1, 2, 3, 4]"}, | |
| {"input": "[1], [2]", "expected": "[1, 2]"}, | |
| {"input": "[], [1, 2]", "expected": "[1, 2]"}, | |
| {"input": "[1, 2], []", "expected": "[1, 2]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "Use <= to keep the merge stable and ascending.", | |
| }, | |
| # 29 | |
| { | |
| "id": "bug_029", | |
| "difficulty": "hard", | |
| "title": "Wrong heap operation (push vs pop)", | |
| "description": "Fix the function that finds the k-th largest element using a min-heap.", | |
| "buggy_code": ( | |
| "import heapq\n" | |
| "def kth_largest(nums, k):\n" | |
| " heap = []\n" | |
| " for n in nums:\n" | |
| " heapq.heappush(heap, n)\n" | |
| " if len(heap) > k:\n" | |
| " heapq.heappush(heap, heapq.heappop(heap))\n" | |
| " return heap[0]\n" | |
| ), | |
| "fixed_code": ( | |
| "import heapq\n" | |
| "def kth_largest(nums, k):\n" | |
| " heap = []\n" | |
| " for n in nums:\n" | |
| " heapq.heappush(heap, n)\n" | |
| " if len(heap) > k:\n" | |
| " heapq.heappop(heap)\n" | |
| " return heap[0]\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[3, 2, 1, 5, 6, 4], 2", "expected": "5"}, | |
| {"input": "[3, 2, 3, 1, 2, 4, 5, 5, 6], 4", "expected": "4"}, | |
| {"input": "[1], 1", "expected": "1"}, | |
| {"input": "[5, 4, 3, 2, 1], 3", "expected": "3"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "When the heap exceeds k elements just pop (remove smallest), don't re-push.", | |
| }, | |
| # 30 | |
| { | |
| "id": "bug_030", | |
| "difficulty": "hard", | |
| "title": "Wrong backtracking: missing undo step", | |
| "description": "Fix the backtracking permutation generator that forgets to un-choose.", | |
| "buggy_code": ( | |
| "def permutations(nums):\n" | |
| " result = []\n" | |
| " def backtrack(path, remaining):\n" | |
| " if not remaining:\n" | |
| " result.append(path[:])\n" | |
| " return\n" | |
| " for i in range(len(remaining)):\n" | |
| " path.append(remaining[i])\n" | |
| " backtrack(path, remaining[:i] + remaining[i+1:])\n" | |
| " backtrack([], nums)\n" | |
| " return sorted(result)\n" | |
| ), | |
| "fixed_code": ( | |
| "def permutations(nums):\n" | |
| " result = []\n" | |
| " def backtrack(path, remaining):\n" | |
| " if not remaining:\n" | |
| " result.append(path[:])\n" | |
| " return\n" | |
| " for i in range(len(remaining)):\n" | |
| " path.append(remaining[i])\n" | |
| " backtrack(path, remaining[:i] + remaining[i+1:])\n" | |
| " path.pop()\n" | |
| " backtrack([], nums)\n" | |
| " return sorted(result)\n" | |
| ), | |
| "test_cases": [ | |
| {"input": "[1, 2]", "expected": "[[1, 2], [2, 1]]"}, | |
| {"input": "[1]", "expected": "[[1]]"}, | |
| {"input": "[1, 2, 3]", "expected": "[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]"}, | |
| {"input": "[3, 1]", "expected": "[[1, 3], [3, 1]]"}, | |
| ], | |
| "error_type": "LogicError", | |
| "hint": "After each recursive call, pop the last element to undo the choice.", | |
| }, | |
| ] | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Module-level exports | |
| # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ALL_PROBLEMS = EASY_BUGS + MEDIUM_BUGS + HARD_BUGS | |
| TRAINING_SCENARIOS = sorted( | |
| ALL_PROBLEMS, | |
| key=lambda x: ["easy", "medium", "hard"].index(x["difficulty"]), | |
| ) | |
| BUG_DATASET = ALL_PROBLEMS # backward-compat alias | |
| # ββ Helper functions ββββββββββββββββββββββββββββββββββββββββββββ | |
| def get_problem(problem_id: str) -> dict | None: | |
| """Return a single problem by ID, or None if not found.""" | |
| for p in ALL_PROBLEMS: | |
| if p["id"] == problem_id: | |
| return p | |
| return None | |
| def get_all_problems() -> list[dict]: | |
| """Return all 30 problems.""" | |
| return ALL_PROBLEMS | |
| def get_problem_ids() -> list[str]: | |
| """Return all problem IDs in order.""" | |
| return [p["id"] for p in ALL_PROBLEMS] | |
| def get_problems_by_difficulty(difficulty: str) -> list[dict]: | |
| """Return problems filtered by difficulty ('easy'|'medium'|'hard').""" | |
| return [p for p in ALL_PROBLEMS if p["difficulty"] == difficulty] | |