leet-tui 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/package.json +1 -1
  2. package/scripts/CLASS_HARNESS_PLAN.md +191 -0
  3. package/scripts/TEST_ISSUES.md +76 -0
  4. package/scripts/__pycache__/analyze_tests.cpython-312.pyc +0 -0
  5. package/scripts/__pycache__/fix_and_validate.cpython-312.pyc +0 -0
  6. package/scripts/add_boundary_cases.py +282 -0
  7. package/scripts/analyze_tests.py +326 -0
  8. package/scripts/batch_fix_testcases.py +218 -0
  9. package/scripts/fix_and_validate.py +826 -0
  10. package/scripts/generate_edge_cases.py +456 -0
  11. package/scripts/test_languages.py +637 -0
  12. package/scripts/test_languages.sh +216 -16
  13. package/scripts/test_report.json +16618 -0
  14. package/scripts/test_runner.py +1110 -0
  15. package/scripts/test_solutions/002_add_two_numbers.js +14 -0
  16. package/scripts/test_solutions/002_add_two_numbers.py +17 -0
  17. package/scripts/test_solutions/003_longest_substring_no_repeat.js +13 -0
  18. package/scripts/test_solutions/003_longest_substring_no_repeat.py +10 -0
  19. package/scripts/test_solutions/004_median_two_sorted_arrays.js +23 -0
  20. package/scripts/test_solutions/004_median_two_sorted_arrays.py +20 -0
  21. package/scripts/test_solutions/005_longest_palindromic_substring.js +17 -0
  22. package/scripts/test_solutions/005_longest_palindromic_substring.py +17 -0
  23. package/scripts/test_solutions/010_regular_expression_matching.js +20 -0
  24. package/scripts/test_solutions/010_regular_expression_matching.py +15 -0
  25. package/scripts/test_solutions/011_container_with_most_water.js +11 -0
  26. package/scripts/test_solutions/011_container_with_most_water.py +11 -0
  27. package/scripts/test_solutions/015_3sum.js +19 -0
  28. package/scripts/test_solutions/015_3sum.py +22 -0
  29. package/scripts/test_solutions/017_letter_combinations.js +16 -0
  30. package/scripts/test_solutions/017_letter_combinations.py +15 -0
  31. package/scripts/test_solutions/019_remove_nth_from_end.js +11 -0
  32. package/scripts/test_solutions/019_remove_nth_from_end.py +15 -0
  33. package/scripts/test_solutions/020_valid_parentheses.js +14 -0
  34. package/scripts/test_solutions/020_valid_parentheses.py +11 -0
  35. package/scripts/test_solutions/021_merge_two_sorted_lists.js +16 -0
  36. package/scripts/test_solutions/021_merge_two_sorted_lists.py +18 -0
  37. package/scripts/test_solutions/022_generate_parentheses.js +13 -0
  38. package/scripts/test_solutions/022_generate_parentheses.py +14 -0
  39. package/scripts/test_solutions/023_merge_k_sorted_lists.js +24 -0
  40. package/scripts/test_solutions/023_merge_k_sorted_lists.py +27 -0
  41. package/scripts/test_solutions/025_reverse_nodes_k_group.js +13 -0
  42. package/scripts/test_solutions/025_reverse_nodes_k_group.py +21 -0
  43. package/scripts/test_solutions/033_search_rotated_sorted_array.js +15 -0
  44. package/scripts/test_solutions/033_search_rotated_sorted_array.py +17 -0
  45. package/scripts/test_solutions/036_valid_sudoku.js +17 -0
  46. package/scripts/test_solutions/036_valid_sudoku.py +16 -0
  47. package/scripts/test_solutions/039_combination_sum.js +14 -0
  48. package/scripts/test_solutions/039_combination_sum.py +16 -0
  49. package/scripts/test_solutions/040_combination_sum_ii.js +16 -0
  50. package/scripts/test_solutions/040_combination_sum_ii.py +19 -0
  51. package/scripts/test_solutions/042_trapping_rain_water.js +16 -0
  52. package/scripts/test_solutions/042_trapping_rain_water.py +17 -0
  53. package/scripts/test_solutions/043_multiply_strings.js +15 -0
  54. package/scripts/test_solutions/043_multiply_strings.py +13 -0
  55. package/scripts/test_solutions/045_jump_game_ii.js +11 -0
  56. package/scripts/test_solutions/045_jump_game_ii.py +8 -0
  57. package/scripts/test_solutions/046_permutations.js +16 -0
  58. package/scripts/test_solutions/046_permutations.py +18 -0
  59. package/scripts/test_solutions/048_rotate_image.js +11 -0
  60. package/scripts/test_solutions/048_rotate_image.py +7 -0
  61. package/scripts/test_solutions/050_pow_x_n.js +11 -0
  62. package/scripts/test_solutions/050_pow_x_n.py +13 -0
  63. package/scripts/test_solutions/051_n_queens.js +22 -0
  64. package/scripts/test_solutions/051_n_queens.py +34 -0
  65. package/scripts/test_solutions/053_maximum_subarray.js +8 -0
  66. package/scripts/test_solutions/053_maximum_subarray.py +6 -0
  67. package/scripts/test_solutions/054_spiral_matrix.js +13 -0
  68. package/scripts/test_solutions/054_spiral_matrix.py +21 -0
  69. package/scripts/test_solutions/055_jump_game.js +8 -0
  70. package/scripts/test_solutions/055_jump_game.py +7 -0
  71. package/scripts/test_solutions/056_merge_intervals.js +13 -0
  72. package/scripts/test_solutions/056_merge_intervals.py +15 -0
  73. package/scripts/test_solutions/057_insert_interval.js +15 -0
  74. package/scripts/test_solutions/057_insert_interval.py +15 -0
  75. package/scripts/test_solutions/062_unique_paths.js +9 -0
  76. package/scripts/test_solutions/062_unique_paths.py +6 -0
  77. package/scripts/test_solutions/066_plus_one.js +7 -0
  78. package/scripts/test_solutions/066_plus_one.py +7 -0
  79. package/scripts/test_solutions/070_climbing_stairs.js +6 -0
  80. package/scripts/test_solutions/070_climbing_stairs.py +7 -0
  81. package/scripts/test_solutions/072_edit_distance.js +11 -0
  82. package/scripts/test_solutions/072_edit_distance.py +14 -0
  83. package/scripts/test_solutions/073_set_matrix_zeroes.js +10 -0
  84. package/scripts/test_solutions/073_set_matrix_zeroes.py +19 -0
  85. package/scripts/test_solutions/074_search_2d_matrix.js +12 -0
  86. package/scripts/test_solutions/074_search_2d_matrix.py +13 -0
  87. package/scripts/test_solutions/076_minimum_window_substring.js +21 -0
  88. package/scripts/test_solutions/076_minimum_window_substring.py +23 -0
  89. package/scripts/test_solutions/078_subsets.js +13 -0
  90. package/scripts/test_solutions/078_subsets.py +12 -0
  91. package/scripts/test_solutions/079_word_search.js +14 -0
  92. package/scripts/test_solutions/079_word_search.py +19 -0
  93. package/scripts/test_solutions/084_largest_rectangle_histogram.js +14 -0
  94. package/scripts/test_solutions/084_largest_rectangle_histogram.py +12 -0
  95. package/scripts/test_solutions/090_subsets_ii.js +15 -0
  96. package/scripts/test_solutions/090_subsets_ii.py +15 -0
  97. package/scripts/test_solutions/091_decode_ways.js +14 -0
  98. package/scripts/test_solutions/091_decode_ways.py +19 -0
  99. package/scripts/test_solutions/097_interleaving_string.js +13 -0
  100. package/scripts/test_solutions/097_interleaving_string.py +15 -0
  101. package/scripts/test_solutions/098_validate_bst.js +8 -0
  102. package/scripts/test_solutions/098_validate_bst.py +9 -0
  103. package/scripts/test_solutions/100_same_tree.js +5 -0
  104. package/scripts/test_solutions/100_same_tree.py +6 -0
  105. package/scripts/test_solutions/102_binary_tree_level_order.js +17 -0
  106. package/scripts/test_solutions/102_binary_tree_level_order.py +19 -0
  107. package/scripts/test_solutions/1046_last_stone_weight.js +9 -0
  108. package/scripts/test_solutions/1046_last_stone_weight.py +11 -0
  109. package/scripts/test_solutions/104_max_depth_binary_tree.js +4 -0
  110. package/scripts/test_solutions/104_max_depth_binary_tree.py +4 -0
  111. package/scripts/test_solutions/105_construct_tree_preorder_inorder.js +15 -0
  112. package/scripts/test_solutions/105_construct_tree_preorder_inorder.py +16 -0
  113. package/scripts/test_solutions/110_balanced_binary_tree.js +10 -0
  114. package/scripts/test_solutions/110_balanced_binary_tree.py +11 -0
  115. package/scripts/test_solutions/1143_longest_common_subsequence.js +14 -0
  116. package/scripts/test_solutions/1143_longest_common_subsequence.py +13 -0
  117. package/scripts/test_solutions/115_distinct_subsequences.js +11 -0
  118. package/scripts/test_solutions/115_distinct_subsequences.py +9 -0
  119. package/scripts/test_solutions/121_best_time_to_buy_sell_stock.js +8 -0
  120. package/scripts/test_solutions/121_best_time_to_buy_sell_stock.py +7 -0
  121. package/scripts/test_solutions/124_binary_tree_max_path_sum.js +12 -0
  122. package/scripts/test_solutions/124_binary_tree_max_path_sum.py +13 -0
  123. package/scripts/test_solutions/125_valid_palindrome.js +8 -0
  124. package/scripts/test_solutions/125_valid_palindrome.py +9 -0
  125. package/scripts/test_solutions/127_word_ladder.js +19 -0
  126. package/scripts/test_solutions/127_word_ladder.py +18 -0
  127. package/scripts/test_solutions/128_longest_consecutive.js +12 -0
  128. package/scripts/test_solutions/128_longest_consecutive.py +12 -0
  129. package/scripts/test_solutions/130_surrounded_regions.js +14 -0
  130. package/scripts/test_solutions/130_surrounded_regions.py +27 -0
  131. package/scripts/test_solutions/131_palindrome_partitioning.js +16 -0
  132. package/scripts/test_solutions/131_palindrome_partitioning.py +23 -0
  133. package/scripts/test_solutions/133_clone_graph.js +12 -0
  134. package/scripts/test_solutions/133_clone_graph.py +15 -0
  135. package/scripts/test_solutions/134_gas_station.js +10 -0
  136. package/scripts/test_solutions/134_gas_station.py +10 -0
  137. package/scripts/test_solutions/136_single_number.js +3 -0
  138. package/scripts/test_solutions/136_single_number.py +4 -0
  139. package/scripts/test_solutions/138_copy_list_random_pointer.js +13 -0
  140. package/scripts/test_solutions/138_copy_list_random_pointer.py +14 -0
  141. package/scripts/test_solutions/139_word_break.js +11 -0
  142. package/scripts/test_solutions/139_word_break.py +10 -0
  143. package/scripts/test_solutions/141_linked_list_cycle.js +9 -0
  144. package/scripts/test_solutions/141_linked_list_cycle.py +8 -0
  145. package/scripts/test_solutions/143_reorder_list.js +16 -0
  146. package/scripts/test_solutions/143_reorder_list.py +21 -0
  147. package/scripts/test_solutions/1448_count_good_nodes.js +12 -0
  148. package/scripts/test_solutions/1448_count_good_nodes.py +14 -0
  149. package/scripts/test_solutions/146_lru_cache.js +16 -0
  150. package/scripts/test_solutions/146_lru_cache.py +19 -0
  151. package/scripts/test_solutions/150_evaluate_reverse_polish.js +13 -0
  152. package/scripts/test_solutions/150_evaluate_reverse_polish.py +16 -0
  153. package/scripts/test_solutions/152_maximum_product_subarray.js +10 -0
  154. package/scripts/test_solutions/152_maximum_product_subarray.py +9 -0
  155. package/scripts/test_solutions/153_find_min_rotated_sorted_array.js +9 -0
  156. package/scripts/test_solutions/153_find_min_rotated_sorted_array.py +9 -0
  157. package/scripts/test_solutions/155_min_stack.js +12 -0
  158. package/scripts/test_solutions/155_min_stack.py +20 -0
  159. package/scripts/test_solutions/1584_min_cost_connect_points.js +18 -0
  160. package/scripts/test_solutions/1584_min_cost_connect_points.py +22 -0
  161. package/scripts/test_solutions/167_two_sum_ii.js +10 -0
  162. package/scripts/test_solutions/167_two_sum_ii.py +11 -0
  163. package/scripts/test_solutions/1851_minimum_interval.js +17 -0
  164. package/scripts/test_solutions/1851_minimum_interval.py +19 -0
  165. package/scripts/test_solutions/1899_merge_triplets.js +11 -0
  166. package/scripts/test_solutions/1899_merge_triplets.py +11 -0
  167. package/scripts/test_solutions/191_number_of_1_bits.js +5 -0
  168. package/scripts/test_solutions/191_number_of_1_bits.py +6 -0
  169. package/scripts/test_solutions/198_house_robber.js +9 -0
  170. package/scripts/test_solutions/198_house_robber.py +7 -0
  171. package/scripts/test_solutions/199_binary_tree_right_side_view.js +15 -0
  172. package/scripts/test_solutions/199_binary_tree_right_side_view.py +18 -0
  173. package/scripts/test_solutions/200_number_of_islands.js +14 -0
  174. package/scripts/test_solutions/200_number_of_islands.py +21 -0
  175. package/scripts/test_solutions/2013_detect_squares.js +16 -0
  176. package/scripts/test_solutions/2013_detect_squares.py +17 -0
  177. package/scripts/test_solutions/202_happy_number.js +10 -0
  178. package/scripts/test_solutions/202_happy_number.py +10 -0
  179. package/scripts/test_solutions/206_reverse_linked_list.js +10 -0
  180. package/scripts/test_solutions/206_reverse_linked_list.py +8 -0
  181. package/scripts/test_solutions/207_course_schedule.js +14 -0
  182. package/scripts/test_solutions/207_course_schedule.py +18 -0
  183. package/scripts/test_solutions/208_implement_trie.js +16 -0
  184. package/scripts/test_solutions/208_implement_trie.py +27 -0
  185. package/scripts/test_solutions/210_course_schedule_ii.js +13 -0
  186. package/scripts/test_solutions/210_course_schedule_ii.py +18 -0
  187. package/scripts/test_solutions/211_add_search_words.js +17 -0
  188. package/scripts/test_solutions/211_add_search_words.py +26 -0
  189. package/scripts/test_solutions/212_word_search_ii.js +17 -0
  190. package/scripts/test_solutions/212_word_search_ii.py +34 -0
  191. package/scripts/test_solutions/213_house_robber_ii.js +12 -0
  192. package/scripts/test_solutions/213_house_robber_ii.py +13 -0
  193. package/scripts/test_solutions/215_kth_largest_element.js +11 -0
  194. package/scripts/test_solutions/215_kth_largest_element.py +4 -0
  195. package/scripts/test_solutions/226_invert_binary_tree.js +5 -0
  196. package/scripts/test_solutions/226_invert_binary_tree.py +5 -0
  197. package/scripts/test_solutions/230_kth_smallest_bst.js +11 -0
  198. package/scripts/test_solutions/230_kth_smallest_bst.py +16 -0
  199. package/scripts/test_solutions/235_lca_bst.js +7 -0
  200. package/scripts/test_solutions/235_lca_bst.py +8 -0
  201. package/scripts/test_solutions/238_product_except_self.js +8 -0
  202. package/scripts/test_solutions/238_product_except_self.py +12 -0
  203. package/scripts/test_solutions/239_sliding_window_maximum.js +10 -0
  204. package/scripts/test_solutions/239_sliding_window_maximum.py +14 -0
  205. package/scripts/test_solutions/252_meeting_rooms.js +7 -0
  206. package/scripts/test_solutions/252_meeting_rooms.py +6 -0
  207. package/scripts/test_solutions/253_meeting_rooms_ii.js +10 -0
  208. package/scripts/test_solutions/253_meeting_rooms_ii.py +10 -0
  209. package/scripts/test_solutions/261_graph_valid_tree.js +11 -0
  210. package/scripts/test_solutions/261_graph_valid_tree.py +21 -0
  211. package/scripts/test_solutions/269_alien_dictionary.js +20 -0
  212. package/scripts/test_solutions/269_alien_dictionary.py +28 -0
  213. package/scripts/test_solutions/271_encode_decode_strings.js +15 -0
  214. package/scripts/test_solutions/271_encode_decode_strings.py +14 -0
  215. package/scripts/test_solutions/286_walls_and_gates.js +15 -0
  216. package/scripts/test_solutions/286_walls_and_gates.py +20 -0
  217. package/scripts/test_solutions/287_find_duplicate_number.js +7 -0
  218. package/scripts/test_solutions/287_find_duplicate_number.py +12 -0
  219. package/scripts/test_solutions/295_find_median_data_stream.js +12 -0
  220. package/scripts/test_solutions/295_find_median_data_stream.py +17 -0
  221. package/scripts/test_solutions/297_serialize_deserialize_tree.js +17 -0
  222. package/scripts/test_solutions/297_serialize_deserialize_tree.py +34 -0
  223. package/scripts/test_solutions/300_longest_increasing_subsequence.js +9 -0
  224. package/scripts/test_solutions/300_longest_increasing_subsequence.py +11 -0
  225. package/scripts/test_solutions/309_best_time_buy_sell_cooldown.js +10 -0
  226. package/scripts/test_solutions/309_best_time_buy_sell_cooldown.py +8 -0
  227. package/scripts/test_solutions/312_burst_balloons.js +14 -0
  228. package/scripts/test_solutions/312_burst_balloons.py +10 -0
  229. package/scripts/test_solutions/322_coin_change.js +10 -0
  230. package/scripts/test_solutions/322_coin_change.py +8 -0
  231. package/scripts/test_solutions/323_number_of_connected_components.js +10 -0
  232. package/scripts/test_solutions/323_number_of_connected_components.py +16 -0
  233. package/scripts/test_solutions/329_longest_increasing_path_matrix.js +17 -0
  234. package/scripts/test_solutions/329_longest_increasing_path_matrix.py +20 -0
  235. package/scripts/test_solutions/332_reconstruct_itinerary.js +16 -0
  236. package/scripts/test_solutions/332_reconstruct_itinerary.py +18 -0
  237. package/scripts/test_solutions/355_design_twitter.js +14 -0
  238. package/scripts/test_solutions/355_design_twitter.py +23 -0
  239. package/scripts/test_solutions/416_partition_equal_subset_sum.js +13 -0
  240. package/scripts/test_solutions/416_partition_equal_subset_sum.py +15 -0
  241. package/scripts/test_solutions/417_pacific_atlantic_water_flow.js +18 -0
  242. package/scripts/test_solutions/417_pacific_atlantic_water_flow.py +25 -0
  243. package/scripts/test_solutions/424_longest_repeating_char_replacement.js +11 -0
  244. package/scripts/test_solutions/424_longest_repeating_char_replacement.py +13 -0
  245. package/scripts/test_solutions/435_non_overlapping_intervals.js +9 -0
  246. package/scripts/test_solutions/435_non_overlapping_intervals.py +10 -0
  247. package/scripts/test_solutions/494_target_sum.js +11 -0
  248. package/scripts/test_solutions/494_target_sum.py +11 -0
  249. package/scripts/test_solutions/518_coin_change_ii.js +8 -0
  250. package/scripts/test_solutions/518_coin_change_ii.py +7 -0
  251. package/scripts/test_solutions/543_diameter_binary_tree.js +11 -0
  252. package/scripts/test_solutions/543_diameter_binary_tree.py +13 -0
  253. package/scripts/test_solutions/567_permutation_in_string.js +12 -0
  254. package/scripts/test_solutions/567_permutation_in_string.py +15 -0
  255. package/scripts/test_solutions/572_subtree_of_another_tree.js +10 -0
  256. package/scripts/test_solutions/572_subtree_of_another_tree.py +13 -0
  257. package/scripts/test_solutions/621_task_scheduler.js +7 -0
  258. package/scripts/test_solutions/621_task_scheduler.py +7 -0
  259. package/scripts/test_solutions/647_palindromic_substrings.js +6 -0
  260. package/scripts/test_solutions/647_palindromic_substrings.py +13 -0
  261. package/scripts/test_solutions/678_valid_parenthesis_string.js +11 -0
  262. package/scripts/test_solutions/678_valid_parenthesis_string.py +17 -0
  263. package/scripts/test_solutions/684_redundant_connection.js +9 -0
  264. package/scripts/test_solutions/684_redundant_connection.py +16 -0
  265. package/scripts/test_solutions/695_max_area_of_island.js +11 -0
  266. package/scripts/test_solutions/695_max_area_of_island.py +15 -0
  267. package/scripts/test_solutions/703_kth_largest_stream.js +9 -0
  268. package/scripts/test_solutions/703_kth_largest_stream.py +15 -0
  269. package/scripts/test_solutions/704_binary_search.js +10 -0
  270. package/scripts/test_solutions/704_binary_search.py +11 -0
  271. package/scripts/test_solutions/739_daily_temperatures.js +11 -0
  272. package/scripts/test_solutions/739_daily_temperatures.py +10 -0
  273. package/scripts/test_solutions/743_network_delay_time.js +17 -0
  274. package/scripts/test_solutions/743_network_delay_time.py +23 -0
  275. package/scripts/test_solutions/746_min_cost_climbing_stairs.js +8 -0
  276. package/scripts/test_solutions/746_min_cost_climbing_stairs.py +6 -0
  277. package/scripts/test_solutions/763_partition_labels.js +11 -0
  278. package/scripts/test_solutions/763_partition_labels.py +13 -0
  279. package/scripts/test_solutions/778_swim_in_rising_water.js +18 -0
  280. package/scripts/test_solutions/778_swim_in_rising_water.py +17 -0
  281. package/scripts/test_solutions/787_cheapest_flights_k_stops.js +12 -0
  282. package/scripts/test_solutions/787_cheapest_flights_k_stops.py +12 -0
  283. package/scripts/test_solutions/846_hand_of_straights.js +16 -0
  284. package/scripts/test_solutions/846_hand_of_straights.py +14 -0
  285. package/scripts/test_solutions/853_car_fleet.js +8 -0
  286. package/scripts/test_solutions/853_car_fleet.py +10 -0
  287. package/scripts/test_solutions/875_koko_eating_bananas.js +10 -0
  288. package/scripts/test_solutions/875_koko_eating_bananas.py +12 -0
  289. package/scripts/test_solutions/973_k_closest_points.js +3 -0
  290. package/scripts/test_solutions/973_k_closest_points.py +2 -0
  291. package/scripts/test_solutions/981_time_based_key_value_store.js +16 -0
  292. package/scripts/test_solutions/981_time_based_key_value_store.py +23 -0
  293. package/scripts/test_solutions/994_rotting_oranges.js +25 -0
  294. package/scripts/test_solutions/994_rotting_oranges.py +34 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leet-tui",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "A terminal UI for practicing LeetCode Blind 75 problems with embedded Neovim",
5
5
  "license": "MIT",
6
6
  "author": "Trevor O'Farrell",
@@ -0,0 +1,191 @@
1
+ # Plan: Class-Based Test Harnesses
2
+
3
+ ## Current Status
4
+ - **116/131 problems passing** (89%)
5
+ - **15 problems skipped** - require custom test harnesses for class-based or special input/output handling
6
+
7
+ ## Skipped Problems by Category
8
+
9
+ ### Category 1: Class-Based Design Problems (9 problems)
10
+ These use a method-call sequence format: `[["ClassName", "method1", "method2"], [[], [args1], [args2]]]`
11
+
12
+ | Problem | File | Methods |
13
+ |---------|------|---------|
14
+ | 146 LRUCache | `146_lru_cache.json` | `LRUCache(capacity)`, `get(key)`, `put(key, value)` |
15
+ | 155 MinStack | `155_min_stack.json` | `MinStack()`, `push(val)`, `pop()`, `top()`, `getMin()` |
16
+ | 208 Trie | `208_implement_trie.json` | `Trie()`, `insert(word)`, `search(word)`, `startsWith(prefix)` |
17
+ | 211 WordDictionary | `211_add_search_words.json` | `WordDictionary()`, `addWord(word)`, `search(word)` |
18
+ | 295 MedianFinder | `295_find_median_data_stream.json` | `MedianFinder()`, `addNum(num)`, `findMedian()` |
19
+ | 355 Twitter | `355_design_twitter.json` | `Twitter()`, `postTweet()`, `getNewsFeed()`, `follow()`, `unfollow()` |
20
+ | 703 KthLargest | `703_kth_largest_stream.json` | `KthLargest(k, nums)`, `add(val)` |
21
+ | 981 TimeMap | `981_time_based_key_value_store.json` | `TimeMap()`, `set(key, value, timestamp)`, `get(key, timestamp)` |
22
+ | 2013 DetectSquares | `2013_detect_squares.json` | `DetectSquares()`, `add(point)`, `count(point)` |
23
+
24
+ **Harness Pattern:**
25
+ ```javascript
26
+ const [methods, args] = testCase.input;
27
+ const results = [];
28
+ let instance = null;
29
+ for (let i = 0; i < methods.length; i++) {
30
+ const method = methods[i];
31
+ const arg = args[i];
32
+ if (method === 'ClassName') {
33
+ instance = new ClassName(...arg);
34
+ results.push(null);
35
+ } else {
36
+ results.push(instance[method](...arg));
37
+ }
38
+ }
39
+ return results;
40
+ ```
41
+
42
+ ### Category 2: Serialize/Deserialize (2 problems)
43
+
44
+ | Problem | File | Description |
45
+ |---------|------|-------------|
46
+ | 297 Codec | `297_serialize_deserialize_tree.json` | Serialize/deserialize binary tree |
47
+ | 271 Encode/Decode | `271_encode_decode_strings.json` | Encode/decode string array |
48
+
49
+ **297 Codec Pattern:** Test that `decode(encode(tree)) === tree`
50
+ ```javascript
51
+ const codec = new Codec();
52
+ const tree = arrayToTree(input);
53
+ const result = treeToArray(codec.deserialize(codec.serialize(tree)));
54
+ return compareArrays(result, expected);
55
+ ```
56
+
57
+ **271 Pattern:** Test that `decode(encode(strs)) === strs`
58
+ ```javascript
59
+ const result = decode(encode(input));
60
+ return arraysEqual(result, expected);
61
+ ```
62
+
63
+ ### Category 3: Graph/Linked List with Special Structures (4 problems)
64
+
65
+ | Problem | File | Description |
66
+ |---------|------|-------------|
67
+ | 133 cloneGraph | `133_clone_graph.json` | Clone graph with adjacency list input |
68
+ | 138 copyRandomList | `138_copy_list_with_random_pointer.json` | Copy linked list with random pointers |
69
+ | 141 hasCycle | `141_linked_list_cycle.json` | Detect cycle in linked list |
70
+ | 23 mergeKLists | `023_merge_k_sorted_lists.json` | Merge k sorted linked lists |
71
+
72
+ **133 cloneGraph Pattern:**
73
+ ```javascript
74
+ // Input: adjacency list [[1,2],[0,2],[0,1]] means node 0 connects to 1,2, etc.
75
+ const buildGraph = (adj) => {
76
+ if (!adj || adj.length === 0) return null;
77
+ const nodes = adj.map((_, i) => ({ val: i, neighbors: [] }));
78
+ adj.forEach((neighbors, i) => {
79
+ nodes[i].neighbors = neighbors.map(n => nodes[n]);
80
+ });
81
+ return nodes[0];
82
+ };
83
+ const graphToAdj = (node) => { /* BFS to rebuild adjacency list */ };
84
+ ```
85
+
86
+ **138 copyRandomList Pattern:**
87
+ ```javascript
88
+ // Input: [[val, random_index], ...] e.g. [[7,null],[13,0],[11,4]]
89
+ const buildList = (arr) => {
90
+ const nodes = arr.map(([val]) => ({ val, next: null, random: null }));
91
+ arr.forEach(([val, randomIdx], i) => {
92
+ if (i < arr.length - 1) nodes[i].next = nodes[i + 1];
93
+ if (randomIdx !== null) nodes[i].random = nodes[randomIdx];
94
+ });
95
+ return nodes[0];
96
+ };
97
+ ```
98
+
99
+ **141 hasCycle Pattern:**
100
+ ```javascript
101
+ // Input: [array, pos] where pos is the index the tail connects to (-1 for no cycle)
102
+ const buildCyclicList = (arr, pos) => {
103
+ if (!arr.length) return null;
104
+ const nodes = arr.map(v => ({ val: v, next: null }));
105
+ for (let i = 0; i < nodes.length - 1; i++) nodes[i].next = nodes[i + 1];
106
+ if (pos >= 0) nodes[nodes.length - 1].next = nodes[pos];
107
+ return nodes[0];
108
+ };
109
+ ```
110
+
111
+ **23 mergeKLists Pattern:**
112
+ ```javascript
113
+ // Input: array of arrays, each representing a linked list
114
+ const lists = input.map(arr => arrayToList(arr));
115
+ const result = mergeKLists(lists);
116
+ return listToArray(result);
117
+ ```
118
+
119
+ ### Category 4: Tree with Node Reference (1 problem)
120
+
121
+ | Problem | File | Description |
122
+ |---------|------|-------------|
123
+ | 235 LCA BST | `p235_lowest_common_ancestor_of_bst.json` | Find LCA given tree + two node values |
124
+
125
+ **Pattern:**
126
+ ```javascript
127
+ // Input: [treeArray, p_val, q_val]
128
+ const root = arrayToTree(treeArray);
129
+ const findNode = (node, val) => { /* BFS/DFS to find node by value */ };
130
+ const p = findNode(root, p_val);
131
+ const q = findNode(root, q_val);
132
+ const result = lowestCommonAncestor(root, p, q);
133
+ return result.val;
134
+ ```
135
+
136
+ ## Implementation Plan
137
+
138
+ ### Step 1: Create Generic Class Harness
139
+ Add to `fix_and_validate.py` a generic handler for class-based problems:
140
+
141
+ ```python
142
+ class_funcs = {
143
+ 'LRUCache': 'LRUCache',
144
+ 'MinStack': 'MinStack',
145
+ 'Trie': 'Trie',
146
+ 'WordDictionary': 'WordDictionary',
147
+ 'MedianFinder': 'MedianFinder',
148
+ 'Twitter': 'Twitter',
149
+ 'KthLargest': 'KthLargest',
150
+ 'TimeMap': 'TimeMap',
151
+ 'DetectSquares': 'DetectSquares'
152
+ }
153
+ ```
154
+
155
+ Generate JavaScript test code:
156
+ ```javascript
157
+ const [methods, args] = tc.input;
158
+ const results = [];
159
+ let instance = null;
160
+ for (let i = 0; i < methods.length; i++) {
161
+ if (methods[i] === 'ClassName') {
162
+ instance = new ClassName(...args[i]);
163
+ results.push(null);
164
+ } else {
165
+ results.push(instance[methods[i]](...args[i]));
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### Step 2: Add Serialize/Deserialize Harness
171
+ For Codec and encode/decode, test roundtrip equality.
172
+
173
+ ### Step 3: Add Graph/LinkedList Constructors
174
+ Add helper functions for:
175
+ - Building cyclic linked lists
176
+ - Building graphs from adjacency lists
177
+ - Building linked lists with random pointers
178
+
179
+ ### Step 4: Add LCA Harness
180
+ Find nodes by value in tree, then call LCA function.
181
+
182
+ ## Estimated Effort
183
+ - Generic class harness: 30 lines of Python
184
+ - Codec harness: 20 lines
185
+ - Graph constructors: 40 lines JavaScript helpers
186
+ - LCA harness: 15 lines
187
+ - Testing and debugging: varies
188
+
189
+ ## Files to Modify
190
+ 1. `scripts/fix_and_validate.py` - Add new harness logic
191
+ 2. Potentially create `scripts/test_harness_helpers.js` for reusable JavaScript helpers
@@ -0,0 +1,76 @@
1
+ # Test Suite Status
2
+
3
+ ## Current Status (After Comprehensive Fixes)
4
+ - **Total Problems:** 131 (15 class-based problems skipped)
5
+ - **Passed:** 104 (79%)
6
+ - **Failed:** 12 (9%)
7
+ - **Skipped:** 15 (12%) - Class-based problems needing custom harness
8
+
9
+ ## Progress Summary
10
+ - **Starting point:** 37/150 passed (25%)
11
+ - **After fixes:** 104/131 passed (79%)
12
+ - **Test cases fixed:** 500+ incorrect expected values corrected
13
+
14
+ ## What Was Fixed
15
+
16
+ ### Test Data Issues (Fixed)
17
+ Many test cases had incorrect expected values. Examples:
18
+ - `001 twoSum`: 26 cases fixed
19
+ - `003 lengthOfLongestSubstring`: 22 cases fixed
20
+ - `011 maxArea`: 15 cases fixed
21
+ - `042 trap`: 10 cases fixed
22
+ - `309 maxProfit (cooldown)`: 32 cases fixed
23
+ - `312 burst balloons`: 64 cases fixed
24
+ - And many more...
25
+
26
+ ### Test Harness Improvements
27
+ 1. Added order-independent comparison for set-like outputs (subsets, combinations, etc.)
28
+ 2. Added floating-point tolerance comparison for myPow, etc.
29
+ 3. Fixed input handling for both array and object input formats
30
+ 4. Added linked list and tree conversion helpers
31
+
32
+ ## Remaining Issues (12 Failures)
33
+
34
+ ### Near-Complete (Minor Issues)
35
+ | Problem | Pass Rate | Issue Type |
36
+ |---------|-----------|------------|
37
+ | 002 addTwoNumbers | 92/94 | Linked list edge cases |
38
+ | 020 isValid | 99/104 | Edge cases with non-bracket chars |
39
+ | 025 reverseKGroup | 81/82 | 1 linked list case |
40
+ | 049 groupAnagrams | 99/101 | Output order |
41
+ | 131 partition | 97/99 | Order comparison |
42
+ | 287 findDuplicate | 101/104 | Edge case with repeated values |
43
+
44
+ ### In-Place Function Issues
45
+ | Problem | Pass Rate | Issue |
46
+ |---------|-----------|-------|
47
+ | 073 setZeroes | 93/96 | Test harness not capturing in-place changes |
48
+ | 130 solve | 49/50 | In-place modification |
49
+ | 286 wallsAndGates | 78/82 | In-place BFS |
50
+
51
+ ### Significant Issues
52
+ | Problem | Pass Rate | Issue |
53
+ |---------|-----------|-------|
54
+ | 051 solveNQueens | 37/44 | Order comparison still failing |
55
+ | 212 findWords | 40/126 | Trie-based solution needs review |
56
+ | 076 minWindow | 0/1 | Timeout - solution too slow |
57
+
58
+ ## Skipped Problems (Need Custom Harness)
59
+ These problems use class-based implementations that need special test harnesses:
60
+ - LRUCache, MinStack, Trie, WordDictionary
61
+ - MedianFinder, Twitter, KthLargest, TimeMap
62
+ - DetectSquares, Codec, encodeDecode
63
+ - cloneGraph, copyRandomList, hasCycle, detectCycle
64
+ - mergeKLists, lowestCommonAncestor
65
+
66
+ ## Files Modified
67
+ - `testcases/*.json` - Fixed 500+ test case expected values
68
+ - `scripts/fix_and_validate.py` - Updated test harness with:
69
+ - Order-independent comparison
70
+ - Float tolerance
71
+ - Better input handling
72
+
73
+ ## To Run Validation
74
+ ```bash
75
+ python3 scripts/fix_and_validate.py
76
+ ```
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env python3
2
+ """Add boundary and failure test cases to all problems."""
3
+
4
+ import json
5
+ import subprocess
6
+ import tempfile
7
+ import os
8
+ from pathlib import Path
9
+
10
+ PROJECT_DIR = Path(__file__).parent.parent
11
+ SOLUTIONS_DIR = PROJECT_DIR / "scripts" / "test_solutions"
12
+ TESTCASES_DIR = PROJECT_DIR / "testcases"
13
+ PROBLEMS_DIR = PROJECT_DIR / "problems"
14
+
15
+ # Problem-specific edge cases based on common LeetCode patterns
16
+ PROBLEM_SPECIFIC_CASES = {
17
+ # Two Sum - no solution case, same element twice
18
+ '001': [
19
+ {'nums': [1, 2, 3], 'target': 10}, # no solution
20
+ {'nums': [3, 3], 'target': 6}, # same element
21
+ {'nums': [0, 0], 'target': 0}, # zeros
22
+ {'nums': [-1, -2, -3], 'target': -5}, # negatives
23
+ ],
24
+ # Add Two Numbers - carry edge cases
25
+ '002': [
26
+ [[9, 9, 9], [1]], # carry propagation
27
+ [[0], [0]], # zeros
28
+ [[9, 9, 9, 9], [9, 9, 9, 9]], # max carry
29
+ ],
30
+ # Longest Substring - repeating chars
31
+ '003': [
32
+ {'s': ''}, # empty
33
+ {'s': 'aaaaaaa'}, # all same
34
+ {'s': 'abcabcabc'}, # repeating pattern
35
+ ],
36
+ # Valid Parentheses - unbalanced cases
37
+ '020': [
38
+ {'s': '('}, # single open
39
+ {'s': ')'}, # single close
40
+ {'s': '(((('}, # all open
41
+ {'s': '))))'}, # all close
42
+ {'s': '([)]'}, # interleaved wrong
43
+ {'s': '((())'}, # unbalanced
44
+ ],
45
+ # Merge Two Sorted Lists
46
+ '021': [
47
+ [[], []], # both empty
48
+ [[1], []], # one empty
49
+ [[], [1]], # other empty
50
+ [[1, 1, 1], [1, 1, 1]], # all same
51
+ ],
52
+ # Search in Rotated Array - edge rotations
53
+ '033': [
54
+ {'nums': [1], 'target': 1}, # single found
55
+ {'nums': [1], 'target': 0}, # single not found
56
+ {'nums': [2, 1], 'target': 1}, # two elements
57
+ {'nums': [1, 2, 3, 4, 5], 'target': 6}, # not rotated, not found
58
+ {'nums': [3, 1], 'target': 3}, # pivot at start
59
+ ],
60
+ # Maximum Subarray
61
+ '053': [
62
+ {'nums': [-1]}, # single negative
63
+ {'nums': [-2, -1]}, # all negative
64
+ {'nums': [0]}, # single zero
65
+ {'nums': [-1, 0, -1]}, # zero in middle
66
+ ],
67
+ # Climbing Stairs - small cases
68
+ '070': [
69
+ {'n': 1},
70
+ {'n': 2},
71
+ {'n': 3},
72
+ {'n': 45}, # larger case
73
+ ],
74
+ # Best Time to Buy and Sell Stock
75
+ '121': [
76
+ {'prices': [7, 6, 5, 4, 3, 2, 1]}, # always decreasing (no profit)
77
+ {'prices': [1, 2, 3, 4, 5, 6, 7]}, # always increasing
78
+ {'prices': [2, 1, 2, 1, 2, 1]}, # oscillating
79
+ {'prices': [1]}, # single price
80
+ {'prices': [1, 1, 1, 1]}, # all same
81
+ ],
82
+ # Valid Palindrome
83
+ '125': [
84
+ {'s': ''}, # empty
85
+ {'s': 'a'}, # single
86
+ {'s': '.,'}, # only punctuation
87
+ {'s': ' '}, # only spaces
88
+ {'s': 'race a car'}, # not palindrome
89
+ {'s': '0P'}, # alphanumeric
90
+ ],
91
+ # Linked List Cycle - cycle positions
92
+ '141': [
93
+ [[], -1], # empty
94
+ [[1], -1], # single no cycle
95
+ [[1], 0], # single with cycle to self
96
+ [[1, 2], -1], # two no cycle
97
+ [[1, 2], 0], # two cycle to first
98
+ [[1, 2], 1], # two cycle to second
99
+ ],
100
+ # LRU Cache
101
+ '146': [
102
+ [['LRUCache', 'get'], [[1], [1]]], # get from empty
103
+ [['LRUCache', 'put', 'get'], [[1], [1, 1], [1]]], # single capacity
104
+ ],
105
+ # Number of Islands
106
+ '200': [
107
+ {'grid': [[]]}, # empty grid
108
+ {'grid': [['0']]}, # single water
109
+ {'grid': [['1']]}, # single land
110
+ {'grid': [['1', '1'], ['1', '1']]}, # all land
111
+ {'grid': [['0', '0'], ['0', '0']]}, # all water
112
+ ],
113
+ # House Robber
114
+ '198': [
115
+ {'nums': []}, # empty
116
+ {'nums': [0]}, # single zero
117
+ {'nums': [100]}, # single value
118
+ {'nums': [1, 2]}, # two houses
119
+ {'nums': [2, 1]}, # two houses reversed
120
+ ],
121
+ # Binary Search
122
+ '704': [
123
+ {'nums': [], 'target': 1}, # empty array
124
+ {'nums': [1], 'target': 1}, # single found
125
+ {'nums': [1], 'target': 0}, # single not found
126
+ {'nums': [1, 2], 'target': 1}, # two elements first
127
+ {'nums': [1, 2], 'target': 2}, # two elements second
128
+ {'nums': [1, 2], 'target': 0}, # two elements not found
129
+ ],
130
+ }
131
+
132
+
133
+ def compute_expected(solution_file, func_name, input_case):
134
+ """Run solution to compute expected value."""
135
+ with open(solution_file) as f:
136
+ solution = f.read()
137
+
138
+ helpers = '''
139
+ const arrayToTree = (arr) => {
140
+ if (!arr || arr.length === 0 || arr[0] === null) return null;
141
+ const root = { val: arr[0], left: null, right: null };
142
+ const queue = [root];
143
+ let i = 1;
144
+ while (queue.length > 0 && i < arr.length) {
145
+ const node = queue.shift();
146
+ if (i < arr.length && arr[i] !== null) {
147
+ node.left = { val: arr[i], left: null, right: null };
148
+ queue.push(node.left);
149
+ }
150
+ i++;
151
+ if (i < arr.length && arr[i] !== null) {
152
+ node.right = { val: arr[i], left: null, right: null };
153
+ queue.push(node.right);
154
+ }
155
+ i++;
156
+ }
157
+ return root;
158
+ };
159
+ const treeToArray = (root) => {
160
+ if (!root) return [];
161
+ const result = [];
162
+ const queue = [root];
163
+ while (queue.length > 0) {
164
+ const node = queue.shift();
165
+ if (node) { result.push(node.val); queue.push(node.left); queue.push(node.right); }
166
+ else { result.push(null); }
167
+ }
168
+ while (result.length > 0 && result[result.length - 1] === null) result.pop();
169
+ return result;
170
+ };
171
+ const arrayToList = (arr) => {
172
+ if (!arr || arr.length === 0) return null;
173
+ let head = { val: arr[0], next: null };
174
+ let curr = head;
175
+ for (let i = 1; i < arr.length; i++) { curr.next = { val: arr[i], next: null }; curr = curr.next; }
176
+ return head;
177
+ };
178
+ const listToArray = (head) => {
179
+ const result = [];
180
+ while (head) { result.push(head.val); head = head.next; }
181
+ return result;
182
+ };
183
+ '''
184
+
185
+ # Convert input for the test
186
+ if isinstance(input_case, dict):
187
+ inputs = list(input_case.values())
188
+ else:
189
+ inputs = input_case
190
+
191
+ test_code = solution + helpers + f'''
192
+ try {{
193
+ let inputs = {json.dumps(inputs)};
194
+ let result = {func_name}(...inputs);
195
+ if (result && typeof result === 'object' && 'val' in result && 'next' in result) result = listToArray(result);
196
+ if (result && typeof result === 'object' && 'val' in result && 'left' in result) result = treeToArray(result);
197
+ console.log(JSON.stringify({{ success: true, result }}));
198
+ }} catch (e) {{
199
+ console.log(JSON.stringify({{ success: false, error: e.message }}));
200
+ }}
201
+ '''
202
+
203
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f:
204
+ f.write(test_code)
205
+ temp_file = f.name
206
+
207
+ try:
208
+ result = subprocess.run(['bun', 'run', temp_file], capture_output=True, text=True, timeout=5)
209
+ os.unlink(temp_file)
210
+ if result.returncode == 0 and result.stdout.strip():
211
+ data = json.loads(result.stdout.strip())
212
+ if data.get('success'):
213
+ return data.get('result')
214
+ return None
215
+ except:
216
+ if os.path.exists(temp_file):
217
+ os.unlink(temp_file)
218
+ return None
219
+
220
+
221
+ def add_specific_cases(problem_id):
222
+ """Add problem-specific edge cases."""
223
+ if problem_id not in PROBLEM_SPECIFIC_CASES:
224
+ return 0
225
+
226
+ # Get files
227
+ prob_files = list(PROBLEMS_DIR.glob(f"{problem_id}_*.json"))
228
+ sol_files = list(SOLUTIONS_DIR.glob(f"{problem_id}_*.js"))
229
+ tc_files = list(TESTCASES_DIR.glob(f"{problem_id}_*.json"))
230
+
231
+ if not all([prob_files, sol_files, tc_files]):
232
+ return 0
233
+
234
+ with open(prob_files[0]) as f:
235
+ prob_info = json.load(f)
236
+ func_name = prob_info.get('function_name', '')
237
+
238
+ with open(tc_files[0]) as f:
239
+ tc_data = json.load(f)
240
+
241
+ existing = tc_data.get('run_tests', []) + tc_data.get('submit_tests', [])
242
+ existing_inputs = {json.dumps(t.get('input'), sort_keys=True) for t in existing}
243
+
244
+ added = 0
245
+ for case in PROBLEM_SPECIFIC_CASES[problem_id]:
246
+ key = json.dumps(case, sort_keys=True)
247
+ if key in existing_inputs:
248
+ continue
249
+
250
+ expected = compute_expected(sol_files[0], func_name, case)
251
+ if expected is not None:
252
+ tc_data.setdefault('submit_tests', []).append({'input': case, 'expected': expected})
253
+ existing_inputs.add(key)
254
+ added += 1
255
+
256
+ if added > 0:
257
+ with open(tc_files[0], 'w') as f:
258
+ json.dump(tc_data, f, indent=2)
259
+
260
+ return added
261
+
262
+
263
+ def main():
264
+ total = 0
265
+ updated = 0
266
+
267
+ for prob_id in PROBLEM_SPECIFIC_CASES:
268
+ print(f"Processing {prob_id}...", end=' ', flush=True)
269
+ added = add_specific_cases(prob_id)
270
+ if added > 0:
271
+ print(f"Added {added} cases")
272
+ total += added
273
+ updated += 1
274
+ else:
275
+ print("No new cases")
276
+
277
+ print(f"\n{'='*60}")
278
+ print(f"Added {total} boundary/failure cases to {updated} problems")
279
+
280
+
281
+ if __name__ == '__main__':
282
+ main()