feat(frontend): big O complexity estimator
This commit is contained in:
200
frontend/src/lib/python-helpers.ts
Normal file
200
frontend/src/lib/python-helpers.ts
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* Python helper code and detection utilities for the test runner.
|
||||
*
|
||||
* This module provides Python code as string constants for data structure
|
||||
* classes, conversion functions, and utilities to detect problem types.
|
||||
*/
|
||||
|
||||
// =============================================================================
|
||||
// Data Structure Classes
|
||||
// =============================================================================
|
||||
|
||||
export const TREE_NODE_CLASS = `
|
||||
class TreeNode:
|
||||
def __init__(self, val=0, left=None, right=None):
|
||||
self.val = val
|
||||
self.left = left
|
||||
self.right = right
|
||||
`.trim();
|
||||
|
||||
export const LIST_NODE_CLASS = `
|
||||
class ListNode:
|
||||
def __init__(self, val=0, next=None):
|
||||
self.val = val
|
||||
self.next = next
|
||||
`.trim();
|
||||
|
||||
// =============================================================================
|
||||
// Conversion Functions
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Builds a binary tree from a level-order array representation.
|
||||
* Example: [1, 2, 3, null, 4] -> TreeNode(1, TreeNode(2, None, TreeNode(4)), TreeNode(3))
|
||||
*/
|
||||
export const BUILD_TREE = `
|
||||
def __build_tree(arr):
|
||||
if not arr or arr[0] is None:
|
||||
return None
|
||||
root = TreeNode(arr[0])
|
||||
queue = [root]
|
||||
i = 1
|
||||
while queue and i < len(arr):
|
||||
node = queue.pop(0)
|
||||
if i < len(arr) and arr[i] is not None:
|
||||
node.left = TreeNode(arr[i])
|
||||
queue.append(node.left)
|
||||
i += 1
|
||||
if i < len(arr) and arr[i] is not None:
|
||||
node.right = TreeNode(arr[i])
|
||||
queue.append(node.right)
|
||||
i += 1
|
||||
return root
|
||||
`.trim();
|
||||
|
||||
/**
|
||||
* Converts a binary tree to a level-order array representation.
|
||||
* Example: TreeNode(1, TreeNode(2), TreeNode(3)) -> [1, 2, 3]
|
||||
*/
|
||||
export const TREE_TO_ARRAY = `
|
||||
def __tree_to_array(root):
|
||||
if root is None:
|
||||
return []
|
||||
result = []
|
||||
queue = [root]
|
||||
while queue:
|
||||
node = queue.pop(0)
|
||||
if node is None:
|
||||
result.append(None)
|
||||
else:
|
||||
result.append(node.val)
|
||||
queue.append(node.left)
|
||||
queue.append(node.right)
|
||||
# Trim trailing nulls
|
||||
while result and result[-1] is None:
|
||||
result.pop()
|
||||
return result
|
||||
`.trim();
|
||||
|
||||
/**
|
||||
* Builds a linked list from an array.
|
||||
* Example: [1, 2, 3] -> ListNode(1, ListNode(2, ListNode(3)))
|
||||
*/
|
||||
export const BUILD_LIST = `
|
||||
def __build_list(arr):
|
||||
if not arr:
|
||||
return None
|
||||
head = ListNode(arr[0])
|
||||
current = head
|
||||
for val in arr[1:]:
|
||||
current.next = ListNode(val)
|
||||
current = current.next
|
||||
return head
|
||||
`.trim();
|
||||
|
||||
/**
|
||||
* Converts a linked list to an array.
|
||||
* Example: ListNode(1, ListNode(2, ListNode(3))) -> [1, 2, 3]
|
||||
*/
|
||||
export const LIST_TO_ARRAY = `
|
||||
def __list_to_array(head):
|
||||
result = []
|
||||
current = head
|
||||
while current:
|
||||
result.append(current.val)
|
||||
current = current.next
|
||||
return result
|
||||
`.trim();
|
||||
|
||||
// =============================================================================
|
||||
// Problem Type Detection
|
||||
// =============================================================================
|
||||
|
||||
/** Parameter names that indicate a tree-based problem */
|
||||
export const TREE_PARAMS = ["root", "tree", "p", "q"];
|
||||
|
||||
/** Parameter names that indicate a linked-list problem */
|
||||
export const LIST_PARAMS = ["head", "l1", "l2", "list1", "list2", "node"];
|
||||
|
||||
export type ProblemType = "simple" | "tree" | "linkedlist" | "class-based";
|
||||
|
||||
/**
|
||||
* Detects the problem type based on the function signature and input.
|
||||
*
|
||||
* @param signature - The function signature (e.g., "def two_sum(nums, target):")
|
||||
* @param input - The test case input object
|
||||
* @returns The detected problem type
|
||||
*/
|
||||
export function detectProblemType(
|
||||
signature: string,
|
||||
input: Record<string, unknown>
|
||||
): ProblemType {
|
||||
// Class-based: check if input has "operations" key
|
||||
if ("operations" in input) {
|
||||
return "class-based";
|
||||
}
|
||||
|
||||
// Check signature for type hints
|
||||
const hasTreeNode = signature.includes("TreeNode");
|
||||
const hasListNode = signature.includes("ListNode");
|
||||
|
||||
if (hasTreeNode) {
|
||||
return "tree";
|
||||
}
|
||||
|
||||
if (hasListNode) {
|
||||
return "linkedlist";
|
||||
}
|
||||
|
||||
// Check parameter names in signature and input keys
|
||||
const inputKeys = Object.keys(input);
|
||||
|
||||
const hasTreeParam =
|
||||
TREE_PARAMS.some((param) => signature.includes(param)) ||
|
||||
inputKeys.some((key) => TREE_PARAMS.includes(key));
|
||||
|
||||
const hasListParam =
|
||||
LIST_PARAMS.some((param) => signature.includes(param)) ||
|
||||
inputKeys.some((key) => LIST_PARAMS.includes(key));
|
||||
|
||||
if (hasTreeParam) {
|
||||
return "tree";
|
||||
}
|
||||
|
||||
if (hasListParam) {
|
||||
return "linkedlist";
|
||||
}
|
||||
|
||||
return "simple";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Python helper code needed for a given problem type.
|
||||
*/
|
||||
export function getPythonHelpers(problemType: ProblemType): string {
|
||||
switch (problemType) {
|
||||
case "tree":
|
||||
return [TREE_NODE_CLASS, BUILD_TREE, TREE_TO_ARRAY].join("\n\n");
|
||||
case "linkedlist":
|
||||
return [LIST_NODE_CLASS, BUILD_LIST, LIST_TO_ARRAY].join("\n\n");
|
||||
case "class-based":
|
||||
return ""; // Class-based problems define their own class
|
||||
case "simple":
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of parameter names that need tree conversion.
|
||||
*/
|
||||
export function getTreeParams(input: Record<string, unknown>): string[] {
|
||||
return Object.keys(input).filter((key) => TREE_PARAMS.includes(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of parameter names that need linked list conversion.
|
||||
*/
|
||||
export function getListParams(input: Record<string, unknown>): string[] {
|
||||
return Object.keys(input).filter((key) => LIST_PARAMS.includes(key));
|
||||
}
|
||||
Reference in New Issue
Block a user