solve-sudoku-text
Input a Sudoku puzzle in text format to generate the solved solution effortlessly using the MCP server's dedicated solver tool.
Instructions
Solve a Sudoku puzzle from text input
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| puzzle | Yes | The Sudoku puzzle in text format |
Implementation Reference
- src/sodukusolver/server.py:284-331 (handler)Handler for the 'solve-sudoku-text' tool: parses text input, solves the Sudoku, stores puzzles, and returns formatted original and solution grids.elif name == "solve-sudoku-text": puzzle_text = arguments.get("puzzle") if not puzzle_text: raise ValueError("Missing puzzle") try: # Parse the puzzle grid = parse_sudoku_text(puzzle_text) # Make a copy of the grid to solve original_grid = [row[:] for row in grid] # Solve the puzzle if solveSudoku(grid): # Store both the original and solved puzzles timestamp = asyncio.get_event_loop().time() puzzle_name = f"puzzle_{int(timestamp)}" sudoku_puzzles[puzzle_name] = original_grid sudoku_puzzles[f"{puzzle_name}_solved"] = grid # Notify clients that resources have changed await server.request_context.session.send_resource_list_changed() # Return formatted solution original_formatted = format_sudoku_grid(original_grid) solution_formatted = format_sudoku_grid(grid) return [ types.TextContent( type="text", text=f"Original Sudoku puzzle:\n\n{original_formatted}\n\nSolution:\n\n{solution_formatted}", ) ] else: return [ types.TextContent( type="text", text=f"No solution found for the given Sudoku puzzle", ) ] except ValueError as e: return [ types.TextContent( type="text", text=f"Error parsing Sudoku puzzle: {str(e)}", ) ]
- src/sodukusolver/server.py:163-173 (registration)Registration of the 'solve-sudoku-text' tool in the list_tools handler, including its schema.types.Tool( name="solve-sudoku-text", description="Solve a Sudoku puzzle from text input", inputSchema={ "type": "object", "properties": { "puzzle": {"type": "string", "description": "The Sudoku puzzle in text format"}, }, "required": ["puzzle"], }, )
- src/sodukusolver/solver.py:70-94 (helper)Core backtracking Sudoku solver using bitmasks for efficient row/column/box tracking.def solveSudoku(mat): """ Solve a Sudoku puzzle. Args: mat: The Sudoku grid (9x9 matrix) with 0s for empty cells Returns: bool: True if solved successfully, False otherwise """ n = len(mat) row = [0] * n col = [0] * n box = [0] * n # Set the bits in bitmasks for values that are initially present for i in range(n): for j in range(n): if mat[i][j] != 0: row[i] |= (1 << mat[i][j]) col[j] |= (1 << mat[i][j]) box[(i // 3) * 3 + j // 3] |= (1 << mat[i][j]) return sudokuSolverRec(mat, 0, 0, row, col, box)
- src/sodukusolver/solver.py:95-173 (helper)Parses flexible text input (single/multi-line, separators) into a validated 9x9 Sudoku grid.def parse_sudoku_text(text): """ Parse a Sudoku puzzle from text input. The input can be in various formats: - Space or comma-separated values (0 or . for empty cells) - Multiple lines representing rows Args: text: String containing the Sudoku puzzle Returns: list: 9x9 matrix representing the Sudoku puzzle """ # Initialize an empty 9x9 grid grid = [] # Split the input into lines lines = [line.strip() for line in text.strip().split('\n') if line.strip()] # If we have a single line, try to parse it as a flat representation if len(lines) == 1: # Replace common separators with spaces flat = lines[0].replace(',', ' ').replace(';', ' ') # Replace dots with zeros flat = flat.replace('.', '0') # Split by whitespace and filter out empty strings values = [v for v in flat.split() if v] # Check if we have enough values if len(values) != 81: raise ValueError(f"Expected 81 values for a 9x9 Sudoku, got {len(values)}") # Create the 9x9 grid for i in range(9): row = [] for j in range(9): cell = values[i * 9 + j] try: row.append(int(cell)) except ValueError: raise ValueError(f"Invalid Sudoku value: {cell}") grid.append(row) else: # Parse multiple lines for line in lines: if not line.strip(): continue # Replace dots with zeros and remove other common separators line = line.replace('.', '0').replace(',', ' ').replace(';', ' ') # Split and filter values = [v for v in line.split() if v] row = [] for cell in values: try: row.append(int(cell)) except ValueError: raise ValueError(f"Invalid Sudoku value: {cell}") if row: grid.append(row) # Validate the grid dimensions if len(grid) != 9: raise ValueError(f"Expected 9 rows for Sudoku, got {len(grid)}") for i, row in enumerate(grid): if len(row) != 9: raise ValueError(f"Expected 9 columns in row {i}, got {len(row)}") # Validate the values (0-9 only) for i in range(9): for j in range(9): if not 0 <= grid[i][j] <= 9: raise ValueError(f"Invalid value {grid[i][j]} at position ({i}, {j})") return grid
- src/sodukusolver/solver.py:175-203 (helper)Formats 9x9 Sudoku grid into a readable string with borders.def format_sudoku_grid(grid): """ Format a Sudoku grid for display. Args: grid: 9x9 Sudoku grid Returns: str: Formatted string representation of the grid """ result = [] horizontal_line = "+-------+-------+-------+" for i in range(9): if i % 3 == 0: result.append(horizontal_line) row = "| " for j in range(9): row += str(grid[i][j]) + " " if (j + 1) % 3 == 0: row += "| " result.append(row) result.append(horizontal_line) return "\n".join(result)