I first created my function using an imperative approach. This is just how I naturally write code most of the time. I then tried to think about the problem using a “What I want to accomplish?” approach, rather than “What do I want it to do?” In the end I think I still ended up with an imperative approach, just using STL algorithms as loops.

The code itself pre-calculates the winning combinations for an n-sized tic tac toe board.

Imperative approach:

`std::vector<std::vector<int>> rules3(const int x){ using namespace std; vector<vector<int>> seqs; for(int n=0; n<x; ++n){ vector<int> seq; for(int m=0; m<x; ++m){ seq.push_back(n*x+m); } seqs.push_back(seq); } for(int n=0; n<x; ++n){ vector<int> seq; for(int m=0; m<x; ++m){ seq.push_back(n+x*m); } seqs.push_back(seq); } vector<int> seq; for(int n=0; n<x; ++n){ seq.push_back(n*x+n); } seqs.push_back(seq); seq.clear(); for(int n=0; n<x; ++n){ seq.push_back(x-1+n*(x-1)); } seqs.push_back(seq); return seqs; } `

Getting more functional:

`std::vector<std::vector<int>> rules2(const int x){ using namespace std; vector<vector<int>> seqs; vector<int> iter(x); iota(iter.begin(), iter.end(), 0); for(auto n: iter){ vector<int> seq; for(auto m: iter){ seq.push_back(n*x+m); } seqs.push_back(seq); } for(auto n: iter){ vector<int> seq; for(auto m: iter){ seq.push_back(n+x*m); } seqs.push_back(seq); } vector<int> seq; seq.clear(); for(auto n: iter){ seq.push_back(n*x+n); } seqs.push_back(seq); seq.clear(); for(auto n: iter){ seq.push_back(x-1+n*(x-1)); } seqs.push_back(seq); return seqs; } `

Functional approach? (still feels imperative):

`std::vector<std::vector<int>> rules1(const int x){ using namespace std; vector<vector<int>> seqs; vector<int> iter(x); iota(iter.begin(), iter.end(), 0); transform(iter.begin(), iter.end(), back_inserter(seqs), [&](const int& n){ vector<int> seq; transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& m){ return n*x+m; }); return seq; }); transform(iter.begin(), iter.end(), back_inserter(seqs), [&](const int& n){ vector<int> seq; transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& m){ return n+x*m; }); return seq; }); vector<int> seq; transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& n){ return n*x+n; }); seqs.push_back(seq); seq.clear(); transform(iter.begin(), iter.end(), back_inserter(seq), [&](const int& n){ //return (x-n-1)*x+n; // 6,4,2 return x-1+n*(x-1); // 2,4,6 }); seqs.push_back(seq); return seqs; } `

Output when printing:

`rules3 std::vector(0, 1, 2) std::vector(3, 4, 5) std::vector(6, 7, 8) std::vector(0, 3, 6) std::vector(1, 4, 7) std::vector(2, 5, 8) std::vector(0, 4, 8) std::vector(2, 4, 6) rules2 std::vector(0, 1, 2) std::vector(3, 4, 5) std::vector(6, 7, 8) std::vector(0, 3, 6) std::vector(1, 4, 7) std::vector(2, 5, 8) std::vector(0, 4, 8) std::vector(2, 4, 6) rules1 std::vector(0, 1, 2) std::vector(3, 4, 5) std::vector(6, 7, 8) std::vector(0, 3, 6) std::vector(1, 4, 7) std::vector(2, 5, 8) std::vector(0, 4, 8) std::vector(2, 4, 6) `