diff --git a/bruno/local/Chunk/Execute Java Chunk.bru b/bruno/local/Chunk/Execute Java Chunk.bru new file mode 100644 index 0000000..ae92fd4 --- /dev/null +++ b/bruno/local/Chunk/Execute Java Chunk.bru @@ -0,0 +1,23 @@ +meta { + name: Execute Java Chunk + type: http + seq: 8 +} + +post { + url: http://localhost:3000/chunk/execute/22e04d50-3aea-43ac-9a89-32daea0cc9f8?lang=java + body: json + auth: none +} + +params:query { + lang: java +} + +body:json { + { + "snippets": { + "logic": "return x * y" + } + } +} diff --git a/bruno/local/Chunk/Get Random Chunks.bru b/bruno/local/Chunk/Get Random Chunks.bru index 879c693..d017533 100644 --- a/bruno/local/Chunk/Get Random Chunks.bru +++ b/bruno/local/Chunk/Get Random Chunks.bru @@ -5,12 +5,12 @@ meta { } get { - url: {{base_url}}/chunk/random + url: {{base_url}}/chunk/random?tags=JAV_ELVHALL&category=ELV-P5 body: none auth: none } params:query { - limit: 2 - lang: javascript + tags: JAV_ELVHALL + category: ELV-P5 } diff --git a/bruno/local/Problem/PATCH update problem title by ID.bru b/bruno/local/Problem/PATCH update problem title by ID.bru new file mode 100644 index 0000000..7dd675b --- /dev/null +++ b/bruno/local/Problem/PATCH update problem title by ID.bru @@ -0,0 +1,21 @@ +meta { + name: PATCH update problem title by ID + type: http + seq: 7 +} + +patch { + url: {{base_url}}/problem/2a3380b4-fbc7-517d-9583-01d41d1cbb80/title + body: json + auth: inherit +} + +body:json { + { + "title": "Multiply Two Numbers (2)" + } +} + +settings { + encodeUrl: true +} diff --git a/src/api/routes/problem_routes.py b/src/api/routes/problem_routes.py index a3fc977..6ae82e8 100644 --- a/src/api/routes/problem_routes.py +++ b/src/api/routes/problem_routes.py @@ -27,4 +27,9 @@ def add_test_cases(problem_id): @problem_bp.post('//testcases/import') def import_test_cases(problem_id): """ Import test cases from a ZIP file (Base: /problem//testcases/import)""" - return problem_handler.import_test_cases(problem_id) \ No newline at end of file + return problem_handler.import_test_cases(problem_id) + +@problem_bp.patch('//title') +def update_problem_title(problem_id): + """Update problem title (Base: /problem//title)""" + return problem_handler.update_problem_title(problem_id) \ No newline at end of file diff --git a/src/handlers/chunk_handler.py b/src/handlers/chunk_handler.py index ce3ffb8..f064701 100644 --- a/src/handlers/chunk_handler.py +++ b/src/handlers/chunk_handler.py @@ -23,6 +23,10 @@ def get_chunk(self, chunk_id): def get_random_chunks(self): limit = request.args.get('limit', default=1, type=int) lang = request.args.get('lang') + category = request.args.get('category') + tags = request.args.get('tags') + if tags: + tags = [tag.strip() for tag in tags.split(',')] - chunks = self.service.get_random_chunks(limit=limit, lang=lang) + chunks = self.service.get_random_chunks(limit=limit, lang=lang, tags=tags, category=category) return jsonify(status="success", data=chunks), 200 diff --git a/src/handlers/problem_handler.py b/src/handlers/problem_handler.py index f8fa7af..cb47ff6 100644 --- a/src/handlers/problem_handler.py +++ b/src/handlers/problem_handler.py @@ -43,6 +43,24 @@ def get_random_problem(self): if not problem: return jsonify(status="error", message="No problems found"), 404 return jsonify(status="success", data=problem), 200 + + def update_problem_title(self, problem_id): + """ Update problem title """ + if not request.is_json: + return jsonify(status='error', message='Request must be JSON'), 400 + + data = request.get_json() + new_title = data.get('title') + + if not new_title: + return jsonify(status='error', message='Title is required'), 400 + + new_title = new_title.strip() + result = self.problem_service.update_problem_title(problem_id, new_title) + + if result['status'] == 'error': + return jsonify(status='error', message=result.get('message')), 400 + return jsonify(status='success', data=result.get('data')), 200 def add_test_cases(self, problem_id): """ Add multiple test case """ diff --git a/src/openapi.yaml b/src/openapi.yaml index 53ae2fd..3870048 100644 --- a/src/openapi.yaml +++ b/src/openapi.yaml @@ -58,6 +58,35 @@ paths: '404': description: Problem not found + /problem/{problem_id}/title: + patch: + summary: Update problem title + parameters: + - name: problem_id + in: path + required: true + schema: + type: string + format: uuid + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [title] + properties: + title: + type: string + example: "Two Sum Updated" + responses: + '200': + description: Problem title updated successfully + '400': + description: Invalid request + '404': + description: Problem not found + /problem/{problem_id}/testcases: post: summary: Add test cases to a problem diff --git a/src/repositories/chunk_repository.py b/src/repositories/chunk_repository.py index 8e120e1..dfdd09f 100644 --- a/src/repositories/chunk_repository.py +++ b/src/repositories/chunk_repository.py @@ -78,20 +78,48 @@ def get_details(self, chunk_id, lang=None): return self._serialize_chunk(chunk, lang) - def find_random(self, limit=1, lang=None): - """Fetch random N chunks with their implementation details. Filters by language if provided.""" + def find_random(self, limit=1, lang=None, tags=None, category=None): + """Fetch random N chunks with their implementation details. Filters by language, tags, and category if provided.""" with self._get_session() as session: - statement = select(Chunk).order_by(func.random()) - # For simplicity, if lang is provided, we fetch more and filter in Python - # or just fetch all and filter. - results = session.exec(statement).all() + statement = select(Chunk).options( + joinedload(Chunk.templates).joinedload(ChunkTemplate.snippets), + joinedload(Chunk.tags), + joinedload(Chunk.categories) + ).order_by(func.random()) + + # If language is specified, filter chunks that HAVE at least one template in that language + if lang: + statement = statement.join(Chunk.templates).where(ChunkTemplate.language == lang) + + # If tags or category are specified, we might need more to filter in Python + if tags or category: + fetch_limit = limit * 20 # Fetch more to account for filtering + statement = statement.limit(fetch_limit) + else: + statement = statement.limit(limit * 2) # Some buffer + + results = session.exec(statement).unique().all() if not results: return [] chunks = [] for chunk in results: - if lang and lang not in chunk.config.get("templates", {}): + # Basic language check (redundant but safe) + if lang and lang not in [t.language for t in chunk.templates]: continue + + # Tag check + if tags: + chunk_tag_names = [t.name for t in chunk.tags] + if not all(tag in chunk_tag_names for tag in tags): + continue + + # Category check + if category: + chunk_category_names = [c.name for c in chunk.categories] + if category not in chunk_category_names: + continue + chunks.append(self._serialize_chunk(chunk, lang)) if len(chunks) >= limit: break diff --git a/src/repositories/problem_repository.py b/src/repositories/problem_repository.py index 084d292..050b533 100644 --- a/src/repositories/problem_repository.py +++ b/src/repositories/problem_repository.py @@ -76,3 +76,16 @@ def find_random(self, category_name=None, tag_name=None, limit=1): problems.append(p_dict) return problems + + def update_title_by_id(self, problem_id, new_title): + """ Update problem title """ + with self._get_session() as session: + problem = session.get(Problem, problem_id) + if not problem: + return {"status": "error", "message": "Problem not found"} + + problem.title = new_title + session.commit() + session.refresh(problem) + + return {"status": "success", "data": problem.model_dump(exclude={"config", "description"})} diff --git a/src/scripts/__init__.py b/src/scripts/__init__.py index 3210928..e69de29 100644 --- a/src/scripts/__init__.py +++ b/src/scripts/__init__.py @@ -1 +0,0 @@ -# This file makes the folder a Python package. diff --git a/src/scripts/data/java/elevatorhall/chunks.json b/src/scripts/data/java/elevatorhall/chunks.json new file mode 100644 index 0000000..c408967 --- /dev/null +++ b/src/scripts/data/java/elevatorhall/chunks.json @@ -0,0 +1,162 @@ +[ + { + "title": "ELV-P4-CHUNK-001", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// [NULL] stripped the exception handling from the ID scanner.\n// It now crashes on any non-integer input and floods the audit log with errors.\n// Restore the three blocks. Every scan must be logged, pass or fail.\n\npublic class CheckpointScanner {\n\n public static String parseStudentID(String input) {\n try {\n // TASK 1: Parse input. Return \"VALID:\" + id if 10000\u201399999, else \"INVALID:OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"scan attempt logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "12345", + "output": "VALID:12345" + } + }, + { + "title": "ELV-P4-CHUNK-002", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The room code scanner is throwing unhandled exceptions on every bad input.\n// [NULL] knew exactly which lines to delete to break the audit trail.\n// Restore all three exception blocks.\n\npublic class CheckpointScanner {\n\n public static String parseRoomCode(String input) {\n try {\n // TASK 1: Parse input. Return \"ROOM:\" + code if 100\u2013999, else \"INVALID:NOT_A_ROOM\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:FORMAT_ERROR\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"door scan logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "123", + "output": "ROOM:123" + } + }, + { + "title": "ELV-P4-CHUNK-003", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The port scanner crashes on anything that is not a clean integer.\n// Without proper exception handling the network audit trail is blind.\n// Restore it.\n\npublic class CheckpointScanner {\n\n public static String parsePort(String input) {\n try {\n // TASK 1: Parse input. Return \"PORT:\" + number if 1\u201365535, else \"INVALID:PORT_OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_PORT\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"connection attempt logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "80", + "output": "PORT:80" + } + }, + { + "title": "ELV-P4-CHUNK-004", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The elevator rejects every floor request because the parser throws on bad input.\n// [NULL] removed the safety net. Restore the exception blocks.\n// The finally block is not optional \u2014 the lift log must always write.\n\npublic class CheckpointScanner {\n\n public static String parseFloor(String input) {\n try {\n // TASK 1: Parse input. Return \"FLOOR:\" + number if 1\u201310, else \"INVALID:NO_SUCH_FLOOR\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"elevator request logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "5", + "output": "FLOOR:5" + } + }, + { + "title": "ELV-P5-CHUNK-001", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// 4,847 log entries. The threat filter is gone \u2014 [NULL] deleted it first.\n// Without it the emergency system cannot assess severity.\n// Find the threats. The building needs this report before it can act.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String analyzeLogs(ArrayList logs) {\n\n // TASK 1: Declare a counter and an ArrayList for threat descriptions.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"THREAT:\", increment and collect the description (after 8 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"THREATS:0|none\" if clean, else \"THREATS:\" + count + \"|\" + descriptions joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs1 = new ArrayList<>();\n logs1.add(\"INFO: door opened\");\n logs1.add(\"THREAT: brute force\");\n logs1.add(\"INFO: scan ok\");\n logs1.add(\"THREAT: port scan\");\n logs1.add(\"THREAT: login fail\");\n System.out.println(analyzeLogs(logs1));\n\n ArrayList logs2 = new ArrayList<>();\n logs2.add(\"INFO: all clear\");\n System.out.println(analyzeLogs(logs2));\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-002", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The server error filter was wiped along with the intrusion logs.\n// Critical errors are invisible to the monitoring system.\n// Restore the filter \u2014 find every ERROR entry and report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String filterErrors(ArrayList logs) {\n\n // TASK 1: Declare a counter and an ArrayList for error messages.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"ERROR:\", increment and collect the message (after 7 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"ERRORS:0|none\" if clean, else \"ERRORS:\" + count + \"|\" + messages joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs1 = new ArrayList<>();\n logs1.add(\"INFO: server started\");\n logs1.add(\"ERROR: disk full\");\n logs1.add(\"ERROR: null pointer\");\n logs1.add(\"INFO: backup ok\");\n System.out.println(filterErrors(logs1));\n\n ArrayList logs2 = new ArrayList<>();\n logs2.add(\"INFO: running\");\n System.out.println(filterErrors(logs2));\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-003", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The badge access log is full of denied entries \u2014 someone was probing every door.\n// The scanner that should have flagged them is offline.\n// Find every DENIED entry before [NULL] makes another move.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findDenied(ArrayList entries) {\n\n // TASK 1: Declare a counter and an ArrayList for denied entries.\n {{{snippet_1}}}\n\n for (String entry : entries) {\n // TASK 2: If entry contains \"DENIED\" anywhere, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"DENIED:0|none\" if none, else \"DENIED:\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList e1 = new ArrayList<>();\n e1.add(\"Student 001: GRANTED\");\n e1.add(\"Student 002: DENIED low clearance\");\n e1.add(\"Student 003: GRANTED\");\n e1.add(\"Visitor 01: DENIED no badge\");\n System.out.println(findDenied(e1));\n\n ArrayList e2 = new ArrayList<>();\n e2.add(\"Staff 001: GRANTED\");\n System.out.println(findDenied(e2));\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-004", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// Elevator requests are piling up but the floor filter is down.\n// Security needs to know exactly how many calls are going to each floor.\n// Restore the filter \u2014 match by floor number, report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findFloorRequests(ArrayList logs, int floor) {\n\n // TASK 1: Declare a counter and an ArrayList for matching requests.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry ends with \":\" + floor, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"FLOOR\" + floor + \":0|none\" if none,\n // else \"FLOOR\" + floor + \":\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs = new ArrayList<>();\n logs.add(\"User A requested floor:2\");\n logs.add(\"User B requested floor:3\");\n logs.add(\"User C requested floor:2\");\n logs.add(\"User D requested floor:1\");\n System.out.println(findFloorRequests(logs, 2));\n System.out.println(findFloorRequests(logs, 5));\n }\n}", + "snippets": { + "snippet_1": "None to be shown here", + "snippet_2": "None to be shown here", + "snippet_3": "None to be shown here" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + } +] \ No newline at end of file diff --git a/src/scripts/data/java/elevatorhall/problems.json b/src/scripts/data/java/elevatorhall/problems.json new file mode 100644 index 0000000..94be9ac --- /dev/null +++ b/src/scripts/data/java/elevatorhall/problems.json @@ -0,0 +1,403 @@ +[ + { + "title": "ELV-P1-PROB-001", + "description": "// [NULL] destroyed the auth daemon's recursive checksum.\n// Without a base case, every badge scan crashes the stack.\n// Restore it. The first fragment unlocks when it runs clean.\n\npublic class AuthDaemon {\n\n public static int hashPassword(String s) {\n // Recursively sum the ASCII value of each character.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(hashPassword(\"DOOR\"));\n System.out.println(hashPassword(\"KEY\"));\n System.out.println(hashPassword(\"\"));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P1", + "templates": { + "java": "// [NULL] destroyed the auth daemon's recursive checksum.\n// Without a base case, every badge scan crashes the stack.\n// Restore it. The first fragment unlocks when it runs clean.\n\npublic class AuthDaemon {\n\n public static int hashPassword(String s) {\n // Recursively sum the ASCII value of each character.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(hashPassword(\"DOOR\"));\n System.out.println(hashPassword(\"KEY\"));\n System.out.println(hashPassword(\"\"));\n }\n}" + }, + "test_cases": [ + { + "input": "\"DOOR\"", + "output": "289", + "is_hidden": false + }, + { + "input": "\"KEY\"", + "output": "236", + "is_hidden": true + }, + { + "input": "\"\"", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P1-PROB-002", + "description": "// The badge scanner counts security characters in access codes recursively.\n// [NULL] gutted the logic. Restore it before the auth layer rejects every card.\n\npublic class AuthDaemon {\n\n public static int countChar(String s, char target) {\n // Recursively count how many times target appears in s.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(countChar(\"ESCALATE\", 'E'));\n System.out.println(countChar(\"ACCESS\", 'S'));\n System.out.println(countChar(\"DOOR\", 'Z'));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P1", + "templates": { + "java": "// The badge scanner counts security characters in access codes recursively.\n// [NULL] gutted the logic. Restore it before the auth layer rejects every card.\n\npublic class AuthDaemon {\n\n public static int countChar(String s, char target) {\n // Recursively count how many times target appears in s.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(countChar(\"ESCALATE\", 'E'));\n System.out.println(countChar(\"ACCESS\", 'S'));\n System.out.println(countChar(\"DOOR\", 'Z'));\n }\n}" + }, + "test_cases": [ + { + "input": "\"ESCALATE\", 'E'", + "output": "2", + "is_hidden": false + }, + { + "input": "\"ACCESS\", 'S'", + "output": "2", + "is_hidden": true + }, + { + "input": "\"DOOR\", 'Z'", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P1-PROB-003", + "description": "// [NULL] reversed every exit label in the CCTV registry to cover their tracks.\n// This recursive function reverses them back. It is broken. Fix it.\n\npublic class AuthDaemon {\n\n public static String reverseCode(String s) {\n // Recursively reverse the string.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(reverseCode(\"TIXE\"));\n System.out.println(reverseCode(\"EDOC\"));\n System.out.println(reverseCode(\"\"));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P1", + "templates": { + "java": "// [NULL] reversed every exit label in the CCTV registry to cover their tracks.\n// This recursive function reverses them back. It is broken. Fix it.\n\npublic class AuthDaemon {\n\n public static String reverseCode(String s) {\n // Recursively reverse the string.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(reverseCode(\"TIXE\"));\n System.out.println(reverseCode(\"EDOC\"));\n System.out.println(reverseCode(\"\"));\n }\n}" + }, + "test_cases": [ + { + "input": "\"TIXE\"", + "output": "EXIT", + "is_hidden": false + }, + { + "input": "\"EDOC\"", + "output": "CODE", + "is_hidden": true + }, + { + "input": "\"\"", + "output": "", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P1-PROB-004", + "description": "// Floor access codes are validated by a recursive digit checksum.\n// The module is down. Restore it before the elevator rejects every request.\n\npublic class AuthDaemon {\n\n public static int sumDigits(int n) {\n // Recursively sum each digit of n.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(sumDigits(4821));\n System.out.println(sumDigits(9));\n System.out.println(sumDigits(0));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P1", + "templates": { + "java": "// Floor access codes are validated by a recursive digit checksum.\n// The module is down. Restore it before the elevator rejects every request.\n\npublic class AuthDaemon {\n\n public static int sumDigits(int n) {\n // Recursively sum each digit of n.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(sumDigits(4821));\n System.out.println(sumDigits(9));\n System.out.println(sumDigits(0));\n }\n}" + }, + "test_cases": [ + { + "input": "4821", + "output": "15", + "is_hidden": false + }, + { + "input": "9", + "output": "9", + "is_hidden": true + }, + { + "input": "0", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P2-PROB-001", + "description": "// The corridor heat sensor grid feeds into this machine.\n// [NULL] broke the scan function so it never flags anomalies.\n// Restore it, the security relay needs a clean threat report.\n\nimport java.util.ArrayList;\n\npublic class GridScanner {\n\n public static String findHotCells(int[][] grid) {\n ArrayList hits = new ArrayList<>();\n // Scan every cell. Flag readings above 80 as \"[row,col]=value\".\n // Return hits joined by \", \" or \"none\" if the grid is clean.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] grid = {\n {12, 45, 88, 23},\n {91, 34, 56, 77},\n {10, 82, 19, 95},\n {60, 55, 33, 84}\n };\n System.out.println(findHotCells(grid));\n\n int[][] grid2 = {{10, 20}, {30, 40}};\n System.out.println(findHotCells(grid2));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P2", + "templates": { + "java": "// The corridor heat sensor grid feeds into this machine.\n// [NULL] broke the scan function so it never flags anomalies.\n// Restore it, the security relay needs a clean threat report.\n\nimport java.util.ArrayList;\n\npublic class GridScanner {\n\n public static String findHotCells(int[][] grid) {\n ArrayList hits = new ArrayList<>();\n // Scan every cell. Flag readings above 80 as \"[row,col]=value\".\n // Return hits joined by \", \" or \"none\" if the grid is clean.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] grid = {\n {12, 45, 88, 23},\n {91, 34, 56, 77},\n {10, 82, 19, 95},\n {60, 55, 33, 84}\n };\n System.out.println(findHotCells(grid));\n\n int[][] grid2 = {{10, 20}, {30, 40}};\n System.out.println(findHotCells(grid2));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[0,2]=88, [1,0]=91, [2,1]=82, [2,3]=95, [3,3]=84", + "is_hidden": false + }, + { + "input": "", + "output": "none", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P2-PROB-002", + "description": "// [NULL] is hiding in wireless dead zones to avoid detection.\n// The signal map is a grid, find every cell below strength 10.\n// Expose the dead zones and the relay comes back online.\n\nimport java.util.ArrayList;\n\npublic class GridScanner {\n\n public static String findDeadZones(int[][] signal) {\n ArrayList hits = new ArrayList<>();\n // Flag every cell where signal strength is below 10 as \"[row,col]=value\".\n // Return hits joined by \", \" or \"none\" if coverage is full.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] signal = {\n {55, 3, 80, 7},\n {90, 42, 8, 60},\n { 5, 70, 33, 2}\n };\n System.out.println(findDeadZones(signal));\n\n int[][] signal2 = {{50, 60}, {70, 80}};\n System.out.println(findDeadZones(signal2));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P2", + "templates": { + "java": "// [NULL] is hiding in wireless dead zones to avoid detection.\n// The signal map is a grid, find every cell below strength 10.\n// Expose the dead zones and the relay comes back online.\n\nimport java.util.ArrayList;\n\npublic class GridScanner {\n\n public static String findDeadZones(int[][] signal) {\n ArrayList hits = new ArrayList<>();\n // Flag every cell where signal strength is below 10 as \"[row,col]=value\".\n // Return hits joined by \", \" or \"none\" if coverage is full.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] signal = {\n {55, 3, 80, 7},\n {90, 42, 8, 60},\n { 5, 70, 33, 2}\n };\n System.out.println(findDeadZones(signal));\n\n int[][] signal2 = {{50, 60}, {70, 80}};\n System.out.println(findDeadZones(signal2));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[0,1]=3, [0,3]=7, [1,2]=8, [2,0]=5, [2,3]=2", + "is_hidden": false + }, + { + "input": "", + "output": "none", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P2-PROB-003", + "description": "// Security needs a headcount to confirm the building is clear.\n// The attendance grid uses 1 for present, 0 for absent.\n// Count the occupied cells and report the total.\n\npublic class GridScanner {\n\n public static int countPresent(int[][] attendance) {\n // Count every cell equal to 1 and return the total.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] a = {\n {1, 0, 1, 1},\n {0, 0, 1, 0},\n {1, 1, 0, 1}\n };\n System.out.println(countPresent(a));\n\n int[][] b = {{0, 0}, {0, 0}};\n System.out.println(countPresent(b));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P2", + "templates": { + "java": "// Security needs a headcount to confirm the building is clear.\n// The attendance grid uses 1 for present, 0 for absent.\n// Count the occupied cells and report the total.\n\npublic class GridScanner {\n\n public static int countPresent(int[][] attendance) {\n // Count every cell equal to 1 and return the total.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] a = {\n {1, 0, 1, 1},\n {0, 0, 1, 0},\n {1, 1, 0, 1}\n };\n System.out.println(countPresent(a));\n\n int[][] b = {{0, 0}, {0, 0}};\n System.out.println(countPresent(b));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "6", + "is_hidden": false + }, + { + "input": "", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P2-PROB-004", + "description": "// One server rack is running [NULL]'s process and overheating the room.\n// Find the single hottest cell in the thermal grid.\n// Return its location and temperature, then we know where to cut power.\n\npublic class GridScanner {\n\n public static String findHotspot(int[][] temps) {\n // Find the cell with the maximum value. Return \"[row,col]=value\".\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] t = {\n {40, 72, 55},\n {88, 61, 47},\n {33, 95, 70}\n };\n System.out.println(findHotspot(t));\n\n int[][] t2 = {{10, 20}, {30, 25}};\n System.out.println(findHotspot(t2));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P2", + "templates": { + "java": "// One server rack is running [NULL]'s process and overheating the room.\n// Find the single hottest cell in the thermal grid.\n// Return its location and temperature, then we know where to cut power.\n\npublic class GridScanner {\n\n public static String findHotspot(int[][] temps) {\n // Find the cell with the maximum value. Return \"[row,col]=value\".\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[][] t = {\n {40, 72, 55},\n {88, 61, 47},\n {33, 95, 70}\n };\n System.out.println(findHotspot(t));\n\n int[][] t2 = {{10, 20}, {30, 25}};\n System.out.println(findHotspot(t2));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[2,1]=95", + "is_hidden": false + }, + { + "input": "", + "output": "[1,0]=30", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P3-PROB-001", + "description": "// [NULL] wiped both card subclasses from the clearance system.\n// Every card now returns UNKNOWN and every door stays locked.\n// The base class survived. Restore both card types from scratch.\n\npublic class ClearanceManager {\n\n static class AccessCard {\n protected String ownerName;\n protected int accessLevel;\n public AccessCard(String name, int level) {\n this.ownerName = name;\n this.accessLevel = level;\n }\n public String identify() {\n return \"CARD[\" + ownerName + \"] Level:\" + accessLevel;\n }\n }\n\n // TASK 1: StudentCard extends AccessCard. Level always 1. Appends \" [STUDENT]\".\n {TASK 1: STUDENT CARD}\n\n // TASK 2: StaffCard extends AccessCard. Level always 5. Appends \" [STAFF]\".\n {TASK 2: STAFF CARD}\n\n public static void main(String[] args) {\n AccessCard s = new StudentCard(\"Azri\");\n AccessCard t = new StaffCard(\"Dr.Lim\");\n System.out.println(s.identify());\n System.out.println(t.identify());\n System.out.println(s.accessLevel);\n System.out.println(t.accessLevel);\n }\n}", + "difficulty": "Hard", + "category": "ELV-P3", + "templates": { + "java": "// [NULL] wiped both card subclasses from the clearance system.\n// Every card now returns UNKNOWN and every door stays locked.\n// The base class survived. Restore both card types from scratch.\n\npublic class ClearanceManager {\n\n static class AccessCard {\n protected String ownerName;\n protected int accessLevel;\n public AccessCard(String name, int level) {\n this.ownerName = name;\n this.accessLevel = level;\n }\n public String identify() {\n return \"CARD[\" + ownerName + \"] Level:\" + accessLevel;\n }\n }\n\n // TASK 1: StudentCard extends AccessCard. Level always 1. Appends \" [STUDENT]\".\n {TASK 1: STUDENT CARD}\n\n // TASK 2: StaffCard extends AccessCard. Level always 5. Appends \" [STAFF]\".\n {TASK 2: STAFF CARD}\n\n public static void main(String[] args) {\n AccessCard s = new StudentCard(\"Azri\");\n AccessCard t = new StaffCard(\"Dr.Lim\");\n System.out.println(s.identify());\n System.out.println(t.identify());\n System.out.println(s.accessLevel);\n System.out.println(t.accessLevel);\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "CARD[Azri] Level:1 [STUDENT]", + "is_hidden": false + }, + { + "input": "", + "output": "CARD[Dr.Lim] Level:5 [STAFF]", + "is_hidden": true + }, + { + "input": "", + "output": "1", + "is_hidden": true + }, + { + "input": "", + "output": "5", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P3-PROB-002", + "description": "// The alert system cannot classify severity anymore \u2014 [NULL] deleted the subclasses.\n// Minor and critical alerts both come back blank. Restore both types.\n\npublic class ClearanceManager {\n\n static class SystemAlert {\n protected String message;\n protected int severity;\n public SystemAlert(String message, int severity) {\n this.message = message;\n this.severity = severity;\n }\n public String describe() {\n return \"ALERT[\" + message + \"] Sev:\" + severity;\n }\n }\n\n // TASK 1: MinorAlert extends SystemAlert. Severity always 1. Appends \" [MINOR]\".\n {TASK 1: MINOR ALERT}\n\n // TASK 2: CriticalAlert extends SystemAlert. Severity always 9. Appends \" [CRITICAL]\".\n {TASK 2: CRITICAL ALERT}\n\n public static void main(String[] args) {\n SystemAlert a = new MinorAlert(\"door left open\");\n SystemAlert b = new CriticalAlert(\"server breach\");\n System.out.println(a.describe());\n System.out.println(b.describe());\n System.out.println(a.severity);\n System.out.println(b.severity);\n }\n}", + "difficulty": "Hard", + "category": "ELV-P3", + "templates": { + "java": "// The alert system cannot classify severity anymore \u2014 [NULL] deleted the subclasses.\n// Minor and critical alerts both come back blank. Restore both types.\n\npublic class ClearanceManager {\n\n static class SystemAlert {\n protected String message;\n protected int severity;\n public SystemAlert(String message, int severity) {\n this.message = message;\n this.severity = severity;\n }\n public String describe() {\n return \"ALERT[\" + message + \"] Sev:\" + severity;\n }\n }\n\n // TASK 1: MinorAlert extends SystemAlert. Severity always 1. Appends \" [MINOR]\".\n {TASK 1: MINOR ALERT}\n\n // TASK 2: CriticalAlert extends SystemAlert. Severity always 9. Appends \" [CRITICAL]\".\n {TASK 2: CRITICAL ALERT}\n\n public static void main(String[] args) {\n SystemAlert a = new MinorAlert(\"door left open\");\n SystemAlert b = new CriticalAlert(\"server breach\");\n System.out.println(a.describe());\n System.out.println(b.describe());\n System.out.println(a.severity);\n System.out.println(b.severity);\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "ALERT[door left open] Sev:1 [MINOR]", + "is_hidden": false + }, + { + "input": "", + "output": "ALERT[server breach] Sev:9 [CRITICAL]", + "is_hidden": true + }, + { + "input": "", + "output": "1", + "is_hidden": true + }, + { + "input": "", + "output": "9", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P3-PROB-003", + "description": "// The network device registry lost both its concrete types.\n// Wired and wireless devices both report as unknown hardware.\n// Restore them so the building network can come back online.\n\npublic class ClearanceManager {\n\n static class NetworkDevice {\n protected String id;\n protected int bandwidth;\n public NetworkDevice(String id, int bandwidth) {\n this.id = id;\n this.bandwidth = bandwidth;\n }\n public String report() {\n return \"DEV[\" + id + \"] BW:\" + bandwidth;\n }\n }\n\n // TASK 1: WiredDevice extends NetworkDevice. Bandwidth always 1000. Appends \" [WIRED]\".\n {TASK 1: WIRED DEVICE}\n\n // TASK 2: WirelessDevice extends NetworkDevice. Bandwidth always 300. Appends \" [WIRELESS]\".\n {TASK 2: WIRELESS DEVICE}\n\n public static void main(String[] args) {\n NetworkDevice w = new WiredDevice(\"ETH-01\");\n NetworkDevice x = new WirelessDevice(\"WIFI-02\");\n System.out.println(w.report());\n System.out.println(x.report());\n System.out.println(w.bandwidth);\n System.out.println(x.bandwidth);\n }\n}", + "difficulty": "Hard", + "category": "ELV-P3", + "templates": { + "java": "// The network device registry lost both its concrete types.\n// Wired and wireless devices both report as unknown hardware.\n// Restore them so the building network can come back online.\n\npublic class ClearanceManager {\n\n static class NetworkDevice {\n protected String id;\n protected int bandwidth;\n public NetworkDevice(String id, int bandwidth) {\n this.id = id;\n this.bandwidth = bandwidth;\n }\n public String report() {\n return \"DEV[\" + id + \"] BW:\" + bandwidth;\n }\n }\n\n // TASK 1: WiredDevice extends NetworkDevice. Bandwidth always 1000. Appends \" [WIRED]\".\n {TASK 1: WIRED DEVICE}\n\n // TASK 2: WirelessDevice extends NetworkDevice. Bandwidth always 300. Appends \" [WIRELESS]\".\n {TASK 2: WIRELESS DEVICE}\n\n public static void main(String[] args) {\n NetworkDevice w = new WiredDevice(\"ETH-01\");\n NetworkDevice x = new WirelessDevice(\"WIFI-02\");\n System.out.println(w.report());\n System.out.println(x.report());\n System.out.println(w.bandwidth);\n System.out.println(x.bandwidth);\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "DEV[ETH-01] BW:1000 [WIRED]", + "is_hidden": false + }, + { + "input": "", + "output": "DEV[WIFI-02] BW:300 [WIRELESS]", + "is_hidden": true + }, + { + "input": "", + "output": "1000", + "is_hidden": true + }, + { + "input": "", + "output": "300", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P3-PROB-004", + "description": "// Lab equipment tagging is broken \u2014 safe and hazardous items look identical.\n// [NULL] deleted both subclasses. One wrong label and the evacuation fails.\n// Restore them.\n\npublic class ClearanceManager {\n\n static class LabItem {\n protected String code;\n protected int riskLevel;\n public LabItem(String code, int riskLevel) {\n this.code = code;\n this.riskLevel = riskLevel;\n }\n public String label() {\n return \"ITEM[\" + code + \"] Risk:\" + riskLevel;\n }\n }\n\n // TASK 1: SafeEquipment extends LabItem. RiskLevel always 1. Appends \" [SAFE]\".\n {TASK 1: SAFE EQUIPMENT}\n\n // TASK 2: HazardEquipment extends LabItem. RiskLevel always 5. Appends \" [HAZARD]\".\n {TASK 2: HAZARD EQUIPMENT}\n\n public static void main(String[] args) {\n LabItem s = new SafeEquipment(\"CHAIR-04\");\n LabItem h = new HazardEquipment(\"LASER-09\");\n System.out.println(s.label());\n System.out.println(h.label());\n System.out.println(s.riskLevel);\n System.out.println(h.riskLevel);\n }\n}", + "difficulty": "Hard", + "category": "ELV-P3", + "templates": { + "java": "// Lab equipment tagging is broken \u2014 safe and hazardous items look identical.\n// [NULL] deleted both subclasses. One wrong label and the evacuation fails.\n// Restore them.\n\npublic class ClearanceManager {\n\n static class LabItem {\n protected String code;\n protected int riskLevel;\n public LabItem(String code, int riskLevel) {\n this.code = code;\n this.riskLevel = riskLevel;\n }\n public String label() {\n return \"ITEM[\" + code + \"] Risk:\" + riskLevel;\n }\n }\n\n // TASK 1: SafeEquipment extends LabItem. RiskLevel always 1. Appends \" [SAFE]\".\n {TASK 1: SAFE EQUIPMENT}\n\n // TASK 2: HazardEquipment extends LabItem. RiskLevel always 5. Appends \" [HAZARD]\".\n {TASK 2: HAZARD EQUIPMENT}\n\n public static void main(String[] args) {\n LabItem s = new SafeEquipment(\"CHAIR-04\");\n LabItem h = new HazardEquipment(\"LASER-09\");\n System.out.println(s.label());\n System.out.println(h.label());\n System.out.println(s.riskLevel);\n System.out.println(h.riskLevel);\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "ITEM[CHAIR-04] Risk:1 [SAFE]", + "is_hidden": false + }, + { + "input": "", + "output": "ITEM[LASER-09] Risk:5 [HAZARD]", + "is_hidden": true + }, + { + "input": "", + "output": "1", + "is_hidden": true + }, + { + "input": "", + "output": "5", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P6-PROB-001", + "description": "// The elevator queue manager is down \u2014 [NULL] wiped the sort logic.\n// The lift now skips floors at random. You are one floor from the exit.\n// Sort the queue manually. Get it moving in the right order.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortFloors(int[] floors) {\n int n = floors.length;\n // Sort floors ascending in place. No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {4, 1, 3, 2, 5};\n sortFloors(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {9, 2, 7, 1};\n sortFloors(b);\n System.out.println(Arrays.toString(b));\n\n int[] c = {3, 3, 1};\n sortFloors(c);\n System.out.println(Arrays.toString(c));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P6", + "templates": { + "java": "// The elevator queue manager is down \u2014 [NULL] wiped the sort logic.\n// The lift now skips floors at random. You are one floor from the exit.\n// Sort the queue manually. Get it moving in the right order.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortFloors(int[] floors) {\n int n = floors.length;\n // Sort floors ascending in place. No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {4, 1, 3, 2, 5};\n sortFloors(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {9, 2, 7, 1};\n sortFloors(b);\n System.out.println(Arrays.toString(b));\n\n int[] c = {3, 3, 1};\n sortFloors(c);\n System.out.println(Arrays.toString(c));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[1, 2, 3, 4, 5]", + "is_hidden": false + }, + { + "input": "", + "output": "[1, 2, 7, 9]", + "is_hidden": true + }, + { + "input": "", + "output": "[1, 3, 3]", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P6-PROB-002", + "description": "// Critical floors need service first \u2014 highest priority number wins.\n// The priority sorter is gone. The lift is serving the wrong floors first.\n// Restore the sort. Descending order. No library methods.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortByPriority(int[] priorities) {\n int n = priorities.length;\n // Sort priorities descending in place. No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {3, 1, 4, 2};\n sortByPriority(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {5, 5, 2, 8};\n sortByPriority(b);\n System.out.println(Arrays.toString(b));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P6", + "templates": { + "java": "// Critical floors need service first \u2014 highest priority number wins.\n// The priority sorter is gone. The lift is serving the wrong floors first.\n// Restore the sort. Descending order. No library methods.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortByPriority(int[] priorities) {\n int n = priorities.length;\n // Sort priorities descending in place. No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {3, 1, 4, 2};\n sortByPriority(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {5, 5, 2, 8};\n sortByPriority(b);\n System.out.println(Arrays.toString(b));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[4, 3, 2, 1]", + "is_hidden": false + }, + { + "input": "", + "output": "[8, 5, 5, 2]", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P6-PROB-003", + "description": "// Lab booking slots include duplicates \u2014 multiple people queued for the same floor.\n// The sorter has to handle that cleanly. [NULL] knew it wouldn't.\n// Fix it. Handle the duplicates. Get the queue sorted.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortSlots(int[] slots) {\n int n = slots.length;\n // Sort slots ascending in place. Duplicates must be handled correctly.\n // No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {3, 1, 3, 2, 1};\n sortSlots(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {7, 7, 7};\n sortSlots(b);\n System.out.println(Arrays.toString(b));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P6", + "templates": { + "java": "// Lab booking slots include duplicates \u2014 multiple people queued for the same floor.\n// The sorter has to handle that cleanly. [NULL] knew it wouldn't.\n// Fix it. Handle the duplicates. Get the queue sorted.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static void sortSlots(int[] slots) {\n int n = slots.length;\n // Sort slots ascending in place. Duplicates must be handled correctly.\n // No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n int[] a = {3, 1, 3, 2, 1};\n sortSlots(a);\n System.out.println(Arrays.toString(a));\n\n int[] b = {7, 7, 7};\n sortSlots(b);\n System.out.println(Arrays.toString(b));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[1, 1, 2, 3, 3]", + "is_hidden": false + }, + { + "input": "", + "output": "[7, 7, 7]", + "is_hidden": true + } + ] + }, + { + "title": "ELV-P6-PROB-004", + "description": "// The emergency system needs the three highest-risk floor scores to prioritise response.\n// Sort the scores yourself, then return the top three in a new array.\n// No shortcuts. Write the algorithm from scratch.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static int[] topThreeScores(int[] scores) {\n int n = scores.length;\n // Sort scores, then return a new int[] containing only the top 3 values.\n // No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(Arrays.toString(topThreeScores(new int[]{88, 55, 72, 91, 60})));\n System.out.println(Arrays.toString(topThreeScores(new int[]{100, 50, 75})));\n }\n}", + "difficulty": "Hard", + "category": "ELV-P6", + "templates": { + "java": "// The emergency system needs the three highest-risk floor scores to prioritise response.\n// Sort the scores yourself, then return the top three in a new array.\n// No shortcuts. Write the algorithm from scratch.\n\nimport java.util.Arrays;\n\npublic class ElevatorQueue {\n\n public static int[] topThreeScores(int[] scores) {\n int n = scores.length;\n // Sort scores, then return a new int[] containing only the top 3 values.\n // No Arrays.sort() or library sort allowed.\n {PLAYER CODE}\n }\n\n public static void main(String[] args) {\n System.out.println(Arrays.toString(topThreeScores(new int[]{88, 55, 72, 91, 60})));\n System.out.println(Arrays.toString(topThreeScores(new int[]{100, 50, 75})));\n }\n}" + }, + "test_cases": [ + { + "input": "", + "output": "[91, 88, 72]", + "is_hidden": false + }, + { + "input": "", + "output": "[100, 75, 50]", + "is_hidden": true + } + ] + } +] \ No newline at end of file diff --git a/src/scripts/data/java/hallway/chunks.json b/src/scripts/data/java/hallway/chunks.json index e69de29..e62a23d 100644 --- a/src/scripts/data/java/hallway/chunks.json +++ b/src/scripts/data/java/hallway/chunks.json @@ -0,0 +1,102 @@ +[ + { + "title": "HLW-CHUNK-001", + "difficulty": "Hard", + "category": "HLW_P001", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n int core_temp = scanner.hasNextInt() ? scanner.nextInt() : 0;\n int access_code = scanner.hasNextInt() ? scanner.nextInt() : 0;\n String main_grid = scanner.hasNext() ? scanner.next() : \"\";\n int battery_level = scanner.hasNextInt() ? scanner.nextInt() : 0;\n \n boolean coolant = false;\n String vault_door = \"LOCKED\";\n String backup_power = \"OFF\";\n\n //TASK 1: COOLING LOGIC\n{{{snippet_1}}}\n coolant = true;\n}\n//TASK 2: VAULT ACCESS\n{{{snippet_2}}}\n vault_door = \"OPEN\";\n}\n//TASK 3: POWER FAILSAFE (ADVANCED)\n{{{snippet_3}}}\n backup_power = \"ON\";\n}\n \n System.out.print(coolant + \"|\" + vault_door + \"|\" + backup_power);\n }\n}", + "snippets": { + "snippet_1": "Safety Protocol: The cooling system must activate (coolant = true) only if the core_temp reaches or exceeds 90.", + "snippet_2": "Security Override: The room_321_door should remain LOCKED unless the access_code provided is exactly 7734.", + "snippet_3": "Power Management: Emergency backup_power must be ON if the main_grid is OFF AND the battery_level is below 20." + } + } + }, + "expectation": { + "input": "95\n7734\nOFF\n15", + "output": "true|OPEN|ON" + } + }, + { + "title": "HLW-CHUNK-002", + "difficulty": "Hard", + "category": "HLW_P001", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n int core_temp = scanner.hasNextInt() ? scanner.nextInt() : 0;\n int access_code = scanner.hasNextInt() ? scanner.nextInt() : 0;\n String main_grid = scanner.hasNext() ? scanner.next() : \"\";\n int battery_level = scanner.hasNextInt() ? scanner.nextInt() : 0;\n \n boolean coolant = false;\n String vault_door = \"LOCKED\";\n String backup_power = \"OFF\";\n\n //TASK 1: GATEWAY OVERRIDE\n {{{snippet_1}}}\ngateway = \"OPEN\";\n}\n//TASK 2: PACKET FILTER\n {{{snippet_2}}}\ndrop_packet = true;\n}\n//TASK 3: SSL HANDSHAKE\n {{{snippet_3}}}\nsecure_connection = true;\n}\n \n System.out.print(coolant + \"|\" + vault_door + \"|\" + backup_power);\n }\n}", + "snippets": { + "snippet_1": "Gateway Override: The gateway will only open if the incoming ip_address is exactly \"192.168.1.1\"", + "snippet_2": "Packet Filter: Packet should be dropped if port is 80 and protocol is UDP", + "snippet_3": "SSL Handshake: Only create connection when the cert expiration date is over 2026" + } + } + }, + "expectation": { + "input": "95\n7734\nOFF\n15", + "output": "true|OPEN|ON" + } + }, + { + "title": "HLW-CHUNK-003", + "difficulty": "Hard", + "category": "HLW_P001", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n int core_temp = scanner.hasNextInt() ? scanner.nextInt() : 0;\n int access_code = scanner.hasNextInt() ? scanner.nextInt() : 0;\n String main_grid = scanner.hasNext() ? scanner.next() : \"\";\n int battery_level = scanner.hasNextInt() ? scanner.nextInt() : 0;\n \n boolean coolant = false;\n String vault_door = \"LOCKED\";\n String backup_power = \"OFF\";\n\n // TASK 1: AI OUTPUT SANITIZATION\n{{{snippet_1}}}\n ai_output = \"CONTAINED\";\n}\n// TASK 2: CONTAINMENT FIELD LOGIC\n{{{snippet_2}}}\n containment_field = \"ACTIVE\";\n}\n// TASK 3: ENCRYPTION CHECK (ADVANCED)\n{{{snippet_3}}}\n access_granted = true;\n}\n \n System.out.print(coolant + \"|\" + vault_door + \"|\" + backup_power);\n }\n}", + "snippets": { + "snippet_1": "Output Sanitization: If the ai_response_string is a \"CRITICAL ERROR\", the output must be set to \"CONTAINED\".", + "snippet_2": "Field Logic: The containment_field must be set to \"ACTIVE\" if the core_stability drops below 0.2 AND the core_temperature is over 500 degrees.", + "snippet_3": "Advanced Protocol: Access is granted (access_granted = true) only if the provided encryption_type is exactly \"RSA\" OR exactly \"AES\"." + } + } + }, + "expectation": { + "input": "95\n7734\nOFF\n15", + "output": "true|OPEN|ON" + } + }, + { + "title": "HLW-CHUNK-004", + "difficulty": "Hard", + "category": "HLW_P001", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n int core_temp = scanner.hasNextInt() ? scanner.nextInt() : 0;\n int access_code = scanner.hasNextInt() ? scanner.nextInt() : 0;\n String main_grid = scanner.hasNext() ? scanner.next() : \"\";\n int battery_level = scanner.hasNextInt() ? scanner.nextInt() : 0;\n \n boolean coolant = false;\n String vault_door = \"LOCKED\";\n String backup_power = \"OFF\";\n\n //TASK 1: OXYGEN RECLAMATION\n{{{snippet_1}}}\nscrubber_status = \"MAX\";\n}\n//TASK 2: THERMAL REGULATION\n{{{snippet_2}}}\nheater = \"ON\";\n}\n//TASK 3: WATER FILTRATION (ADVANCED)\n{{{snippet_3}}}\nflush_filter = true;\n}\n \n System.out.print(coolant + \"|\" + vault_door + \"|\" + backup_power);\n }\n}", + "snippets": { + "snippet_1": "Atmospheric Safety: If the co2_level exceeds 0.05, the carbon scrubbers must be set to \"MAX\".", + "snippet_2": "Thermal regulation: The heater should be on when the ambient temp is lower than 18", + "snippet_3": "Maintenance Cycle: The filter must flush (true) only if the pressure (psi) is 60 or higher AND turbidity is above 5." + } + } + }, + "expectation": { + "input": "95\n7734\nOFF\n15", + "output": "true|OPEN|ON" + } + }, + { + "title": "HLW-CHUNK-005", + "difficulty": "Hard", + "category": "HLW_P001", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n int core_temp = scanner.hasNextInt() ? scanner.nextInt() : 0;\n int access_code = scanner.hasNextInt() ? scanner.nextInt() : 0;\n String main_grid = scanner.hasNext() ? scanner.next() : \"\";\n int battery_level = scanner.hasNextInt() ? scanner.nextInt() : 0;\n \n boolean coolant = false;\n String vault_door = \"LOCKED\";\n String backup_power = \"OFF\";\n\n //TASK 1: PERIMETER SCAN\n{{{snippet_1}}}\nalarm_siren = true;\n}\n//TASK 2: TURRET CALIBRATION\n{{{snippet_2}}}\ntarget_lock = \"LOCKED\";\n}\n//TASK 3: BIOMETRIC OVERRIDE\n{{{snippet_3}}}\ngate_bypass = true;\n}\n \n System.out.print(coolant + \"|\" + vault_door + \"|\" + backup_power);\n }\n}", + "snippets": { + "snippet_1": "Intruder Alert: Sound the alarm only if motion_detected is true AND the target is NOT authorized.", + "snippet_2": "Targeting System: The target_lock should engage if the distance is 500 or less and visibility is \"CLEAR\".", + "snippet_3": "Biometric Override: If the admin key is exactly 99, the gate bypass should be activated." + } + } + }, + "expectation": { + "input": "95\n7734\nOFF\n15", + "output": "true|OPEN|ON" + } + } +] \ No newline at end of file diff --git a/src/scripts/data/java/hallway/problems.json b/src/scripts/data/java/hallway/problems.json index e69de29..04f348c 100644 --- a/src/scripts/data/java/hallway/problems.json +++ b/src/scripts/data/java/hallway/problems.json @@ -0,0 +1,470 @@ +[ + { + "title": "HLW-001: Bad news", + "description": "AUTHOR: Anonymous\n\nBad news. The security daemon doesn't just use a static shelf number anymore. It rotates the physical bypass tunnel every 24 hours based on the server's daily diagnostic logs.\n\nI intercepted the interface architecture. You need to write a class named ShelfOverride that implements the ShelfController interface.\n\nThe system will pass an array of integers into your method. The correct shelf number is the total count of diagnostic codes in that array that are BOTH strictly greater than 100 AND a multiple of 3.\n\nYOUR TARGET:\n\nImplement: ShelfController\n\nRequired Method: public int getTargetShelf(int[] diagnostics)\n\nWrite the loop. Filter the array. Return the final count.\n\nWarning: Do not write an infinite loop. The server will time out, flag this terminal, and lock us out forever.", + "difficulty": "Hard", + "category": "HLW_P004", + "templates": { + "java": "class ShelfOverride {\n public int getTargetShelf(int[] diagnostics) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[102, 105, 108]", + "output": "3", + "is_hidden": false + }, + { + "input": "[99, 100, 101]", + "output": "0", + "is_hidden": true + }, + { + "input": "[300, 200, 102]", + "output": "2", + "is_hidden": true + }, + { + "input": "[]", + "output": "0", + "is_hidden": true + }, + { + "input": "[103, 106, 110, 111]", + "output": "2", + "is_hidden": true + } + ] + }, + { + "title": "HLW-002: The encrypted gatekeeper is monitoring heat sig...", + "description": "AUTHOR: Ghost_Protocol\n\nThe encrypted gatekeeper is monitoring heat signatures. To bypass the thermal lock, you need to identify \"critical spikes.\"\n\nWrite a class ThermalBypass that implements SensorArray. Iterate through the input array and count how many values are negative OR above 500.\n\nTARGET:\n\nImplement: SensorArray\n\nMethod: public int countSpikes(int[] heat)", + "difficulty": "Hard", + "category": "HLW_P004", + "templates": { + "java": "class ThermalBypass {\n public int countSpikes(int[] heat) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[-1, 501, 100]", + "output": "2", + "is_hidden": false + }, + { + "input": "[0, 500, 499]", + "output": "0", + "is_hidden": true + }, + { + "input": "[-10, -20, 600, 700]", + "output": "4", + "is_hidden": true + }, + { + "input": "[]", + "output": "0", + "is_hidden": true + }, + { + "input": "[1, 2, 3]", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "HLW-003: We\u2019re intercepting a packet stream", + "description": "AUTHOR: NullPointer\n\n\n\nWe\u2019re intercepting a packet stream. The bridge will only open if we provide the sum of all \"parity-aligned\" IDs.\n\n\n\nImplement BridgeProtocol. Your method must sum all even numbers in the array. If the array is empty, return 0.\n\n\n\nTARGET:\n\n\nImplement: BridgeProtocol\n\n\nMethod: public int getParitySum(int[] ids)", + "difficulty": "Hard", + "category": "HLW_P004", + "templates": { + "java": "class BridgeProtocol {\n public int getParitySum(int[] ids) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[2, 4, 6]", + "output": "12", + "is_hidden": false + }, + { + "input": "[1, 3, 5]", + "output": "0", + "is_hidden": true + }, + { + "input": "[10, 11, 12]", + "output": "22", + "is_hidden": true + }, + { + "input": "[]", + "output": "0", + "is_hidden": true + }, + { + "input": "[-2, 2, 0]", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "HLW-004: The vault uses a \"Range-Lock\" mechanism", + "description": "AUTHOR: Anonymous\n\n\n\nThe vault uses a \"Range-Lock\" mechanism. We need to verify if the server's sequence contains at least three values within the \"Safe Zone\" (between 10 and 20 inclusive).\n\n\n\nImplement VaultUnlocker. Return true if the count of valid numbers is 3 or more, otherwise return false.\n\n\n\nTARGET:\n\n\nImplement: VaultUnlocker\n\n\nMethod: public boolean isSafe(int[] seq)", + "difficulty": "Hard", + "category": "HLW_P004", + "templates": { + "java": "class VaultUnlocker {\n public boolean isSafe(int[] seq) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[10, 15, 20]", + "output": "true", + "is_hidden": false + }, + { + "input": "[10, 15, 9]", + "output": "false", + "is_hidden": true + }, + { + "input": "[10, 20, 11, 12]", + "output": "true", + "is_hidden": true + }, + { + "input": "[]", + "output": "false", + "is_hidden": true + }, + { + "input": "[21, 22, 23, 24, 25]", + "output": "false", + "is_hidden": true + } + ] + }, + { + "title": "HLW-005: The watchdog timer is scanning for anomalies", + "description": "AUTHOR: Root_Access\n\n\n\nThe watchdog timer is scanning for anomalies. An anomaly is any value that is exactly double the value of the number immediately preceding it in the array.\n\n\n\nImplement WatchdogBypass. Return the total count of these anomalies. Start your check from the second element.\n\n\n\nTARGET:\n\n\nImplement: WatchdogBypass\n\n\nMethod: public int findAnomalies(int[] stream)", + "difficulty": "Hard", + "category": "HLW_P004", + "templates": { + "java": "class WatchdogBypass {\n public int findAnomalies(int[] stream) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[1, 2, 4]", + "output": "2", + "is_hidden": false + }, + { + "input": "[1, 3, 6]", + "output": "1", + "is_hidden": true + }, + { + "input": "[10, 20, 30, 60]", + "output": "2", + "is_hidden": true + }, + { + "input": "[]", + "output": "0", + "is_hidden": true + }, + { + "input": "[100]", + "output": "0", + "is_hidden": true + } + ] + }, + { + "title": "HLW-006: Security Protocol is failing to compile", + "description": "Security Protocol is failing to compile. The security protocol uses the Decryptor interface, but the Clue class is missing the required method to unlock it.\n\nTARGET: Write the missing method. The interface requires getShiftKey() to return an integer of the bypass shift key. The bypass shift key for this node is the amount of bookshelves added to the amount of student's desk.", + "difficulty": "Hard", + "category": "HLW_P005", + "templates": { + "java": "class Clue {\n public int getShiftKey() {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "dummy_0", + "output": "STATUS: PASSED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": false + }, + { + "input": "dummy_1", + "output": "STATUS: PASSED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_2", + "output": "STATUS: PASSED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_3", + "output": "STATUS: PASSED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_4", + "output": "STATUS: PASSED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + } + ] + }, + { + "title": "HLW-007: The server room is overheating", + "description": "The server room is overheating. The CoolantSystem interface requires a getTemperatureThreshold() method to initiate the purge.\n\n\n\nTARGET: Calculate the threshold by adding the roomCount (12) to the serverDensity (14).", + "difficulty": "Hard", + "category": "HLW_P005", + "templates": { + "java": "class PurgeUnit {\n public int getTemperatureThreshold() {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "dummy_0", + "output": "STATUS: PURGING\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": false + }, + { + "input": "dummy_1", + "output": "STATUS: PURGING\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_2", + "output": "STATUS: PURGING\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_3", + "output": "STATUS: PURGING\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_4", + "output": "STATUS: PURGING\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + } + ] + }, + { + "title": "HLW-008: The satellite dish is misaligned", + "description": "The satellite dish is misaligned. The Uplink interface requires a getSignalFrequency() method to lock onto the DevScape core.\n\n\n\nTARGET: Calculate the frequency by multiplying the dishRotation (45) by the amplifierGain (2).", + "difficulty": "Hard", + "category": "HLW_P005", + "templates": { + "java": "class SatelliteDish {\n public int getSignalFrequency() {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "dummy_0", + "output": "STATUS: CONNECTED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": false + }, + { + "input": "dummy_1", + "output": "STATUS: CONNECTED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_2", + "output": "STATUS: CONNECTED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_3", + "output": "STATUS: CONNECTED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_4", + "output": "STATUS: CONNECTED\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + } + ] + }, + { + "title": "HLW-009: The archive vault is locked behind a syntax error", + "description": "The archive vault is locked behind a syntax error. The Vault interface requires getAccessKey() to verify the user.\n\n\n\nTARGET: The access key is the vaultID (1024) minus the securityDelay (24).", + "difficulty": "Hard", + "category": "HLW_P005", + "templates": { + "java": "class ArchiveVault {\n public int getAccessKey() {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "dummy_0", + "output": "STATUS: UNLOCKED\n\n\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": false + }, + { + "input": "dummy_1", + "output": "STATUS: UNLOCKED\n\n\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_2", + "output": "STATUS: UNLOCKED\n\n\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_3", + "output": "STATUS: UNLOCKED\n\n\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + }, + { + "input": "dummy_4", + "output": "STATUS: UNLOCKED\n\n\nRIDDLE ACQUIRED: \"RIDDLE\"", + "is_hidden": true + } + ] + }, + { + "title": "HLW-010: Don't bother running straight to the lobby", + "description": "AUTHOR: Anonymous\n\nDon't bother running straight to the lobby. The final exit keypad is completely powered down. The system won't supply power to the keypad until all five auxiliary security nodes in this hallway are decrypted.\n\nThe lockdown AI completely wiped the Firewall class from the server memory to stop us from getting the last clue. It only left the Mainframe interface intact.\n\nTARGET: \nRebuild the missing class from scratch.\n\nCreate a class named Firewall that implements Mainframe.\n\nImplement the missing decrypt() method.\n\nThe method must scan the data array. If it finds the exact integer 404, it must return: getPasskeyRiddle()\n\nIf it doesn't find it, return \"LOCKED\".", + "difficulty": "Hard", + "category": "HLW_P006", + "templates": { + "java": "class Firewall {\n public String decrypt(int[] data) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[101, 404, 202]", + "output": "RIDDLE_CONTENT", + "is_hidden": false + }, + { + "input": "[1, 2, 3]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[404]", + "output": "RIDDLE_CONTENT", + "is_hidden": true + }, + { + "input": "[]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[405, 403]", + "output": "LOCKED", + "is_hidden": true + } + ] + }, + { + "title": "HLW-011: The biometric scanner for the armory is offline", + "description": "AUTHOR: Cipher\n\nThe biometric scanner for the armory is offline. The auxiliary power routing needs a massive surge to bypass the mechanical breaker. We need to channel all available data packets and check if the total voltage is high enough.\n\nTARGET:\nRebuild the missing routing class.\n\nCreate a class named PowerRouter that implements Mainframe.\n\nImplement the missing decrypt() method.\n\nThe method must calculate the total sum of all integers in the data array. If the total is greater than 9000, it must return: getPasskeyRiddle()\n\nIf it isn't, return \"LOCKED\".", + "difficulty": "Hard", + "category": "HLW_P006", + "templates": { + "java": "class PowerRouter {\n public String decrypt(int[] data) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[5000, 4001]", + "output": "RIDDLE_CONTENT", + "is_hidden": false + }, + { + "input": "[9000]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[4500, 4500]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[10000]", + "output": "RIDDLE_CONTENT", + "is_hidden": true + } + ] + }, + { + "title": "HLW-012: A logic bomb has been planted in the ventilatio...", + "description": "AUTHOR: Ghost\n\n\n\nA logic bomb has been planted in the ventilation control subnet. We don't have time to sanitize the whole thing. We just need to find the trigger sequence before it executes. The bomb's signature is two consecutive negative integers.\n\n\n\nTARGET:\n\n\nConstruct the scanner class.\n\n\n\nCreate a class named LogicScanner that implements Mainframe.\n\n\n\nImplement the missing decrypt() method.\n\n\n\nThe method must scan the data array for two negative numbers in a row (e.g., -5 immediately followed by -1). If it finds this signature, return: getPasskeyRiddle()\n\n\n\nIf it reaches the end without finding the signature, return \"LOCKED\".", + "difficulty": "Hard", + "category": "HLW_P006", + "templates": { + "java": "class LogicScanner {\n public String decrypt(int[] data) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[-1, -2]", + "output": "RIDDLE_CONTENT", + "is_hidden": false + }, + { + "input": "[-1, 0, -2]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[1, 2, -3, -4, 5]", + "output": "RIDDLE_CONTENT", + "is_hidden": true + }, + { + "input": "[]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[-1]", + "output": "LOCKED", + "is_hidden": true + } + ] + }, + { + "title": "HLW-013: The main elevator requires a secure handshake t...", + "description": "AUTHOR: Overwatch\n\nThe main elevator requires a secure handshake to descend to the lab level. The encryption parity is strict: every single packet in the handshake sequence must be an even number. One odd packet means the connection is compromised.\n\nTARGET:\n\nBuild the verification class.\n\nCreate a class named ParityCheck that implements Mainframe.\n\nImplement the missing decrypt() method.\n\nThe method must evaluate the data array. If it detects ANY odd integer, immediately return: \"LOCKED\"\n\nIf it successfully scans the entire array and all numbers are even, return: getPasskeyRiddle()", + "difficulty": "Hard", + "category": "HLW_P006", + "templates": { + "java": "class ParityCheck {\n public String decrypt(int[] data) {\n // Your code here\n }\n}" + }, + "test_cases": [ + { + "input": "[2, 4, 6]", + "output": "RIDDLE_CONTENT", + "is_hidden": false + }, + { + "input": "[2, 4, 5]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[1, 3, 5]", + "output": "LOCKED", + "is_hidden": true + }, + { + "input": "[]", + "output": "RIDDLE_CONTENT", + "is_hidden": true + }, + { + "input": "[0, 2, 4]", + "output": "RIDDLE_CONTENT", + "is_hidden": true + } + ] + } +] \ No newline at end of file diff --git a/src/scripts/data/java/hallway/questions.json b/src/scripts/data/java/hallway/questions.json index e69de29..fe51488 100644 --- a/src/scripts/data/java/hallway/questions.json +++ b/src/scripts/data/java/hallway/questions.json @@ -0,0 +1 @@ +[] diff --git a/src/scripts/data/java/hallway/riddles.json b/src/scripts/data/java/hallway/riddles.json index e69de29..c62521d 100644 --- a/src/scripts/data/java/hallway/riddles.json +++ b/src/scripts/data/java/hallway/riddles.json @@ -0,0 +1,602 @@ +[ + { + "text": "A pointed peak with a belt across, standing at the head of every sorted row. I lead the hallway's code, the very first letter of this episode.", + "char": "A", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "Two loops stacked like nested iterations on a lecture's endless road, one inside the other. Second in the passkey chain, I carry forward the next refrain.", + "char": "B", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A crescent arc that bends the way a theorem curves before it resolves. Third in the sequence, halfway done, the midpoint letter of this one.", + "char": "C", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "A straight back with a rounded front, like a record filed at the head of a table. Fourth in line, one step from the end, almost around the final bend.", + "char": "D", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "Three teeth like a comb, the kind that separates elements into their proper set. Fifth and final, I complete the key, the last letter to unlock and free.", + "char": "E", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A flag upon a pole, the sort that marks the start of a declared block before it runs. First to step up at position one, the opening cipher before we're done.", + "char": "F", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A spiral inward, like a node being visited twice in a traversal that forgets to stop. Second in the passkey slot, the follow-up cipher of this plot.", + "char": "G", + "index": 2, + "difficulty": "Hard" + }, + { + "text": "Two walls and a bridge between them, the shape of a corridor where two wings converge under one roof. Third in the middle, bridging through, the center letter meant for you.", + "char": "H", + "index": 3, + "difficulty": "Easy" + }, + { + "text": "A lone pillar, the kind that holds a single truth in the middle of an expression. Fourth in the slot, I stand alone, one step away from the keystone.", + "char": "I", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A fishhook at the end of a line, the kind that pulls a method out of an abstract well. Fifth and last, I hook the end, the final cipher round the bend.", + "char": "J", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A sharp kick to the right, the kind of shortcut you press without thinking to jump to the next file. First in the passkey, sharp and angled, the opening code not yet untangled.", + "char": "K", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "A right-angled foot planted firmly, the way a base case grounds a proof before the induction climbs. Second in line, I sit below, the follow-up letter in the flow.", + "char": "L", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "Twin peaks that rise and fall the way a loss curve dips through its early epochs. Third in sequence, double-arched and tall, the midpoint cipher of the hall.", + "char": "M", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A jagged zigzag, the path a packet takes when it bounces between nodes on its way through. Fourth in the chain, I route the way, almost the end of this relay.", + "char": "N", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A perfect circle, the shape of a fully formed instance with no attributes missing. Fifth and final, round and true, the last passkey digit for you.", + "char": "O", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A head on a stick, the silhouette of someone standing at a podium with all eyes forward. First to stand at position one, the opening cipher before we're done.", + "char": "P", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A circle with a tail, the shape of a cursor spinning over a table it hasn't finished reading. Second in the slot, I spin around, the follow-up letter to be found.", + "char": "Q", + "index": 2, + "difficulty": "Hard" + }, + { + "text": "A leg that kicks outward, the way a call doubles back and lands one level below where it started. Third in the sequence, kicked and wide, the center cipher stepping inside.", + "char": "R", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A snake's smooth curve, the shape of a process winding through each stage of a flow diagram. Fourth in the chain, I curve along, one step before the final song.", + "char": "S", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "A balanced cross, the kind drawn in a cell where a condition is either met or it isn't. Fifth and final, balanced last, the closing cipher of the cast.", + "char": "T", + "index": 5, + "difficulty": "Hard" + }, + { + "text": "A dipping bowl, the kind left by an uninitialised variable that was never assigned its value. First in the passkey, scooped and low, the opening cipher of the show.", + "char": "U", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A downward arrow, the kind that marks a changed line in a diff, pointing to what was replaced. Second in line, I point below, the next key letter in the flow.", + "char": "V", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "Two valleys, the shape of a fork where two branches diverge and neither rejoins the other. Third in the sequence, forking out, the middle cipher beyond a doubt.", + "char": "W", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "Crossed paths, the mark left at the spot where two threads collide and neither survives cleanly. Fourth in the code, I cross the space, one step before the final place.", + "char": "X", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A wishbone split, the shape of a yield that hands control back before the task is fully done. Fifth and last, I branch and soar, the final letter of the core.", + "char": "Y", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A lightning bolt, the kind that flashes on a screen when the last layer of defence has already been breached. First in the passkey, striking fast, the opening cipher unsurpassed.", + "char": "Z", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A peaked arch, the shape of a skylight above an open atrium, letting theory pour in from above. Second in the sequence, arched up high, the next code letter brushing sky.", + "char": "A", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "Two rounded loops, side by side on a board where paired conditions must both be true to pass. Third in line, I loop and post, the midpoint cipher of the most.", + "char": "B", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A crescent curve, the shape of a shield that wraps around a system's most sensitive perimeter. Fourth in the chain, I curve and guard, one step before the final shard.", + "char": "C", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "A flat panel, the kind that displays each column and its data type before a single row is inserted. Fifth and last, I list and end, the closing letter round the bend.", + "char": "D", + "index": 5, + "difficulty": "Hard" + }, + { + "text": "Three horizontal ledges, like the three rows of a truth table before the final column is filled. First at position one, a triple stack, the opening cipher on the rack.", + "char": "E", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A flagpole at the top of a block, the kind that hoists a name before the body below it runs. Second in the slot, I flag ahead, the next code letter to be read.", + "char": "F", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "A circular gear, the kind buried inside a shaft that lifts its load by turning rather than pulling. Third in the sequence, spinning neat, the center letter, hard to beat.", + "char": "G", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "Two posts and a bridge, the frame of a door where students pass through without noticing the joints. Fourth in the code, I frame the way, one step before the final display.", + "char": "H", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "A lone pillar standing on its own, the kind that holds a single branch with nothing depending on it. Fifth and last, I stand alone, the final cipher fully grown.", + "char": "I", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A hooked curve, the kind on a sign that bends back toward a room most people walk past without stopping. First in the passkey, hooking on, the opening cipher to carry on.", + "char": "J", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "An angular kick, the corner of a counter that juts into a corridor and catches every elbow. Second in line, I jut and kick, the follow-up letter to pick.", + "char": "K", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A right-angled foot, the bracket at the base of a partition that stops it toppling sideways. Third in the sequence, angled true, the midpoint cipher meant for you.", + "char": "L", + "index": 3, + "difficulty": "Easy" + }, + { + "text": "Twin peaks side by side, the shape of two screens mounted next to each other at a shared workstation. Fourth in the chain, double-peaked and tall, one step before the final call.", + "char": "M", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A jagged peak, a pinned corner of paper caught in a breeze that no one bothered to press flat. Fifth and last, I flutter and freeze, the closing letter of these keys.", + "char": "N", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A perfect ring, the kind punched into a panel where a cable passes through and nothing else fits. First in the passkey, round and whole, the opening cipher of the scroll.", + "char": "O", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "A podium shape, a raised console where a person stands and waits for something to finish printing. Second in the line, I stand and wait, the follow-up letter at the gate.", + "char": "P", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A tailed circle, the shape of a request that loops back on itself when the table it needs is still locked. Third in the sequence, looping wide, the center cipher stepping inside.", + "char": "Q", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "A kicked leg, the bracket at the base of a railing that curves outward just before it meets the floor. Fourth in the code, I kick and curve, one step before the final swerve.", + "char": "R", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "A serpentine path, the aisle that winds between chairs pushed in at odd angles by the last group to leave. Fifth and final, snaking last, the closing cipher of the cast.", + "char": "S", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A balanced cross, the kind pressed onto glass to mark a point that every calibration must return to. First in the passkey, balanced true, the opening letter through.", + "char": "T", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A dipping curve, the hollow underneath something that rises, a shape that holds what falls into it. Second in line, I dip below, the next key letter in the flow.", + "char": "U", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "A downward chevron, the slot in a panel that sends what enters it somewhere it cannot be seen. Third in the sequence, pointing down, the middle cipher of the town.", + "char": "V", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "Two forking arms, the shape of a corridor that splits and sends each group to a different part of the building. Fourth in the chain, I fork and spread, one step before the last is read.", + "char": "W", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "Crossed lines, the mark left at the centre point where every route through this level eventually intersects. Fifth and last, I cross the end, the final passkey round the bend.", + "char": "X", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A wishbone fork, the shape of a path that branches at the point where one group rides and another walks. First in the passkey, forked ahead, the opening cipher to be read.", + "char": "Y", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A lightning zigzag, the warning that appears on a screen when the battery drops to a number no one wants to see. Second in the slot, I flash ahead, the follow-up letter to be said.", + "char": "Z", + "index": 2, + "difficulty": "Hard" + }, + { + "text": "A peaked arch, the curve above a corridor that frames the space without being part of the walls on either side. Third in the sequence, arched and tall, the center cipher of the hall.", + "char": "A", + "index": 3, + "difficulty": "Easy" + }, + { + "text": "Two rounded shapes, like a pair of corkboards flanking a pillar, each one covered in notices nobody has taken down. Fourth in the chain, double-round, one step before the final sound.", + "char": "B", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "A crescent curve, the armrest that rolls outward from a sofa and invites a bag to be rested on it. Fifth and last, I curve and close, the final letter of this prose.", + "char": "C", + "index": 5, + "difficulty": "Hard" + }, + { + "text": "A flat rectangle, the frame of a screen that cycles through announcements nobody fully reads. First in the passkey, straight and plain, the opening cipher of the lane.", + "char": "D", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "Three horizontal bars, the grip-points on a rail that most people touch without counting them. Second in the slot, triple-lined, the follow-up letter you will find.", + "char": "E", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A flagpole top, a small marker beside a door that shows which number you are on without explaining how you got there. Third in the sequence, flagged upright, the midpoint cipher in the light.", + "char": "F", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "A spinning wheel, the kind at the top of a shaft that keeps something heavy moving at a steady pace. Fourth in the code, I spin and hold, one step before the story's told.", + "char": "G", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "Two uprights and a crossbar, the frame that separates one route from another at the point where both become available. Fifth and last, I bridge and close, the final letter of this prose.", + "char": "H", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A lone post at the centre, the kind that holds a single source of information and asks nothing in return. First in the passkey, upright slim, the opening letter at the brim.", + "char": "I", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A curved hook, the shape of an arrow that bends back toward a room on the south side, as if it changed its mind. Second in line, I hook and loop, the follow-up letter of the group.", + "char": "J", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "An angular kick, the corner of a stand that juts into the walking space in a way that was probably intentional. Third in the sequence, angled out, the center cipher beyond a doubt.", + "char": "K", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A right-angled foot, the corner where two sections of seating meet and form a pocket that fills up first. Fourth in the chain, angled low, one step before the final show.", + "char": "L", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "Twin columns, the shape of a legend on a map that uses two lines to explain what the colours mean. Fifth and last, I twin and close, the closing cipher of this prose.", + "char": "M", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A jagged path, the shape of a cable channel that bends around obstacles rather than cutting through them. First in the passkey, jagged right, the opening letter of the night.", + "char": "N", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A perfect ring, the face of a clock on the wall above the entrance, showing a time that may or may not be correct. Second in the line, I tick round, the follow-up letter to be found.", + "char": "O", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "A podium shape, a tall console by the wall where documents wait in a tray for someone who forgot they sent them. Third in the sequence, standing tall, the middle cipher of the hall.", + "char": "P", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "A tailed circle, the loop of a barrier belt that stretches from post to post and asks people to form a line. Fourth in the code, I loop and land, one step before the final stand.", + "char": "Q", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "A kicked-out leg, the bracket at the base of a railing that keeps it from sliding when something heavy leans on it. Fifth and last, I kick and end, the final passkey round the bend.", + "char": "R", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "A serpentine curve, the shape of a row that arcs gently rather than running straight, the way comfort tends to win over efficiency. First in the passkey, curving first, the opening cipher quenching thirst.", + "char": "S", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A balanced cross, the mark at the centre of a shared surface where the power leads from two different seats converge. Second in the slot, I cross ahead, the next code letter to be read.", + "char": "T", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A dipping bowl, the tray beneath a desk that catches every cable so the floor stays clear. Third in the sequence, scooped below, the midpoint cipher in the flow.", + "char": "U", + "index": 3, + "difficulty": "Easy" + }, + { + "text": "A downward slot, angled in the ceiling panel to send air toward the row below without anyone looking up to notice. Fourth in the chain, I angle down, one step before the final crown.", + "char": "V", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "Two forking arms, the point where the east corridor and the west corridor peel apart and stop being the same place. Fifth and final, forked and free, the last letter of this key.", + "char": "W", + "index": 5, + "difficulty": "Hard" + }, + { + "text": "Crossed beams above the atrium, two steel ribs meeting at a point that holds everything else in place. First in the passkey, crossing ahead, the opening cipher to be read.", + "char": "X", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "A wishbone fork, the split where one group steps onto the moving stairs and the other keeps walking. Second in line, I split and flow, the follow-up letter in the show.", + "char": "Y", + "index": 2, + "difficulty": "Hard" + }, + { + "text": "A lightning bolt on a small screen, the icon that appears when the last bar disappears and urgency sets in. Third in the sequence, flashing bright, the center cipher in the light.", + "char": "Z", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A peaked arch, the capital atop a column that makes an entrance feel more significant than the door it frames. Fourth in the code, I arch and guard, one step before the final shard.", + "char": "A", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "Two rounded posts flanking a lane, the kind that mark a boundary without explaining what happens if you cross it. Fifth and last, I post and close, the final letter of this prose.", + "char": "B", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A crescent curve of glass, the kind that wraps around a shaft so you can watch the floors pass without touching them. First in the passkey, curving wide, the opening cipher stepping inside.", + "char": "C", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A flat plate beside a door, the sensor that registers a presence and decides whether the door should open or ignore it. Second in the slot, I plate ahead, the next code letter to be said.", + "char": "D", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "Three flat treads stacked in a cross-section, the geometry of something that moves you upward without asking for effort. Third in the sequence, triple-shelved right, the midpoint cipher within sight.", + "char": "E", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A flagpole marker above a door, the small indicator that tells you which number you are at before you step out. Fourth in the chain, I flag the floor, one step before the final door.", + "char": "F", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A round wheel at the motor hub, the part that turns so that something much heavier can rise at a predictable rate. Fifth and last, I spin and end, the closing letter round the bend.", + "char": "G", + "index": 5, + "difficulty": "Easy" + }, + { + "text": "Two uprights and a bridge, the arch that marks the point where the central space becomes the corridor beyond it. First in the passkey, bridged and braced, the opening cipher in its place.", + "char": "H", + "index": 1, + "difficulty": "Medium" + }, + { + "text": "A lone post in the centre, standing quietly in the kind of spot where everyone passes but nobody stops. Second in line, I stand upright, the follow-up letter of the night.", + "char": "I", + "index": 2, + "difficulty": "Hard" + }, + { + "text": "A curved hook on a sign, the arrow that bends back toward the seating area as if pointing at something the corridor forgot. Third in the sequence, hooking near, the midpoint cipher crystal clear.", + "char": "J", + "index": 3, + "difficulty": "Easy" + }, + { + "text": "An angular foot jutting from a stand, the kind that catches a shoe in the dark and is never apologised for. Fourth in the code, I kick and brace, one step before the final place.", + "char": "K", + "index": 4, + "difficulty": "Medium" + }, + { + "text": "A right-angle bracket anchoring a partition, the small piece of hardware that does the most work and receives the least credit. Fifth and last, I brace and close, the final cipher of this prose.", + "char": "L", + "index": 5, + "difficulty": "Hard" + }, + { + "text": "Twin arms holding two screens at the same station, a shape that doubles the output without doubling the space. First in the passkey, double-armed high, the opening cipher reaching the sky.", + "char": "M", + "index": 1, + "difficulty": "Easy" + }, + { + "text": "A zigzagging path on the floor tiles, arrows pointing the way to something most people already know how to find. Second in line, I zigzag and guide, the follow-up letter stepping inside.", + "char": "N", + "index": 2, + "difficulty": "Medium" + }, + { + "text": "A ring of chairs arranged in a circle, the kind of layout that assumes everyone wants to face the middle. Third in the sequence, circled whole, the center cipher of the scroll.", + "char": "O", + "index": 3, + "difficulty": "Hard" + }, + { + "text": "A shelf at the front of a machine, where pages sit in a tray and wait for whoever sent them to remember. Fourth in the chain, I shelf ahead, one step before the last is read.", + "char": "P", + "index": 4, + "difficulty": "Easy" + }, + { + "text": "A loop with a hook at the end, the latch on a barrier that only opens when someone authorised reaches for it. Fifth and final, looping last, the closing cipher of the cast.", + "char": "Q", + "index": 5, + "difficulty": "Medium" + }, + { + "text": "A kicked-out leg at the base of a railing, the bracket that keeps it fixed to the floor and pointed in the right direction. First in the passkey, kicking first, the opening letter quenching thirst.", + "char": "R", + "index": 1, + "difficulty": "Hard" + }, + { + "text": "A serpentine trail through the lounge, the path left by chairs that were moved and never quite returned to where they started. Second in the slot, I weave ahead, the next code letter to be read.", + "char": "S", + "index": 2, + "difficulty": "Easy" + }, + { + "text": "A balanced cross at the centre of a touchscreen, the calibration mark that must be pressed before anything else will work. Third in the sequence, balanced neat, the midpoint cipher, hard to beat.", + "char": "T", + "index": 3, + "difficulty": "Medium" + }, + { + "text": "A dipping channel beneath the floor, carrying cables from one side of the building to the other without anyone noticing. Fourth in the code, I dip and run, one step before the code is done.", + "char": "U", + "index": 4, + "difficulty": "Hard" + }, + { + "text": "A louvre angled downward in the ceiling, pushing air toward the row below in a way that only becomes obvious when you're cold. Fifth and last, I angle down, the final letter of the crown.", + "char": "V", + "index": 5, + "difficulty": "Easy" + } +] \ No newline at end of file diff --git a/src/scripts/data/java/lockerroom/chunks.json b/src/scripts/data/java/lockerroom/chunks.json index 0637a08..79c872b 100644 --- a/src/scripts/data/java/lockerroom/chunks.json +++ b/src/scripts/data/java/lockerroom/chunks.json @@ -1 +1,74 @@ -[] \ No newline at end of file +[ + { + "title": "LCK-CHUNK-001: Internal Subnet Check", + "difficulty": "Medium", + "category": "Java Basics", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n String ipAddress = scanner.nextLine();\n \n /* The faculty's strict firewall is blocking all of your external traffic. \n * To run your escape script, you need to spoof the routing so it looks like \n * it's coming from the internal student network. The internal subnet ALWAYS \n * begins with \"192.168.\".\n */\n \n // Return true if the IP address starts with the internal subnet\n {{{player_code}}}\n \n System.out.println(isInternal);\n }\n}", + "snippets": { + "player_code": "no clue provided here" + } + } + }, + "expectation": { + "input": "192.168.1.1", + "output": "true" + } + }, + { + "title": "LCK-CHUNK-002: Backdoor Account Detection", + "difficulty": "Medium", + "category": "Java Basics", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\npublic class Solution {\n public static void main(String[] args) {\n Scanner scanner = new Scanner(System.in);\n String username = scanner.nextLine();\n \n /* The corrupt SysAdmin leaves hidden backdoor accounts on every faculty server. \n * You intercepted the user logs. You know their naming convention always includes \n * the word \"admin\", but they try to hide it by mixing uppercase and lowercase \n * letters (like \"SysAdMin42\" or \"rootADMIN\").\n */\n \n // Return true if the username contains \"admin\" (ignoring case!)\n {{{find_backdoor}}}\n \n System.out.println(isBackdoor);\n }\n}", + "snippets": { + "find_backdoor": "no clue provided here" + } + } + }, + "expectation": { + "input": "admin", + "output": "true" + } + }, + { + "title": "LCK-CHUNK-004: Storage Capacity Check", + "difficulty": "Medium", + "category": "Java Basics", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\n\n\npublic class Solution {\n\n public static void main(String[] args) {\n\n Scanner scanner = new Scanner(System.in);\n\n int driveCapacityMB = scanner.nextInt();\n\n int fileSizeKB = scanner.nextInt();\n\n \n\n /* * LORE: You've accessed the Dean's terminal and are trying to download the \n\n * digital blueprints of the faculty building onto a smuggled thumb drive. \n\n * The system gives you the file size in Kilobytes (KB), but you only know \n\n * your drive's remaining capacity in Megabytes (MB).\n\n */\n\n \n\n // Check if the file will fit on the drive (Remember: 1024 KB in 1 MB)\n\n {{{check_storage}}}\n\n \n\n System.out.println(hasEnoughSpace);\n\n }\n\n}", + "snippets": { + "check_storage": "no clue provided here" + } + } + }, + "expectation": { + "input": "1024\n2048", + "output": "true" + } + }, + { + "title": "LCK-CHUNK-005: Password Validation", + "difficulty": "Medium", + "category": "Java Basics", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "import java.util.*;\n\n\n\npublic class Solution {\n\n public static void main(String[] args) {\n\n Scanner scanner = new Scanner(System.in);\n\n String username = scanner.nextLine();\n\n String password = scanner.nextLine();\n\n \n\n /* The Teaching Assistant used a notoriously weak password policy \n\n * for the gradebook server. To crack into the system and find the security \n\n * bypass key, you need to write a quick validation script. A valid password \n\n * must be at least 8 characters long and MUST NOT be exactly the same as the username.\n\n */\n\n \n\n // Return true if the password is 8+ characters and doesn't match the username\n\n {{{validate_password}}}\n\n \n\n System.out.println(isValid);\n\n }\n\n}", + "snippets": { + "validate_password": "no clue provided here" + } + } + }, + "expectation": { + "input": "password\nusername", + "output": "false" + } + } +] \ No newline at end of file diff --git a/src/scripts/data/java/temp/chunks.json b/src/scripts/data/java/temp/chunks.json new file mode 100644 index 0000000..e32cbe3 --- /dev/null +++ b/src/scripts/data/java/temp/chunks.json @@ -0,0 +1,904 @@ +[ + { + "title": "Java Stream Filter", + "difficulty": "Medium", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\nimport java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n List numbers = Arrays.asList(1, 2, 3, 4, 5, 6);\n {{{logic}}}\n System.out.println(result);\n }\n}", + "snippets": [ + [ + "logic", + "List result = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[2, 4, 6]" + } + }, + { + "title": "LCK-CHUNK-003: URL Protocol Upgrade -- removed due to blacklist detected", + "difficulty": "Medium", + "category": "Java Basics", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\n\n\n\npublic class Solution {\n\n public static void main(String[] args) {\n\n Scanner scanner = new Scanner(System.in);\n\n String legacyUrl = scanner.nextLine();\n\n \n\n /* * LORE: The faculty's student database still uses an outdated, \n\n * unencrypted API for internal requests. Your data extraction script \n\n * will be immediately blocked by the modern outbound proxy unless \n\n * the URL strictly uses \"https://\" instead of \"http://\".\n\n */\n\n \n\n // Replace \"http://\" with \"https://\" in the provided URL string\n\n {{{upgrade_protocol}}}\n\n \n\n System.out.println(secureUrl);\n\n }\n\n}", + "snippets": [ + [ + "upgrade_protocol", + "String secureUrl = legacyUrl.replace(\"http://\", \"https://\");" + ] + ] + } + ], + "expectation": { + "input": "http://example.com", + "output": "https://example.com" + } + }, + { + "title": "Java Lambda Comparator", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n List words = Arrays.asList(\"apple\", \"pear\", \"banana\", \"cherry\");\n {{{logic}}}\n System.out.println(words);\n }\n}", + "snippets": [ + [ + "logic", + "words.sort((a, b) -> a.length() - b.length());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[pear, apple, banana, cherry]" + } + }, + { + "title": "Java Optional Usage", + "difficulty": "Easy", + "category": "Optional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Optional opt = Optional.ofNullable(null);\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(opt.orElse(\"Default Value\"));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Default Value" + } + }, + { + "title": "Java List Concatenation", + "difficulty": "Easy", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n List list1 = new ArrayList<>(Arrays.asList(\"A\", \"B\"));\n List list2 = Arrays.asList(\"C\", \"D\");\n {{{logic}}}\n System.out.println(list1);\n }\n}", + "snippets": [ + [ + "logic", + "list1.addAll(list2);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[A, B, C, D]" + } + }, + { + "title": "Java Map Iteration", + "difficulty": "Easy", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Map map = new HashMap<>();\n map.put(\"A\", 1);\n map.put(\"B\", 2);\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "map.forEach((k, v) -> System.out.println(k + \":\" + v));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "A:1\nB:2" + } + }, + { + "title": "Java String Format", + "difficulty": "Easy", + "category": "Strings", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "public class Solution {\n public static void main(String[] args) {\n String name = \"Java\";\n int version = 17;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(String.format(\"Name: %s, Version: %d\", name, version));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Name: Java, Version: 17" + } + }, + { + "title": "Java Array Sorting", + "difficulty": "Easy", + "category": "Arrays", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n int[] arr = {5, 2, 8, 1};\n {{{logic}}}\n System.out.println(Arrays.toString(arr));\n }\n}", + "snippets": [ + [ + "logic", + "Arrays.sort(arr);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[1, 2, 5, 8]" + } + }, + { + "title": "Java List Filter", + "difficulty": "Medium", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\nimport java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n List items = Arrays.asList(\"apple\", \"banana\", \"apricot\", \"cherry\");\n {{{logic}}}\n System.out.println(aItems);\n }\n}", + "snippets": [ + [ + "logic", + "List aItems = items.stream().filter(s -> s.startsWith(\"a\")).collect(Collectors.toList());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[apple, apricot]" + } + }, + { + "title": "Java Math Pow", + "difficulty": "Easy", + "category": "Math", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "public class Solution {\n public static void main(String[] args) {\n double base = 2;\n double exp = 3;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(Math.pow(base, exp));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "8.0" + } + }, + { + "title": "Java Thread Sleep", + "difficulty": "Easy", + "category": "Concurrency", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "public class Solution {\n public static void main(String[] args) throws InterruptedException {\n System.out.println(\"Start\");\n {{{logic}}}\n System.out.println(\"End\");\n }\n}", + "snippets": [ + [ + "logic", + "Thread.sleep(100);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Start\nEnd" + } + }, + { + "title": "Java AtomicInteger", + "difficulty": "Medium", + "category": "Concurrency", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.concurrent.atomic.*;\npublic class Solution {\n public static void main(String[] args) {\n AtomicInteger count = new AtomicInteger(0);\n {{{logic}}}\n System.out.println(count.get());\n }\n}", + "snippets": [ + [ + "logic", + "count.incrementAndGet();" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "1" + } + }, + { + "title": "Java LocalTime Now", + "difficulty": "Easy", + "category": "Time", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.time.*;\npublic class Solution {\n public static void main(String[] args) {\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "LocalTime time = LocalTime.of(10, 0); System.out.println(time);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "10:00" + } + }, + { + "title": "Java LocalDate Parse", + "difficulty": "Easy", + "category": "Time", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.time.*;\npublic class Solution {\n public static void main(String[] args) {\n String dateStr = \"2023-10-01\";\n {{{logic}}}\n System.out.println(date);\n }\n}", + "snippets": [ + [ + "logic", + "LocalDate date = LocalDate.parse(dateStr);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "2023-10-01" + } + }, + { + "title": "Java HashMap GetDefault", + "difficulty": "Easy", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Map map = new HashMap<>();\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(map.getOrDefault(\"key\", \"Default\"));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Default" + } + }, + { + "title": "Java String Split", + "difficulty": "Easy", + "category": "Strings", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n String s = \"a,b,c\";\n {{{logic}}}\n System.out.println(Arrays.toString(parts));\n }\n}", + "snippets": [ + [ + "logic", + "String[] parts = s.split(\",\");" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[a, b, c]" + } + }, + { + "title": "Java Array Fill", + "difficulty": "Easy", + "category": "Arrays", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n int[] arr = new int[3];\n {{{logic}}}\n System.out.println(Arrays.toString(arr));\n }\n}", + "snippets": [ + [ + "logic", + "Arrays.fill(arr, 7);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[7, 7, 7]" + } + }, + { + "title": "Java List Shuffle", + "difficulty": "Easy", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n List list = new ArrayList<>(Arrays.asList(1, 2, 3));\n {{{logic}}}\n System.out.println(list.size());\n }\n}", + "snippets": [ + [ + "logic", + "Collections.shuffle(list);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "3" + } + }, + { + "title": "Java BigInteger Add", + "difficulty": "Easy", + "category": "Math", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.math.*;\npublic class Solution {\n public static void main(String[] args) {\n BigInteger a = new BigInteger(\"100\");\n BigInteger b = new BigInteger(\"200\");\n {{{logic}}}\n System.out.println(c);\n }\n}", + "snippets": [ + [ + "logic", + "BigInteger c = a.add(b);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "300" + } + }, + { + "title": "Java String Join", + "difficulty": "Easy", + "category": "Strings", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n List list = Arrays.asList(\"A\", \"B\", \"C\");\n {{{logic}}}\n System.out.println(joined);\n }\n}", + "snippets": [ + [ + "logic", + "String joined = String.join(\"-\", list);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "A-B-C" + } + }, + { + "title": "Java Set Intersection", + "difficulty": "Medium", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Set s1 = new HashSet<>(Arrays.asList(1, 2, 3));\n Set s2 = new HashSet<>(Arrays.asList(2, 3, 4));\n {{{logic}}}\n System.out.println(s1);\n }\n}", + "snippets": [ + [ + "logic", + "s1.retainAll(s2);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[2, 3]" + } + }, + { + "title": "Java Streams Map", + "difficulty": "Medium", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\nimport java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n List nums = Arrays.asList(1, 2, 3);\n {{{logic}}}\n System.out.println(squares);\n }\n}", + "snippets": [ + [ + "logic", + "List squares = nums.stream().map(n -> n * n).collect(Collectors.toList());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[1, 4, 9]" + } + }, + { + "title": "Java Streams Reduce", + "difficulty": "Medium", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\nimport java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n List nums = Arrays.asList(1, 2, 3, 4);\n {{{logic}}}\n System.out.println(sum);\n }\n}", + "snippets": [ + [ + "logic", + "int sum = nums.stream().reduce(0, Integer::sum);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "10" + } + }, + { + "title": "Java Files Write", + "difficulty": "Medium", + "category": "IO", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.nio.file.*;\nimport java.util.*;\npublic class Solution {\n public static void main(String[] args) throws Exception {\n System.out.println(\"Done\");\n }\n}", + "snippets": [ + [ + "logic", + "// No logic needed for dummy shell" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Done" + } + }, + { + "title": "Java Base64 Encode", + "difficulty": "Easy", + "category": "Security", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n String original = \"hello\";\n {{{logic}}}\n System.out.println(encoded);\n }\n}", + "snippets": [ + [ + "logic", + "String encoded = Base64.getEncoder().encodeToString(original.getBytes());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "aGVsbG8=" + } + }, + { + "title": "Java UUID Random", + "difficulty": "Easy", + "category": "Util", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n {{{logic}}}\n System.out.println(\"Generated\");\n }\n}", + "snippets": [ + [ + "logic", + "UUID uuid = UUID.randomUUID();" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Generated" + } + }, + { + "title": "Java ReentrantLock", + "difficulty": "Hard", + "category": "Concurrency", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.concurrent.locks.*;\npublic class Solution {\n public static void main(String[] args) {\n ReentrantLock lock = new ReentrantLock();\n {{{logic}}}\n System.out.println(\"Unlocked\");\n }\n}", + "snippets": [ + [ + "logic", + "lock.lock(); try { } finally { lock.unlock(); }" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Unlocked" + } + }, + { + "title": "Java CountDownLatch", + "difficulty": "Hard", + "category": "Concurrency", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.concurrent.*;\npublic class Solution {\n public static void main(String[] args) throws Exception {\n CountDownLatch latch = new CountDownLatch(1);\n {{{logic}}}\n System.out.println(latch.getCount());\n }\n}", + "snippets": [ + [ + "logic", + "latch.countDown();" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "0" + } + }, + { + "title": "Java Scanner Stdin", + "difficulty": "Easy", + "category": "IO", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n // Simulated scan\n System.out.println(\"Scanned\");\n }\n}", + "snippets": [ + [ + "logic", + "" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Scanned" + } + }, + { + "title": "Java Function Interface", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.function.*;\npublic class Solution {\n public static void main(String[] args) {\n Function addOne = x -> x + 1;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(addOne.apply(5));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "6" + } + }, + { + "title": "Java Predicate Usage", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.function.*;\npublic class Solution {\n public static void main(String[] args) {\n Predicate isEmpty = String::isEmpty;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(isEmpty.test(\"\"));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "true" + } + }, + { + "title": "Java Supplier Usage", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.function.*;\npublic class Solution {\n public static void main(String[] args) {\n Supplier random = Math::random;\n {{{logic}}}\n System.out.println(\"Got Value\");\n }\n}", + "snippets": [ + [ + "logic", + "Double d = random.get();" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Got Value" + } + }, + { + "title": "Java Consumer Usage", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.function.*;\npublic class Solution {\n public static void main(String[] args) {\n Consumer printer = System.out::println;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "printer.accept(\"Hello Consumer\");" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Hello Consumer" + } + }, + { + "title": "Java BinaryOperator", + "difficulty": "Medium", + "category": "Functional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.function.*;\npublic class Solution {\n public static void main(String[] args) {\n BinaryOperator add = (a, b) -> a + b;\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "System.out.println(add.apply(10, 20));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "30" + } + }, + { + "title": "Java Collectors Join", + "difficulty": "Medium", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\nimport java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n List items = Arrays.asList(\"A\", \"B\", \"C\");\n {{{logic}}}\n System.out.println(res);\n }\n}", + "snippets": [ + [ + "logic", + "String res = items.stream().collect(Collectors.joining(\", \"));" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "A, B, C" + } + }, + { + "title": "Java List Sort Natural", + "difficulty": "Easy", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n List list = Arrays.asList(3, 1, 2);\n {{{logic}}}\n System.out.println(list);\n }\n}", + "snippets": [ + [ + "logic", + "list.sort(Comparator.naturalOrder());" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "[1, 2, 3]" + } + }, + { + "title": "Java Map Merge", + "difficulty": "Medium", + "category": "Collections", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Map map = new HashMap<>();\n map.put(\"A\", 1);\n {{{logic}}}\n System.out.println(map.get(\"A\"));\n }\n}", + "snippets": [ + [ + "logic", + "map.merge(\"A\", 1, Integer::sum);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "2" + } + }, + { + "title": "Java String Repeat", + "difficulty": "Easy", + "category": "Strings", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "public class Solution {\n public static void main(String[] args) {\n String s = \"A\";\n {{{logic}}}\n System.out.println(res);\n }\n}", + "snippets": [ + [ + "logic", + "String res = s.repeat(3);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "AAA" + } + }, + { + "title": "Java Object Hash", + "difficulty": "Easy", + "category": "Util", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n {{{logic}}}\n System.out.println(\"Hashed\");\n }\n}", + "snippets": [ + [ + "logic", + "int h = Objects.hash(\"a\", \"b\");" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "Hashed" + } + }, + { + "title": "Java Stream Of", + "difficulty": "Easy", + "category": "Streams", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.stream.*;\npublic class Solution {\n public static void main(String[] args) {\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "Stream.of(\"a\", \"b\").forEach(System.out::print);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "ab" + } + }, + { + "title": "Java Optional Map", + "difficulty": "Medium", + "category": "Optional", + "templates": [ + { + "lang": "java", + "name": "Java Implementation", + "code": "import java.util.*;\npublic class Solution {\n public static void main(String[] args) {\n Optional opt = Optional.of(\"hello\");\n {{{logic}}}\n }\n}", + "snippets": [ + [ + "logic", + "opt.map(String::toUpperCase).ifPresent(System.out::println);" + ] + ] + } + ], + "expectation": { + "input": "", + "output": "HELLO" + } + } +] \ No newline at end of file diff --git a/src/scripts/data/java/temp/chunks.lvl4.json b/src/scripts/data/java/temp/chunks.lvl4.json new file mode 100644 index 0000000..f331381 --- /dev/null +++ b/src/scripts/data/java/temp/chunks.lvl4.json @@ -0,0 +1,162 @@ +[ + { + "title": "ELV-P4-CHUNK-001", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// [NULL] stripped the exception handling from the ID scanner.\n// It now crashes on any non-integer input and floods the audit log with errors.\n// Restore the three blocks. Every scan must be logged, pass or fail.\n\npublic class CheckpointScanner {\n\n public static String parseStudentID(String input) {\n try {\n // TASK 1: Parse input. Return \"VALID:\" + id if 10000\u201399999, else \"INVALID:OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"scan attempt logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "int id = Integer.parseInt(input);\nif (id >= 10000 && id <= 99999) {\n return \"VALID:\" + id;\n} else {\n return \"INVALID:OUT_OF_RANGE\";\n}", + "snippet_2": "return \"INVALID:NOT_A_NUMBER\";", + "snippet_3": "System.out.println(\"scan attempt logged\");" + } + } + }, + "expectation": { + "input": "12345", + "output": "VALID:12345" + } + }, + { + "title": "ELV-P4-CHUNK-002", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The room code scanner is throwing unhandled exceptions on every bad input.\n// [NULL] knew exactly which lines to delete to break the audit trail.\n// Restore all three exception blocks.\n\npublic class CheckpointScanner {\n\n public static String parseRoomCode(String input) {\n try {\n // TASK 1: Parse input. Return \"ROOM:\" + code if 100\u2013999, else \"INVALID:NOT_A_ROOM\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:FORMAT_ERROR\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"door scan logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "int code = Integer.parseInt(input);\nif (code >= 100 && code <= 999) {\n return \"ROOM:\" + code;\n} else {\n return \"INVALID:NOT_A_ROOM\";\n}", + "snippet_2": "return \"INVALID:FORMAT_ERROR\";", + "snippet_3": "System.out.println(\"door scan logged\");" + } + } + }, + "expectation": { + "input": "123", + "output": "ROOM:123" + } + }, + { + "title": "ELV-P4-CHUNK-003", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The port scanner crashes on anything that is not a clean integer.\n// Without proper exception handling the network audit trail is blind.\n// Restore it.\n\npublic class CheckpointScanner {\n\n public static String parsePort(String input) {\n try {\n // TASK 1: Parse input. Return \"PORT:\" + number if 1\u201365535, else \"INVALID:PORT_OUT_OF_RANGE\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_PORT\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"connection attempt logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "int port = Integer.parseInt(input);\nif (port >= 1 && port <= 65535) {\n return \"PORT:\" + port;\n} else {\n return \"INVALID:PORT_OUT_OF_RANGE\";\n}", + "snippet_2": "return \"INVALID:NOT_A_PORT\";", + "snippet_3": "System.out.println(\"connection attempt logged\");" + } + } + }, + "expectation": { + "input": "80", + "output": "PORT:80" + } + }, + { + "title": "ELV-P4-CHUNK-004", + "difficulty": "Medium", + "category": "ELV-P4", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The elevator rejects every floor request because the parser throws on bad input.\n// [NULL] removed the safety net. Restore the exception blocks.\n// The finally block is not optional \u2014 the lift log must always write.\n\npublic class CheckpointScanner {\n\n public static String parseFloor(String input) {\n try {\n // TASK 1: Parse input. Return \"FLOOR:\" + number if 1\u201310, else \"INVALID:NO_SUCH_FLOOR\".\n {{{snippet_1}}}\n } catch (NumberFormatException e) {\n // TASK 2: Return \"INVALID:NOT_A_NUMBER\".\n {{{snippet_2}}}\n } finally {\n // TASK 3: Always print \"elevator request logged\".\n {{{snippet_3}}}\n }\n }\n}", + "snippets": { + "snippet_1": "int floor = Integer.parseInt(input);\nif (floor >= 1 && floor <= 10) {\n return \"FLOOR:\" + floor;\n} else {\n return \"INVALID:NO_SUCH_FLOOR\";\n}", + "snippet_2": "return \"INVALID:NOT_A_NUMBER\";", + "snippet_3": "System.out.println(\"elevator request logged\");" + } + } + }, + "expectation": { + "input": "5", + "output": "FLOOR:5" + } + }, + { + "title": "ELV-P5-CHUNK-001", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// 4,847 log entries. The threat filter is gone \u2014 [NULL] deleted it first.\n// Without it the emergency system cannot assess severity.\n// Find the threats. The building needs this report before it can act.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String analyzeLogs(ArrayList logs) {\n\n // TASK 1: Declare a counter and an ArrayList for threat descriptions.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"THREAT:\", increment and collect the description (after 8 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"THREATS:0|none\" if clean, else \"THREATS:\" + count + \"|\" + descriptions joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs1 = new ArrayList<>();\n logs1.add(\"INFO: door opened\");\n logs1.add(\"THREAT: brute force\");\n logs1.add(\"INFO: scan ok\");\n logs1.add(\"THREAT: port scan\");\n logs1.add(\"THREAT: login fail\");\n System.out.println(analyzeLogs(logs1));\n\n ArrayList logs2 = new ArrayList<>();\n logs2.add(\"INFO: all clear\");\n System.out.println(analyzeLogs(logs2));\n }\n}", + "snippets": { + "snippet_1": "int count = 0;\nArrayList threats = new ArrayList<>();", + "snippet_2": "if (entry.startsWith(\"THREAT:\")) {\n count++;\n threats.add(entry.substring(8));\n}", + "snippet_3": "if (count == 0) return \"THREATS:0|none\";\nreturn \"THREATS:\" + count + \"|\" + String.join(\",\", threats);" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-002", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The server error filter was wiped along with the intrusion logs.\n// Critical errors are invisible to the monitoring system.\n// Restore the filter \u2014 find every ERROR entry and report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String filterErrors(ArrayList logs) {\n\n // TASK 1: Declare a counter and an ArrayList for error messages.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry starts with \"ERROR:\", increment and collect the message (after 7 chars).\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"ERRORS:0|none\" if clean, else \"ERRORS:\" + count + \"|\" + messages joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs1 = new ArrayList<>();\n logs1.add(\"INFO: server started\");\n logs1.add(\"ERROR: disk full\");\n logs1.add(\"ERROR: null pointer\");\n logs1.add(\"INFO: backup ok\");\n System.out.println(filterErrors(logs1));\n\n ArrayList logs2 = new ArrayList<>();\n logs2.add(\"INFO: running\");\n System.out.println(filterErrors(logs2));\n }\n}", + "snippets": { + "snippet_1": "int count = 0;\nArrayList errors = new ArrayList<>();", + "snippet_2": "if (entry.startsWith(\"ERROR:\")) {\n count++;\n errors.add(entry.substring(7));\n}", + "snippet_3": "if (count == 0) return \"ERRORS:0|none\";\nreturn \"ERRORS:\" + count + \"|\" + String.join(\",\", errors);" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-003", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// The badge access log is full of denied entries \u2014 someone was probing every door.\n// The scanner that should have flagged them is offline.\n// Find every DENIED entry before [NULL] makes another move.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findDenied(ArrayList entries) {\n\n // TASK 1: Declare a counter and an ArrayList for denied entries.\n {{{snippet_1}}}\n\n for (String entry : entries) {\n // TASK 2: If entry contains \"DENIED\" anywhere, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"DENIED:0|none\" if none, else \"DENIED:\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList e1 = new ArrayList<>();\n e1.add(\"Student 001: GRANTED\");\n e1.add(\"Student 002: DENIED low clearance\");\n e1.add(\"Student 003: GRANTED\");\n e1.add(\"Visitor 01: DENIED no badge\");\n System.out.println(findDenied(e1));\n\n ArrayList e2 = new ArrayList<>();\n e2.add(\"Staff 001: GRANTED\");\n System.out.println(findDenied(e2));\n }\n}", + "snippets": { + "snippet_1": "int count = 0;\nArrayList denied = new ArrayList<>();", + "snippet_2": "if (entry.contains(\"DENIED\")) {\n count++;\n denied.add(entry);\n}", + "snippet_3": "if (count == 0) return \"DENIED:0|none\";\nreturn \"DENIED:\" + count + \"|\" + String.join(\",\", denied);" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + }, + { + "title": "ELV-P5-CHUNK-004", + "difficulty": "Medium", + "category": "ELV-P5", + "templates": { + "java": { + "name": "Java Implementation", + "template_code": "// Elevator requests are piling up but the floor filter is down.\n// Security needs to know exactly how many calls are going to each floor.\n// Restore the filter \u2014 match by floor number, report the count.\n\nimport java.util.ArrayList;\n\npublic class ThreatAnalyser {\n\n public static String findFloorRequests(ArrayList logs, int floor) {\n\n // TASK 1: Declare a counter and an ArrayList for matching requests.\n {{{snippet_1}}}\n\n for (String entry : logs) {\n // TASK 2: If entry ends with \":\" + floor, increment and collect the full entry.\n {{{snippet_2}}}\n }\n\n // TASK 3: Return \"FLOOR\" + floor + \":0|none\" if none,\n // else \"FLOOR\" + floor + \":\" + count + \"|\" + entries joined by \",\".\n {{{snippet_3}}}\n }\n\n public static void main(String[] args) {\n ArrayList logs = new ArrayList<>();\n logs.add(\"User A requested floor:2\");\n logs.add(\"User B requested floor:3\");\n logs.add(\"User C requested floor:2\");\n logs.add(\"User D requested floor:1\");\n System.out.println(findFloorRequests(logs, 2));\n System.out.println(findFloorRequests(logs, 5));\n }\n}", + "snippets": { + "snippet_1": "int count = 0;\nArrayList matches = new ArrayList<>();", + "snippet_2": "if (entry.endsWith(\":\" + floor)) {\n count++;\n matches.add(entry);\n}", + "snippet_3": "if (count == 0) return \"FLOOR\" + floor + \":0|none\";\nreturn \"FLOOR\" + floor + \":\" + count + \"|\" + String.join(\",\", matches);" + } + } + }, + "expectation": { + "input": "", + "output": "" + } + } +] \ No newline at end of file diff --git a/src/scripts/process_elevatorhall.py b/src/scripts/process_elevatorhall.py new file mode 100644 index 0000000..42dd51f --- /dev/null +++ b/src/scripts/process_elevatorhall.py @@ -0,0 +1,114 @@ +import pandas as pd +import json +import os +import re + +def process_excel(): + xl = pd.ExcelFile('Level 4 Puzzles.xlsx') + chunks = [] + problems = [] + + for name in xl.sheet_names: + df = xl.parse(name) + # Extract Px from L4_Px + match_p = re.search(r'L4_(P\d+)', name) + category_id = f"ELV-{match_p.group(1)}" if match_p else "Elevator Hall" + + if '(Chunk)' in name: + for i, row in df.iterrows(): + template_code = str(row.get('Problem', row.get('Template', ''))) + snippet_block = str(row.get('Expected Input', row.get('Expected Snippet', ''))) + + placeholders = re.findall(r'\{TASK\s*(\d+):[^\}]+\}', template_code) + s_dict = {} + + new_template = template_code + for p_num in placeholders: + placeholder_search = re.search(rf'\{{TASK\s*{p_num}:[^\}}]+\}}', new_template) + if placeholder_search: + placeholder_str = placeholder_search.group(0) + new_template = new_template.replace(placeholder_str, f'{{{{{{snippet_{p_num}}}}}}}') + + pattern = rf'TASK\s*{p_num}\s*\([^\)]+\):\s*(.*?)(?=TASK\s*\d+\s*\(|$)' + match = re.search(pattern, snippet_block, re.DOTALL) + if match: + s_dict[f"snippet_{p_num}"] = match.group(1).strip() + else: + s_dict[f"snippet_{p_num}"] = f"// Missing snippet for Task {p_num}" + + chunk_data = { + "title": f"{category_id}-CHUNK-{i+1:03d}", + "difficulty": str(row.get('Difficulty', "Medium")), + "category": category_id, + "templates": { + "java": { + "name": "Java Implementation", + "template_code": new_template, + "snippets": s_dict + } + }, + "expectation": { + "input": str(row.get('Input', '')), + "output": str(row.get('Expected Output', '')) + } + } + chunks.append(chunk_data) + elif '(Problem)' in name: + for i, row in df.iterrows(): + template_code = str(row.get('Problem', row.get('Template', ''))) + expected_output = str(row.get('Expected Output', '')) + + outputs = [o.strip() for o in expected_output.split('\n') if o.strip()] + + method_match = re.search(r'public\s+static\s+(?:\w+(?:\[\])?)\s+(\w+)\(', template_code) + method_name = method_match.group(1) if method_match else "" + + inputs = [] + if method_name: + # Look only inside the main method + main_match = re.search(r'public\s+static\s+void\s+main\s*\(.*?\)\s*\{(.*?)\}', template_code, re.DOTALL) + if main_match: + main_content = main_match.group(1) + # Look for calls: method_name(...) + # We want the arguments between the first "(" and last ")" for this call + matches = re.finditer(rf'{method_name}\((.*?)\)', main_content) + for m in matches: + inputs.append(m.group(1)) + + test_cases = [] + # Use whichever count is larger, but match them up + count = max(len(inputs), len(outputs)) + for j in range(count): + inp = inputs[j] if j < len(inputs) else "" + out = outputs[j] if j < len(outputs) else "" + test_cases.append({ + "input": inp, + "output": out, + "is_hidden": j > 0 + }) + + problem_data = { + "title": f"{category_id}-PROB-{i+1:03d}", + "description": template_code, + "difficulty": str(row.get('Difficulty', "Hard")), + "category": category_id, + "templates": { + "java": template_code + }, + "test_cases": test_cases + } + problems.append(problem_data) + + out_dir = 'src/scripts/data/java/elevatorhall' + os.makedirs(out_dir, exist_ok=True) + + with open(os.path.join(out_dir, 'chunks.json'), 'w') as f: + json.dump(chunks, f, indent=4) + + with open(os.path.join(out_dir, 'problems.json'), 'w') as f: + json.dump(problems, f, indent=4) + + print(f"Processed {len(chunks)} chunks and {len(problems)} problems with category mapping.") + +if __name__ == "__main__": + process_excel() diff --git a/src/scripts/seed.py b/src/scripts/seed.py index c02fdb6..8e646b8 100644 --- a/src/scripts/seed.py +++ b/src/scripts/seed.py @@ -11,6 +11,11 @@ RiddleTagLink, QuestionTagLink, QuestionCategoryLink, ChunkTemplate, Chunk, Snippet, ChunkCategoryLink, ChunkTagLink, Expectation ) +from scripts.seeders.seed_hallway_java import seed_hallway_java +from scripts.seeders.seed_lockerroom_java import seed_lockerroom_java +from scripts.seeders.seed_restroom_java import seed_restroom_java +from scripts.seeders.seed_elevatorhall_java import seed_elevatorhall_java + logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') @@ -411,5 +416,14 @@ def add_problem(title, description, difficulty, category_list, tag_list, config= session.commit() logging.info("Chunk seeding process completed.") + # Seed local regional data + logging.info("Seeding regional data...") + seed_hallway_java() + seed_lockerroom_java() + seed_restroom_java() + seed_elevatorhall_java() + logging.info("Regional seeding process completed.") + + if __name__ == "__main__": seed_data() diff --git a/src/scripts/seeders/__init__.py b/src/scripts/seeders/__init__.py index e69de29..4794268 100644 --- a/src/scripts/seeders/__init__.py +++ b/src/scripts/seeders/__init__.py @@ -0,0 +1,2 @@ +# This file makes seeders a Python package. +# Modules are not imported here to avoid RuntimeWarning when run individually with -m. diff --git a/src/scripts/seeders/seed_elevatorhall_java.py b/src/scripts/seeders/seed_elevatorhall_java.py new file mode 100644 index 0000000..ce9a72d --- /dev/null +++ b/src/scripts/seeders/seed_elevatorhall_java.py @@ -0,0 +1,159 @@ +import logging +import uuid +import json +import os +from datetime import datetime, timezone +from sqlmodel import Session, select +from infrastructure import engine +from models import ( + Category, Tag, Question, Choice, Chunk, ChunkTemplate, Snippet, Expectation, Problem, TestCase +) +from sqlalchemy.orm.attributes import flag_modified + +logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s') + +NAMESPACE = uuid.NAMESPACE_DNS + +def get_uuid(name: str) -> uuid.UUID: + """Generate a deterministic UUID based on a string name.""" + return uuid.uuid5(NAMESPACE, name) + +def load_json(filename): + base_path = os.path.join(os.path.dirname(__file__), "..", "data", "java", "elevatorhall") + filepath = os.path.join(base_path, filename) + if not os.path.exists(filepath): + logging.warning(f"File not found: {filepath}") + return [] + with open(filepath, "r") as f: + return json.load(f) + +def seed_elevatorhall_java(): + if not engine: + logging.error("No database engine found. Skipping seeding.") + return + + CHUNKS = load_json("chunks.json") + PROBLEMS = load_json("problems.json") + + with Session(engine) as session: + logging.info("Starting JAV_ELVHALL JSON-based seeding process...") + + def get_or_create_category(name): + cat_id = get_uuid(f"cat_{name}") + cat = session.exec(select(Category).where(Category.id == cat_id)).first() + if not cat: + cat = Category(id=cat_id, name=name) + session.add(cat) + session.commit() + session.refresh(cat) + return cat + + def get_or_create_tag(name): + tag_id = get_uuid(f"tag_{name}") + tag = session.exec(select(Tag).where(Tag.id == tag_id)).first() + if not tag: + tag = Tag(id=tag_id, name=name) + session.add(tag) + session.commit() + session.refresh(tag) + return tag + + elv_hall_tag = get_or_create_tag("JAV_ELVHALL") + java_cat = get_or_create_category("Java") + + # 1. Seed Chunks + logging.info(f"Seeding {len(CHUNKS)} Java chunks...") + for c_data in CHUNKS: + c_id = get_uuid(f"jav_elvhall_chunk_{c_data['title']}") + chunk = session.exec(select(Chunk).where(Chunk.id == c_id)).first() + if not chunk: + chunk = Chunk( + id=c_id, + title=c_data["title"], + difficulty=c_data["difficulty"], + created_at=datetime.now(timezone.utc) + ) + chunk.categories = [get_or_create_category(c_data.get("category", "Java Basics"))] + chunk.tags = [elv_hall_tag] + session.add(chunk) + session.flush() + else: + chunk.difficulty = c_data["difficulty"] + for t in chunk.templates: + session.delete(t) + session.flush() + + for lang, t_data in c_data["templates"].items(): + template = ChunkTemplate( + chunk_id=chunk.id, + language=lang, + name=t_data["name"], + template_code=t_data["template_code"], + description=t_data.get("description", f"Standard {lang} boilerplate") + ) + session.add(template) + session.flush() + + for key, content in t_data.get("snippets", {}).items(): + s = Snippet(template_id=template.id, placeholder_key=key, code_content=content) + session.add(s) + + if "expectation" in c_data: + for ex in chunk.expectations: + session.delete(ex) + session.flush() + ex = Expectation( + chunk_id=chunk.id, + input=c_data["expectation"]["input"], + output=c_data["expectation"]["output"] + ) + session.add(ex) + + # 2. Seed Problems + logging.info(f"Seeding {len(PROBLEMS)} Java problems...") + for p_data in PROBLEMS: + p_id = get_uuid(f"jav_elvhall_prob_{p_data['title']}") + problem = session.exec(select(Problem).where(Problem.id == p_id)).first() + if not problem: + problem = Problem( + id=p_id, + title=p_data["title"], + description=p_data["description"], + difficulty=p_data["difficulty"], + config={"templates": p_data.get("templates", {})} + ) + problem.categories = [get_or_create_category(p_data.get("category", "Java Algorithms"))] + problem.tags = [elv_hall_tag] + session.add(problem) + else: + problem.description = p_data["description"] + problem.difficulty = p_data["difficulty"] + config = problem.config or {} + config["templates"] = p_data.get("templates", {}) + problem.config = config + flag_modified(problem, "config") + session.add(problem) + session.flush() + + if "test_cases" in p_data: + for tc in problem.test_cases: + session.delete(tc) + session.flush() + + for i, tc_data in enumerate(p_data["test_cases"]): + tc_id = get_uuid(f"jav_elvhall_tc_{p_data['title']}_{i}") + tc = TestCase( + id=tc_id, + problem_id=p_id, + input=str(tc_data["input"]), + output=str(tc_data["output"]), + is_hidden=tc_data.get("is_hidden", True), + sort_order=i + 1 + ) + session.add(tc) + + session.commit() + logging.info("JAV_ELVHALL JSON-based seeding completed successfully.") + +if __name__ == "__main__": + seed_elevatorhall_java() diff --git a/src/scripts/seeders/seed_hallway.py b/src/scripts/seeders/seed_hallway_java.py similarity index 100% rename from src/scripts/seeders/seed_hallway.py rename to src/scripts/seeders/seed_hallway_java.py diff --git a/src/scripts/utils/convert_chunks.py b/src/scripts/utils/convert_chunks.py new file mode 100644 index 0000000..f29fbc5 --- /dev/null +++ b/src/scripts/utils/convert_chunks.py @@ -0,0 +1,64 @@ +import csv +import json +import re + +def convert_chunks_csv_to_json(csv_path, json_path): + # Descriptive titles for each chunk + titles = [ + "Internal Subnet Check", + "Backdoor Account Detection", + "URL Protocol Upgrade", + "Storage Capacity Check", + "Password Validation" + ] + + # Expectations for each chunk + expectations = [ + {"input": "192.168.1.1", "output": "true"}, + {"input": "admin", "output": "true"}, + {"input": "http://example.com", "output": "https://example.com"}, + {"input": "1024\n2048", "output": "true"}, + {"input": "password\nusername", "output": "false"} + ] + + chunks = [] + with open(csv_path, 'r', newline='', encoding='utf-8') as csvfile: + reader = csv.DictReader(csvfile) + for i, row in enumerate(reader): + template = row['Template'] + expected = row['Expected Snippet'] + + # Find the placeholder key + match = re.search(r'\{\{\{(.+?)\}\}\}', template) + if not match: + print(f"Warning: No placeholder found in row {i+1}") + continue + key = match.group(1) + + chunk = { + 'title': f'LCK-CHUNK-{i+1:03d}: {titles[i]}', + 'difficulty': 'Medium', + 'category': 'Java Basics', + 'templates': [ + { + 'lang': 'java', + 'name': 'Java Implementation', + 'code': template, + 'snippets': [ + [key, expected] + ] + } + ], + 'expectation': expectations[i] + } + chunks.append(chunk) + + with open(json_path, 'w', encoding='utf-8') as jsonfile: + json.dump(chunks, jsonfile, indent=4, ensure_ascii=False) + + print(f"Converted {len(chunks)} chunks to {json_path}") + +if __name__ == "__main__": + csv_path = "" + json_path = "" + convert_chunks_csv_to_json(csv_path, json_path) \ No newline at end of file diff --git a/src/scripts/utils/convert_riddles.py b/src/scripts/utils/convert_riddles.py new file mode 100644 index 0000000..b142b1d --- /dev/null +++ b/src/scripts/utils/convert_riddles.py @@ -0,0 +1,25 @@ +import csv +import json + +def convert_riddles_csv_to_json(csv_path, json_path): + riddles = [] + with open(csv_path, 'r', newline='', encoding='utf-8') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + riddle = { + 'text': row['Riddle Text'], + 'char': row['Character (refer_character)'], + 'index': int(row['Index (refer_index)']), + 'difficulty': row['Difficulty'] + } + riddles.append(riddle) + + with open(json_path, 'w', encoding='utf-8') as jsonfile: + json.dump(riddles, jsonfile, indent=4, ensure_ascii=False) + + print(f"Converted {len(riddles)} riddles to {json_path}") + +if __name__ == "__main__": + csv_path = "" + json_path = "" + convert_riddles_csv_to_json(csv_path, json_path) \ No newline at end of file diff --git a/src/services/chunk_service.py b/src/services/chunk_service.py index 0dd2824..c756591 100644 --- a/src/services/chunk_service.py +++ b/src/services/chunk_service.py @@ -6,7 +6,6 @@ def __init__(self): self.repo = ChunkRepository() def _process_chunk(self, chunk): - if not chunk: return None @@ -22,21 +21,31 @@ def _process_chunk(self, chunk): for lang, t_dict in templates.items(): cmt_pat = cmt_map.get(lang.lower(), cmt_map["default"]) tc = t_dict.get("template_code") + if tc: - processed = re.sub( - r'\{{3}\s*(\w+)\s*\}{3}', - lambda m: f"\n{cmt_pat.format(m.group(1))}\n", - tc - ) - t_dict["template_code"] = [line for line in processed.split('\n') if line] - - # Transform snippets dict into parallel arrays - snippets_dict = t_dict.get("snippets", {}) - if isinstance(snippets_dict, dict): - keys = list(snippets_dict.keys()) - values = [snippets_dict[k] for k in keys] - t_dict["snippets"] = keys - t_dict["code_content"] = values + parts = re.split(r'(\{{3}\s*\w+\s*\}{3})', tc) + processed_list = [] + current_buffer = "" + + for part in parts: + match = re.match(r'\{{3}\s*(\w+)\s*\}{3}', part) + if match: + key_name = match.group(1) + comment_str = f"\n{cmt_pat.format(key_name)}" + processed_list.append(current_buffer + comment_str) + current_buffer = "" + else: + current_buffer = part + + processed_list.append(current_buffer if current_buffer else "\n") + t_dict["template_code"] = processed_list + + snippets_dict = t_dict.get("snippets", {}) + if isinstance(snippets_dict, dict): + sorted_keys = sorted(snippets_dict.keys()) + + t_dict["snippets"] = sorted_keys + t_dict["code_content"] = [snippets_dict[k] for k in sorted_keys] return chunk @@ -50,6 +59,6 @@ def get_chunk(self, chunk_id, lang=None): return self._process_chunk(chunk) return None - def get_random_chunks(self, limit=1, lang=None): - chunks = self.repo.find_random(limit=limit, lang=lang) + def get_random_chunks(self, limit=1, lang=None, tags=None, category=None): + chunks = self.repo.find_random(limit=limit, lang=lang, tags=tags, category=category) return [self._process_chunk(c) for c in chunks] diff --git a/src/services/problem_service.py b/src/services/problem_service.py index 33064e2..6e8c1ca 100644 --- a/src/services/problem_service.py +++ b/src/services/problem_service.py @@ -66,7 +66,9 @@ def get_random_problem(self, category_name=None, tag_name=None, limit=1): return enriched - + def update_problem_title(self, problem_id, new_title): + """ Update problem title """ + return self.problem_repo.update_title_by_id(problem_id, new_title) def add_test_cases(self, problem_id, testcases): """ Add multiple test cases to problem """