Skip to content

Commit

Permalink
refactor; change the grading standard
Browse files Browse the repository at this point in the history
  • Loading branch information
Nervonment committed Jun 6, 2024
1 parent 786705a commit 10483fd
Show file tree
Hide file tree
Showing 13 changed files with 854 additions and 531 deletions.
15 changes: 7 additions & 8 deletions benches/solver_benches.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
use criterion::{criterion_group, criterion_main, Criterion};
use sudoku::{
generator::random_sudoku_puzzle,
puzzle::{SudokuPuzzleFull, SudokuPuzzleSimple},
solver::{Solver, StochasticSolver, TechniquesSolver},
solver::{advanced::AdvancedSolver, stochastic::StochasticSolver, Solver},
state::{full_state::FullState, simple_state::SimpleState},
};

fn benchmarks(c: &mut Criterion) {
let puzzle = random_sudoku_puzzle::<
StochasticSolver<SudokuPuzzleSimple>,
TechniquesSolver<SudokuPuzzleFull>,
>(45, 100, 10000);
let mut solver = StochasticSolver::<SudokuPuzzleSimple>::new(puzzle);
let puzzle = random_sudoku_puzzle::<StochasticSolver<SimpleState>, AdvancedSolver<FullState>, f32>(
45, 0.0, 1000.0,
);
let mut solver = StochasticSolver::<SimpleState>::from(puzzle);
c.bench_function("StochasticSolver", |b| {
b.iter(|| {
solver.any_solution();
})
});
let mut solver = TechniquesSolver::<SudokuPuzzleFull>::new(puzzle);
let mut solver = AdvancedSolver::<FullState>::from(puzzle);
c.bench_function("TechniquesSolver", |b| {
b.iter(|| {
solver.any_solution();
Expand Down
21 changes: 9 additions & 12 deletions src/bin/example.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
use sudoku::{
generator::random_sudoku_puzzle,
puzzle::{Grid, SudokuPuzzleFull, SudokuPuzzleSimple},
solver::{Grader, Solver, StochasticSolver, TechniquesSolver},
solver::{advanced::AdvancedSolver, stochastic::StochasticSolver, Grader, Solver},
state::{full_state::FullState, simple_state::SimpleState},
techniques::{
hidden_pair_blk, hidden_pair_col, hidden_pair_row, hidden_single_blk, hidden_single_col,
hidden_single_row, naked_pair_blk, naked_pair_col, naked_pair_row, naked_single, pointing,
},
}, Grid,
};

fn main() {
let board = random_sudoku_puzzle::<
StochasticSolver<SudokuPuzzleSimple>,
TechniquesSolver<SudokuPuzzleFull>,
>(45, 800, 100000);
let puzzle = SudokuPuzzleFull::new(board);
// TODO: print the puzzle
println!("");
let board = random_sudoku_puzzle::<StochasticSolver<SimpleState>, AdvancedSolver<FullState>, f32>(
45, 140.0, 2000.0,
);
let puzzle = FullState::from(board);
println!("{}", Grid(board));
let res_hidden_single_row = hidden_single_row(&puzzle);
let res_hidden_single_col = hidden_single_col(&puzzle);
let res_hidden_single_blk = hidden_single_blk(&puzzle);
Expand All @@ -38,8 +36,7 @@ fn main() {
println!("naked pair in col: {:?}", res_naked_pair_col);
println!("naked pair in blk: {:?}", res_naked_pair_blk);
println!("pointing: {:?}", res_pointing);
let mut solver2 = TechniquesSolver::<SudokuPuzzleFull>::new(board);
let mut solver2 = AdvancedSolver::<FullState>::from(board);
solver2.have_unique_solution();
println!("{}", solver2.difficulty());
println!("{:?}", board);
}
19 changes: 10 additions & 9 deletions src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ use rand::random;

use super::solver::{Grader, Solver};

pub fn random_sudoku_puzzle<T1, T2>(
min_blank_cnt: i32, // 需要生成的题目最少空格数
min_difficulty: i32, // 题目最小难度分数
max_difficulty: i32, // 题目最大难度分数
pub fn random_sudoku_puzzle<S1, S2, T>(
min_blank_cnt: i32, // 需要生成的题目最少空格数
min_difficulty: T, // 题目最小难度分数
max_difficulty: T, // 题目最大难度分数
) -> [[i8; 9]; 9]
where
T1: Solver,
T2: Solver + Grader,
S1: Solver + From<[[i8; 9]; 9]>,
S2: Solver + Grader<T> + From<[[i8; 9]; 9]>,
T: PartialOrd + From<i8>
{
loop {
// 生成随机终局
let mut puzzle = T1::new([[0; 9]; 9]).any_solution().unwrap();
let mut puzzle = S1::from([[0; 9]; 9]).any_solution().unwrap();

let mut dug = 0; // 已经挖掉的空格数
let mut trace = vec![]; // 挖空历史记录
Expand All @@ -24,7 +25,7 @@ where
let mut trace_back_cnt = 0; // 回退的次数
let trace_back_cnt_threshold = 12; // 回退次数阈值,回退次数超过此值会尝试重新生成终局

let mut difficulty = -1; // 搜索函数在此题目上调用的次数
let mut difficulty: T = 0.into(); // 搜索函数在此题目上调用的次数

while trace_back_cnt < trace_back_cnt_threshold
&& !(dug >= min_blank_cnt
Expand All @@ -48,7 +49,7 @@ where
}

// 挖空后,判断是否有唯一解
let mut solver = T2::new(puzzle);
let mut solver = S2::from(puzzle);
if solver.have_unique_solution() {
difficulty = solver.difficulty();
break;
Expand Down
155 changes: 150 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,153 @@
pub mod puzzle;
use std::fmt::Display;

pub mod generator;
pub mod judge;
pub mod solver;
pub mod state;
pub mod techniques;
#[cfg(test)]
mod test;
pub mod utils;
pub mod techniques;
pub mod solver;
pub mod judge;
pub mod generator;

pub struct Grid(pub [[i8; 9]; 9]);

impl Display for Grid {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let grid = self.0.map(|row| {
row.map(|cell| {
if cell > 0 {
(cell as u8 + 48) as char
} else {
' '
}
})
});
writeln!(f, "┏━━━┯━━━┯━━━┳━━━┯━━━┯━━━┳━━━┯━━━┯━━━┓")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[0][0],
grid[0][1],
grid[0][2],
grid[0][3],
grid[0][4],
grid[0][5],
grid[0][6],
grid[0][7],
grid[0][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[1][0],
grid[1][1],
grid[1][2],
grid[1][3],
grid[1][4],
grid[1][5],
grid[1][6],
grid[1][7],
grid[1][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[2][0],
grid[2][1],
grid[2][2],
grid[2][3],
grid[2][4],
grid[2][5],
grid[2][6],
grid[2][7],
grid[2][8],
)?;
writeln!(f, "┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[3][0],
grid[3][1],
grid[3][2],
grid[3][3],
grid[3][4],
grid[3][5],
grid[3][6],
grid[3][7],
grid[3][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[4][0],
grid[4][1],
grid[4][2],
grid[4][3],
grid[4][4],
grid[4][5],
grid[4][6],
grid[4][7],
grid[4][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[5][0],
grid[5][1],
grid[5][2],
grid[5][3],
grid[5][4],
grid[5][5],
grid[5][6],
grid[5][7],
grid[5][8],
)?;
writeln!(f, "┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[6][0],
grid[6][1],
grid[6][2],
grid[6][3],
grid[6][4],
grid[6][5],
grid[6][6],
grid[6][7],
grid[6][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[7][0],
grid[7][1],
grid[7][2],
grid[7][3],
grid[7][4],
grid[7][5],
grid[7][6],
grid[7][7],
grid[7][8],
)?;
writeln!(f, "┠───┼───┼───╂───┼───┼───╂───┼───┼───┨")?;
writeln!(
f,
"┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃ {} │ {} │ {} ┃",
grid[8][0],
grid[8][1],
grid[8][2],
grid[8][3],
grid[8][4],
grid[8][5],
grid[8][6],
grid[8][7],
grid[8][8],
)?;
write!(f, "┗━━━┷━━━┷━━━┻━━━┷━━━┷━━━┻━━━┷━━━┷━━━┛")
}
}
Loading

0 comments on commit 10483fd

Please sign in to comment.