#![forbid(unsafe_code)]
mod sudoku;
const ABC: &str = ".123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ";
fn init(inp: &str) -> (usize, String) {
let mut sudo: String;
for i in [7, 6, 5, 4, 3, 2] {
sudo = String::new();
for mut c in inp.chars() {
if c == '0' {
c = '.'
}
if ABC[..((i * i) + 1)].chars().filter(|x| *x == c).count() == 1 {
sudo.push(c);
}
}
if sudo.len() == i * i * i * i {
return (i, sudo);
}
}
(0, String::from(""))
}
fn format_result(size: usize, inp: &str, sol_vec: Vec<String>) -> Vec<String> {
let mut res: Vec<String> = Vec::new();
for sol in sol_vec {
let mut sol_form: String = String::from("");
let mut sol_rev = sol.chars().rev().collect::<String>();
for mut c in inp.chars() {
if c == '0' {
c = '.'
}
if ABC[..((size * size) + 1)]
.chars()
.filter(|x| *x == c)
.count()
== 1
{
sol_form.push(sol_rev.pop().unwrap());
} else {
sol_form.push(c);
}
}
res.push(sol_form);
}
res
}
pub fn solve(inp: &str, cnt: usize) -> Vec<String> {
let (size, sudo) = init(inp);
if size == 0 {
return vec![String::from("Invalid input.")];
}
let mut board = sudoku::Board::new(size, &sudo);
format_result(size, inp, board.solve(cnt))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_4x4() {
assert_eq!(
solve("1234341.........", 2),
vec![
String::from("1234341221434321"),
String::from("1234341223414123")
]
);
assert_eq!(
solve("1234341000000000", 2),
vec![
String::from("1234341221434321"),
String::from("1234341223414123")
]
);
}
#[test]
fn test_9x9_format() {
assert_eq!(
solve(
"
╔═══════════╦═══════════╦═══════════╗
║ 1 │ 4 │ . ║ . │ 7 │ . ║ . │ 6 │ 5 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 5 │ . │ . ║ . │ 4 │ . ║ . │ . │ 1 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 9 │ . │ . ║ . │ . │ . ║ . │ . │ 7 ║
╠═══════════╬═══════════╬═══════════╣
║ 4 │ 2 │ 9 ║ . │ . │ . ║ 5 │ 1 │ 8 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ . │ . │ 5 ║ 2 │ . │ 8 ║ 4 │ . │ . ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 8 │ 7 │ 1 ║ . │ . │ . ║ 3 │ 2 │ 6 ║
╠═══════════╬═══════════╬═══════════╣
║ 2 │ . │ . ║ . │ . │ . ║ . │ . │ 4 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 7 │ . │ . ║ . │ 6 │ . ║ . │ . │ 3 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 3 │ 1 │ . ║ . │ 8 │ . ║ . │ 9 │ 2 ║
╚═══════════╩═══════════╩═══════════╝",
3
),
vec![String::from(
"
╔═══════════╦═══════════╦═══════════╗
║ 1 │ 4 │ 2 ║ 8 │ 7 │ 3 ║ 9 │ 6 │ 5 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 5 │ 8 │ 7 ║ 6 │ 4 │ 9 ║ 2 │ 3 │ 1 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 9 │ 6 │ 3 ║ 1 │ 2 │ 5 ║ 8 │ 4 │ 7 ║
╠═══════════╬═══════════╬═══════════╣
║ 4 │ 2 │ 9 ║ 7 │ 3 │ 6 ║ 5 │ 1 │ 8 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 6 │ 3 │ 5 ║ 2 │ 1 │ 8 ║ 4 │ 7 │ 9 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 8 │ 7 │ 1 ║ 9 │ 5 │ 4 ║ 3 │ 2 │ 6 ║
╠═══════════╬═══════════╬═══════════╣
║ 2 │ 5 │ 6 ║ 3 │ 9 │ 1 ║ 7 │ 8 │ 4 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 7 │ 9 │ 8 ║ 4 │ 6 │ 2 ║ 1 │ 5 │ 3 ║
║───┼───┼───║───┼───┼───║───┼───┼───║
║ 3 │ 1 │ 4 ║ 5 │ 8 │ 7 ║ 6 │ 9 │ 2 ║
╚═══════════╩═══════════╩═══════════╝"
)]
);
}
#[test]
fn test_error() {
assert_eq!(
solve("1234341....5....", 1),
vec![String::from("Invalid input.")]
);
assert_eq!(
solve("1234341..........", 1),
vec![String::from("Invalid input.")]
);
assert_eq!(
solve("1234341........", 1),
vec![String::from("Invalid input.")]
);
}
}