solver state and module glue

This commit is contained in:
2025-05-30 21:01:07 +03:00
parent 038cc36b78
commit d83f4e04dc
2 changed files with 83 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
pub mod candidate;
pub mod csp;
pub mod state;
pub use csp::{SolveResult, solve};
+78
View File
@@ -0,0 +1,78 @@
use crate::dict::index::WordIndex;
use crate::grid::slot::Slot;
pub struct SolverState {
pub assignments: Vec<Option<usize>>,
pub used_words: Vec<bool>,
pub grid_letters: Vec<Vec<Option<u8>>>,
pub cell_domains: Vec<Vec<u32>>,
pub width: usize,
pub height: usize,
}
impl SolverState {
pub fn new(slots: &[Slot], width: usize, height: usize, dict_size: usize) -> Self {
let all_bits = (1u32 << 26) - 1;
Self {
assignments: vec![None; slots.len()],
used_words: vec![false; dict_size],
grid_letters: vec![vec![None; width]; height],
cell_domains: vec![vec![all_bits; width]; height],
width,
height,
}
}
pub fn init_domains(&mut self, slots: &[Slot], dict: &WordIndex) {
for slot in slots {
for (pos, &(r, c)) in slot.cells().iter().enumerate() {
let allowed = dict.allowed_letters(slot.length, pos);
if allowed != 0 {
self.cell_domains[r][c] &= allowed;
}
}
}
}
pub fn get_domain(&self, r: usize, c: usize) -> u32 {
self.cell_domains[r][c]
}
pub fn set_domain(&mut self, r: usize, c: usize, domain: u32) {
self.cell_domains[r][c] = domain;
}
pub fn get_letter(&self, row: usize, col: usize) -> Option<u8> {
self.grid_letters[row][col]
}
pub fn set_letter(&mut self, row: usize, col: usize, letter: u8) {
self.grid_letters[row][col] = Some(letter);
}
pub fn clear_letter(&mut self, row: usize, col: usize) {
self.grid_letters[row][col] = None;
}
pub fn mark_used(&mut self, word_idx: usize) {
self.used_words[word_idx] = true;
}
pub fn unmark_used(&mut self, word_idx: usize) {
self.used_words[word_idx] = false;
}
pub fn is_used(&self, word_idx: usize) -> bool {
self.used_words[word_idx]
}
pub fn current_constraints(&self, slot: &Slot) -> Vec<(usize, u8)> {
let mut constraints = Vec::new();
for (pos, (r, c)) in slot.cells().iter().enumerate() {
if let Some(letter) = self.get_letter(*r, *c) {
constraints.push((pos, letter));
}
}
constraints
}
}