From 6c855f985c7c4d5217ff85382d4f62cdf808507a Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Wed, 18 Jun 2025 16:34:48 +0200 Subject: Initial commit copied from my godbolt impl --- c++/lights_out.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 c++/lights_out.cpp diff --git a/c++/lights_out.cpp b/c++/lights_out.cpp new file mode 100644 index 0000000..9b8503f --- /dev/null +++ b/c++/lights_out.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include + +constexpr size_t M = 3; +constexpr size_t N = 3; +constexpr size_t MN = M * N; +using Mat = std::array,MN>; +using Vec = std::array; + +struct point { + point():x{0},y{0}{} + point(size_t x_, size_t y_):x{x_},y{y_}{} + + size_t x,y; + + point& inc() { + point& ret = *this; + + ++y; + if(y >= N){ + ++x; + y -= N; + } + + return *this; + } + + size_t stride() const { + return x + y*N; + } + + bool equal(const point& rhs) const { + return (x == rhs.x && y == rhs.y); + } +}; + +void print_vec(const Vec& x){ + for(size_t j = 0; j < N; ++j){ + for(size_t i = 0; i < M; ++i){ + point ind{i,j}; + std::cout<& x){ + for(size_t j = 0; j < MN; ++j){ + std::cout<& P){ + for(size_t j = 0; j < MN; ++j){ + for(size_t i = 0; i < MN; ++i){ + std::cout<& P){ + for(size_t i = 0; i < MN; ++i){ + bool found_pivot = false; + size_t pivot_row = i; + for(size_t k = i; k < MN && (not found_pivot); ++k){ + if(R[P[k]][i]){ + found_pivot = true; + pivot_row = k; + } + } + if(not found_pivot){ + return false; + }else if ( i != pivot_row ){ + std::swap(P[i],P[pivot_row]); + } + for(size_t k = i+1u; k < MN; ++k){ + + if(R[P[k]][i]){ + for(size_t j = i+1u; j < MN; ++j){ + R[P[k]][j] ^= (R[P[i]][j]); + } + } + } + } + + return true; +} + +int main(){ + Mat A; + + Vec b{ + 1,0,1, + 1,0,1, + 0,0,0 + }; + + // Works best if we use odd N's + // even N might not be solvable in roughly half of the cases + // Init + std::cout<<"Init"< P_ident; + std::iota(P_ident.begin(),P_ident.end(),0); + print_mat(A,P_ident); + + std::array P; + std::iota(P.begin(),P.end(),0); + // Solve it :) + std::cout<<"Solve"< P_inv{}; + for(size_t i = 0; i < MN; ++i){ + P_inv[P[i]] = i; + } + + std::cout<<"LR"< 0; --i){ + x[i-1] = y[i-1]; + for(size_t j = i; j < MN; ++j){ + x[i-1] ^= (A[P[i-1]][j] and x[j]); + } + } + + std::cout<<"Solution"<