diff options
Diffstat (limited to 'c++')
| -rw-r--r-- | c++/lights_out.cpp | 62 |
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(){ |
