11mod solver;
22mod strategy;
3- mod sudoku ;
3+ mod sodo ;
44
5- pub use solver:: { Difficulty , SolverStats , SudokuSolver } ;
6- pub use strategy:: { get_all_strategies , SolvingStrategy } ;
7- pub use sudoku :: { Cell , Sudoku } ;
5+ pub use solver:: { Difficulty , Solver , Stats } ;
6+ pub use strategy:: { all as all_strategies , Strategy } ;
7+ pub use sodo :: { Cell , Sudoku } ;
88
99use std:: { fs, process} ;
1010
11- fn parse_size ( size_str : & str ) -> usize {
12- size_str . parse ( ) . unwrap_or_else ( |_| {
13- eprintln ! ( "Invalid size: {size_str }" ) ;
11+ fn parse_size ( s : & str ) -> usize {
12+ s . parse ( ) . unwrap_or_else ( |_| {
13+ eprintln ! ( "Invalid size: {s }" ) ;
1414 process:: exit ( 1 )
1515 } )
1616}
1717
18- fn parse_puzzle ( puzzle_str : & str , size : usize ) -> Sudoku {
19- Sudoku :: from_string ( puzzle_str , size) . unwrap_or_else ( |e| {
18+ fn parse_puzzle ( s : & str , size : usize ) -> Sudoku {
19+ Sudoku :: from_string ( s , size) . unwrap_or_else ( |e| {
2020 eprintln ! ( "Error parsing puzzle: {e}" ) ;
2121 process:: exit ( 1 )
2222 } )
2323}
2424
25+ /// Solves a puzzle from string.
2526pub fn solve_puzzle ( puzzle_str : & str , size_str : & str ) {
2627 let size = parse_size ( size_str) ;
2728 let puzzle = parse_puzzle ( puzzle_str, size) ;
2829
2930 println ! ( "Original puzzle:" ) ;
3031 println ! ( "{puzzle}" ) ;
3132
32- let mut solver = SudokuSolver :: new ( ) ;
33+ let mut solver = Solver :: new ( ) ;
3334
3435 match solver. solve_with_stats ( puzzle) {
3536 Ok ( ( solution, stats) ) => {
3637 println ! ( "Solution found!" ) ;
3738 println ! ( "{solution}" ) ;
38- println ! ( "\n Solver Statistics :" ) ;
39- println ! ( "Iterations: {}" , stats. iterations) ;
40- println ! ( "Cells filled: {}" , stats. cells_filled) ;
41- println ! ( "Backtrack steps : {}" , stats. backtrack_steps ) ;
42- println ! ( "Strategies used :" ) ;
43- for ( strategy , count) in stats. strategies_used {
44- println ! ( " {strategy }: {count}" ) ;
39+ println ! ( "\n Statistics :" ) ;
40+ println ! ( " Iterations: {}" , stats. iterations) ;
41+ println ! ( " Cells filled: {}" , stats. cells_filled) ;
42+ println ! ( " Backtracks : {}" , stats. backtracks ) ;
43+ println ! ( " Strategies :" ) ;
44+ for ( name , count) in & stats. strategies_used {
45+ println ! ( " {name }: {count}" ) ;
4546 }
4647 }
4748 Err ( e) => {
48- eprintln ! ( "Failed to solve puzzle : {e}" ) ;
49+ eprintln ! ( "Failed to solve: {e}" ) ;
4950 process:: exit ( 1 ) ;
5051 }
5152 }
5253}
5354
54- pub fn solve_from_file ( file_path : & str , size_str : & str ) {
55- let puzzle_str = fs:: read_to_string ( file_path)
55+ /// Solves a puzzle from file.
56+ pub fn solve_from_file ( path : & str , size_str : & str ) {
57+ let content = fs:: read_to_string ( path)
5658 . map ( |s| s. trim ( ) . to_string ( ) )
5759 . unwrap_or_else ( |e| {
5860 eprintln ! ( "Error reading file: {e}" ) ;
5961 process:: exit ( 1 )
6062 } ) ;
61- solve_puzzle ( & puzzle_str , size_str) ;
63+ solve_puzzle ( & content , size_str) ;
6264}
6365
66+ /// Generates a puzzle.
6467pub fn generate_puzzle ( size_str : & str , difficulty_str : & str ) {
6568 let size = parse_size ( size_str) ;
6669 let difficulty = match difficulty_str. to_lowercase ( ) . as_str ( ) {
@@ -69,25 +72,26 @@ pub fn generate_puzzle(size_str: &str, difficulty_str: &str) {
6972 "hard" => Difficulty :: Hard ,
7073 "expert" => Difficulty :: Expert ,
7174 _ => {
72- eprintln ! ( "Invalid difficulty: {difficulty_str}. Use easy, medium, hard, or expert " ) ;
75+ eprintln ! ( "Invalid difficulty: {difficulty_str}" ) ;
7376 process:: exit ( 1 )
7477 }
7578 } ;
7679
77- let mut solver = SudokuSolver :: new ( ) ;
80+ let mut solver = Solver :: new ( ) ;
7881
79- match solver. generate_puzzle ( size, difficulty) {
82+ match solver. generate ( size, difficulty) {
8083 Ok ( puzzle) => {
8184 println ! ( "Generated {difficulty_str} puzzle ({size}x{size}):" ) ;
8285 println ! ( "{puzzle}" ) ;
8386 }
8487 Err ( e) => {
85- eprintln ! ( "Failed to generate puzzle : {e}" ) ;
88+ eprintln ! ( "Failed to generate: {e}" ) ;
8689 process:: exit ( 1 ) ;
8790 }
8891 }
8992}
9093
94+ /// Validates a puzzle.
9195pub fn validate_puzzle ( puzzle_str : & str , size_str : & str ) {
9296 let size = parse_size ( size_str) ;
9397 let puzzle = parse_puzzle ( puzzle_str, size) ;
@@ -96,51 +100,45 @@ pub fn validate_puzzle(puzzle_str: &str, size_str: &str) {
96100 println ! ( "{puzzle}" ) ;
97101
98102 if puzzle. is_valid ( ) {
99- println ! ( "✓ Puzzle is valid!" ) ;
100-
103+ println ! ( "Valid!" ) ;
101104 if puzzle. is_complete ( ) {
102- println ! ( "✓ Puzzle is complete and solved!" ) ;
105+ println ! ( "Complete and solved!" ) ;
103106 } else {
104- println ! ( "! Puzzle is valid but not yet complete." ) ;
107+ println ! ( "Not yet complete." ) ;
105108 }
106109 } else {
107- println ! ( "✗ Puzzle is invalid!" ) ;
108-
109- if !puzzle. is_valid_rows ( ) {
110- println ! ( " - Invalid rows detected" ) ;
110+ println ! ( "Invalid!" ) ;
111+ if !puzzle. valid_rows ( ) {
112+ println ! ( " - Invalid rows" ) ;
111113 }
112- if !puzzle. is_valid_cols ( ) {
113- println ! ( " - Invalid columns detected " ) ;
114+ if !puzzle. valid_cols ( ) {
115+ println ! ( " - Invalid columns" ) ;
114116 }
115- if !puzzle. is_valid_boxes ( ) {
116- println ! ( " - Invalid boxes detected " ) ;
117+ if !puzzle. valid_boxes ( ) {
118+ println ! ( " - Invalid boxes" ) ;
117119 }
118120 }
119121}
120122
123+ /// Gets a hint for the puzzle.
121124pub fn get_hint ( puzzle_str : & str , size_str : & str ) {
122125 let size = parse_size ( size_str) ;
123126 let mut puzzle = parse_puzzle ( puzzle_str, size) ;
124127
125128 println ! ( "Current puzzle:" ) ;
126129 println ! ( "{puzzle}" ) ;
127130
128- let mut solver = SudokuSolver :: new ( ) ;
129-
130- match solver. get_hint ( & mut puzzle) {
131- Some ( ( row, col, value) ) => {
132- println ! (
133- "Hint: Place {} at position ({}, {})" ,
134- value,
135- row + 1 ,
136- col + 1
137- ) ;
138- puzzle. set ( row, col, value) . unwrap ( ) ;
139- println ! ( "\n Puzzle with hint applied:" ) ;
131+ let solver = Solver :: new ( ) ;
132+
133+ match solver. hint ( & puzzle) {
134+ Some ( ( r, c, val) ) => {
135+ println ! ( "Hint: Place {val} at ({}, {})" , r + 1 , c + 1 ) ;
136+ let _ = puzzle. set ( r, c, val) ;
137+ println ! ( "\n With hint applied:" ) ;
140138 println ! ( "{puzzle}" ) ;
141139 }
142140 None => {
143- println ! ( "No obvious hint available. You might need to use more advanced techniques. " ) ;
141+ println ! ( "No obvious hint available." ) ;
144142 }
145143 }
146144}
0 commit comments