用selen 4x4数独新版求解程序改写的16x16版本
原版4x4程序位于0.12版selen源代码的example_backup目录。
//! Simple Sudoku Solver (New API)
//!
//! This example demonstrates solving a simple 4x4 Sudoku puzzle using the new unified API.
//!
//! Demonstrates:
//! - m.ints() for creating multiple variables
//! - m.alldiff() for all-different constraints
//! - m.new(var.eq(int(value))) for setting known valuesuse selen::prelude::*;fn main() {println!("🔢 Simple 4x4 Sudoku Solver (New API)");println!("====================================\n");// Create a 4x4 Sudoku puzzle// Puzzle:// 1 _ _ _// _ _ 2 _// _ 3 _ _// _ _ _ 4let mut m = Model::default();// Create 16 variables for the 4x4 grid (values 1-4)let cells = m.ints(256, 1, 16);// Helper to get cell indexlet cell = |row: usize, col: usize| cells[row * 16 + col];// Set known values using runtime API with explicit int() constants//m.new(cell(0, 0).eq(int(1)));//m.new(cell(1, 2).eq(int(2)));//m.new(cell(2, 1).eq(int(3)));//m.new(cell(3, 3).eq(int(4)));
let grid: &'static str ="
--A----C-----O-I
-J--A-B-P-CGF-H-
--D--F-I-E----P-
-G-EL-H----M-J--
----E----C--G---
-I--K-GA-B---E-J
D-GP--J-F----A--
-E---C-B--DP--O-
E--F-M--D--L-K-A
-C--------O-I-L-
H-P-C--F-A--B---
---G-OD---J----H
K---J----H-A-P-L
--B--P--E--K--A-
-H--B--K--FI-C--
--F---C--D--H-N-
";
let mut i=0;
let mut chars: Vec< char > = grid.replace("\n","").chars().collect(); for row in 0..16 {for col in 0..16 {if chars[i].is_ascii_uppercase(){m.new(cell(row, col).eq( (chars[i] as i32) - ('A' as i32) + 1));i+=1;}else {i+=1}}}// Row constraints - each row must have all different valuesfor row in 0..16 {let row_cells: Vec<_> = (0..16).map(|col| cell(row, col)).collect();m.alldiff(&row_cells);}// Column constraints - each column must have all different valuesfor col in 0..16 {let col_cells: Vec<_> = (0..16).map(|row| cell(row, col)).collect();m.alldiff(&col_cells);}// 2x2 box constraints - each box must have all different valuesfor box_row in 0..4 {for box_col in 0..4 {let mut box_cells = Vec::new();for r in 0..4 {for c in 0..4 {box_cells.push(cell(box_row * 4 + r, box_col * 4 + c));}}m.alldiff(&box_cells);}}println!("🔍 Solving...");match m.solve() {Ok(solution) => {println!("✅ Solution found!\n");// Print the solutionfor row in 0..16 {for col in 0..16 {let val = solution.get_int(cell(row, col));print!(" {} ", val);}println!();}}Err(_) => {println!("❌ No solution found!");}}
}
吭哧吭哧跑了几十秒,没有算出结果,而相应的c程序只要7ms
Running `target/release/examples/sudoku_16x16`
🔢 Simple 4x4 Sudoku Solver (New API)
====================================🔍 Solving...
❌ No solution found!
sudo16
--A----C-----O-I
-J--A-B-P-CGF-H-
--D--F-I-E----P-
-G-EL-H----M-J--
----E----C--G---
-I--K-GA-B---E-J
D-GP--J-F----A--
-E---C-B--DP--O-
E--F-M--D--L-K-A
-C--------O-I-L-
H-P-C--F-A--B---
---G-OD---J----H
K---J----H-A-P-L
--B--P--E--K--A-
-H--B--K--FI-C--
--F---C--D--H-N-
FPAHMJECNLBDKOGI
OJMIANBDPKCGFLHE
LNDKGFOIJEAHMBPC
BGCELKHPOFIMAJDN
MFHBELPOACKJGNID
CILNKDGAHBMOPEFJ
DOGPIHJMFNLECAKB
JEKAFCNBGIDPLHOM
EBOFPMIJDGHLNKCA
NCJDHBAEKMOFIGLP
HMPLCGKFIAENBDJO
AKIGNODLBPJCEFMH
KDEMJIFNCHGAOPBL
GLBCDPMHEONKJIAF
PHNOBALKMJFIDCEG
IAFJOECGLDPBHMNKTime:7 Ms
抄录c代码如下,原始出处。
#include <cstdio>
#include <cstring>
#include <ctime>
//#include <windows.h>
const int XSIZE = 4; //16*16的数独
const int _SIZE = XSIZE * XSIZE;
const int MAX_SUDOKU = _SIZE * _SIZE; //数独矩阵大小
const int MAX_C = _SIZE * _SIZE * 4; //最大列
const int MAX_R = _SIZE * _SIZE * _SIZE; //最大行
const int MAX_LINK = MAX_C * MAX_R; //链表最大范围int L[MAX_LINK],R[MAX_LINK],U[MAX_LINK],D[MAX_LINK]; //抽象链表
int C[MAX_LINK],O[MAX_LINK],S[MAX_C],H[MAX_R]; //C&O代表列&行,S每一列的节点数,H每一行的第一个节点
int NodeNumber,RecordNumber; //用来指向节点
int ans[MAX_SUDOKU],record[MAX_R];
//////////////////////Dancing Links模版//////////////////////
void init(void); //Dancing Links的抽象链表初始化
void insert(int,int); //在链表的一个位置中添加标记
void remove(int); //删除一列,同时删除这一列中的行
void resume(int); //恢复一列,同时恢复这一列中的行
//////////////////////Dancing Links模版//////////////////////
char state[MAX_SUDOKU];
bool input(void)
{char buffer[_SIZE+1][_SIZE+1]; //留一个位置给'\0' if(scanf("%s",buffer[0])==EOF)return false;for(int i=1;i<_SIZE;i++)scanf("%s",buffer[i]);for(int i=0;i<_SIZE;i++)for(int j=0;j<_SIZE;j++){if(buffer[i][j]=='-')state[i*_SIZE+j]=0;elsestate[i*_SIZE+j]=buffer[i][j]-'A'+1;}return true;
}void add(int i,int j,int k)
{int row=i*MAX_SUDOKU+j*_SIZE+k+1; //行号 insert(row,i*_SIZE + j + 1); //格子有没有数字 insert(row,i*_SIZE + k + MAX_SUDOKU + 1); //行上有没有相同的数字 insert(row,j*_SIZE + MAX_SUDOKU * 2 + k + 1); //列上有没有相同的数字 insert(row,(i/XSIZE*XSIZE + j/XSIZE) * _SIZE + MAX_SUDOKU * 3 + k + 1); //XSIZE*XSIZE的小矩阵有没有相同的数字
}void build(void)
{int pos;for(int i=0;i<_SIZE;i++)for(int j=0;j<_SIZE;j++){pos=i*_SIZE+j;if(state[pos])add(i,j,state[pos]-1);elsefor(int k=0;k<_SIZE;k++)add(i,j,k); }
}bool dfs(int k)
{if(R[0]==0){RecordNumber=k;return true; }int count=MAX_R,c;for(int i=R[0];i;i=R[i]){if(S[i]<count){count=S[i];c=i;if(count==1)break; }}remove(c);for(int i=D[c];i!=c;i=D[i]){for(int j=R[i];j!=i;j=R[j])remove(C[j]);record[k]=O[i];if(dfs(k+1))return true;for(int j=L[i];j!=i;j=L[j])resume(C[j]);}resume(c);return false;
}void output()
{for(int i=0;i<RecordNumber;++i){ans[(record[i] - 1) / _SIZE] = ((record[i] - 1) % _SIZE) + 1;}for(int i=0;i<_SIZE;++i){for(int j=0;j<_SIZE;++j){printf("%c", ans[i * _SIZE + j] + 'A' - 1);}printf("\n");}printf("\n");
}int main()
{while(input()){time_t start=clock();init();build();dfs(0);output();printf("Time:%ld Ms\n",clock()-start);}//system("pause");
}//////////////////////Dancing Links模版//////////////////////
void init(void)
{for(int i=0;i<=MAX_C;i++){L[i]=i-1;R[i]=i+1;U[i]=i;D[i]=i;C[i]=i;O[i]=0; }L[0]=MAX_C;R[MAX_C]=0;NodeNumber=MAX_C+1;RecordNumber=0;memset(S,0,sizeof(S));memset(H,0,sizeof(H));
}void insert(int i,int j) //行号,列号
{if(H[i]){L[NodeNumber]=L[H[i]];R[NodeNumber]=H[i];L[R[NodeNumber]]=NodeNumber;R[L[NodeNumber]]=NodeNumber;}else{L[NodeNumber]=NodeNumber;R[NodeNumber]=NodeNumber;H[i]=NodeNumber;}U[NodeNumber]=U[j];D[NodeNumber]=j;U[D[NodeNumber]]=NodeNumber;D[U[NodeNumber]]=NodeNumber;C[NodeNumber]=j;O[NodeNumber]=i;S[j]++;NodeNumber++;
}void remove(int c)
{L[R[c]]=L[c];R[L[c]]=R[c];for(int i=D[c];i!=c;i=D[i]){for(int j=R[i];j!=i;j=R[j]){U[D[j]]=U[j];D[U[j]]=D[j];S[C[j]]--;}}
}void resume(int c)
{for(int i=U[c];i!=c;i=U[i]){for(int j=L[i];j!=i;j=L[j]){U[D[j]]=j;D[U[j]]=j;S[C[j]]++;} }L[R[c]]=c;R[L[c]]=c;
}
/*
--A----C-----O-I
-J--A-B-P-CGF-H-
--D--F-I-E----P-
-G-EL-H----M-J--
----E----C--G---
-I--K-GA-B---E-J
D-GP--J-F----A--
-E---C-B--DP--O-
E--F-M--D--L-K-A
-C--------O-I-L-
H-P-C--F-A--B---
---G-OD---J----H
K---J----H-A-P-L
--B--P--E--K--A-
-H--B--K--FI-C--
--F---C--D--H-N-
*/
我让DeepSeek翻译了一版rust程序,编译没问题,但输入棋盘后,报错了。
thread 'main' panicked at examples/dlx16.rs:80:15:
index out of bounds: the len is 1024 but the index is 1024