summaryrefslogtreecommitdiff
path: root/c++
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2026-10-28 21:14:24 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2026-10-28 21:14:24 +0100
commitaeedc7e99ffdbbee2f4c2366a137230af003c3e3 (patch)
treed184bcce3c69e819e04a45d73742eb49a1124559 /c++
parentccc2b17ebb5b24893fc805e198efd0ac55871971 (diff)
downloadapps-lights_out-aeedc7e99ffdbbee2f4c2366a137230af003c3e3.tar.gz
Fixing some bugs and reworking the dispatching
Diffstat (limited to 'c++')
-rw-r--r--c++/lights_out.cpp62
1 files changed, 28 insertions, 34 deletions
diff --git a/c++/lights_out.cpp b/c++/lights_out.cpp
index ae225d5..7dc8dc1 100644
--- a/c++/lights_out.cpp
+++ b/c++/lights_out.cpp
@@ -20,8 +20,6 @@ struct point {
size_t x,y;
point& inc() {
- point& ret = *this;
-
++y;
if(y >= NN){
++x;
@@ -32,7 +30,7 @@ struct point {
}
size_t stride() const {
- return x + y*NN;
+ return x*NN + y;
}
bool equal(const point& rhs) const {
@@ -101,22 +99,16 @@ bool lu_decompose_gf2(Mat<MM,NN>& R, std::array<size_t,MM*NN>& P){
}
template<uint64_t MM, uint64_t NN>
-int solve_lights_out(std::array<int8_t,MM*NN>& b_raw){
- Mat<M,N> A;
- constexpr size_t MN = M*N;
-
- Vec<M,N> b{
- 1,0,1,
- 1,0,1,
- 0,0,0
- };
+int solve_lights_out(const Vec<MM,NN>& b, Vec<MM,NN>& x){
+ Mat<MM,NN> A;
+ constexpr size_t MMNN = MM*NN;
// Works best if we use odd N's
// even N might not be solvable in roughly half of the cases
// Init
std::cout<<"Init"<<std::endl;
- for(point<M,N> i{}; i.x < M && i.y < N; i.inc()){
- for(point<M,N> j{}; j.x < M && j.y < N; j.inc()){
+ for(point<MM,NN> i{}; i.x < MM && i.y < NN; i.inc()){
+ for(point<MM,NN> j{}; j.x < MM && j.y < NN; j.inc()){
if(
(i.equal(j)) ||
(i.x == j.x && (i.y+1) == j.y) ||
@@ -133,34 +125,29 @@ int solve_lights_out(std::array<int8_t,MM*NN>& b_raw){
// Populate how you like it.
//b[i.stride()] = false;
}
- std::array<size_t, MN> P_ident;
- std::iota(P_ident.begin(),P_ident.end(),0);
- print_mat<M,N>(A,P_ident);
-
- std::array<size_t, MN> P;
+ std::array<size_t, MMNN> P;
std::iota(P.begin(),P.end(),0);
// Solve it :)
std::cout<<"Solve"<<std::endl;
- if(!lu_decompose_gf2<M,N>(A,P)){
+ if(!lu_decompose_gf2<MM,NN>(A,P)){
return -1;
}
- std::array<size_t,MN> P_inv{};
- for(size_t i = 0; i < MN; ++i){
+ std::array<size_t,MMNN> P_inv{};
+ for(size_t i = 0; i < MMNN; ++i){
P_inv[P[i]] = i;
}
- Vec<M,N> y;
- for(size_t i = 0; i < MN; ++i){
+ Vec<MM,NN> y;
+ for(size_t i = 0; i < MMNN; ++i){
y[i] = b[P[i]];
for(size_t j = 0; j < i; ++j){
y[i] ^= A[P[i]][j] & y[j];
}
}
- Vec<M,N> x;
- for(size_t i = MN; i > 0; --i){
+ for(size_t i = MMNN; i > 0; --i){
x[i-1] = y[i-1];
- for(size_t j = i; j < MN; ++j){
+ for(size_t j = i; j < MMNN; ++j){
x[i-1] ^= (A[P[i-1]][j] and x[j]);
}
}
@@ -169,14 +156,21 @@ int solve_lights_out(std::array<int8_t,MM*NN>& b_raw){
}
extern "C"{
-int solve_lights_out_3_x_3(std::array<int8_t, 3u*3u>& inp){
- int rc = solve_lights_out<3u,3u>(inp);
- return rc;
-}
+int solve_lights_out_dispatch(int8_t* b, int m, int n){
+ if ( m == 3 and n == 3){
+ Vec<3,3> b_raw;
+ Vec<3,3> x;
-int solve_lights_out_5_x_5(std::array<int8_t, 5u*5u>& inp){
- int rc = solve_lights_out<5u,5u>(inp);
- return rc;
+ auto rc = solve_lights_out<3,3>(b_raw,x);
+ if(rc == 0) {
+ for(point<3,3> i{}; i.x < 3 && i.y < 3; i.inc()){
+ auto is = i.stride();
+ b[is] = x[is];
+ }
+ }
+ return rc;
+ }
+ return -2;
}
int fake_main(){