Task: Knight's tour


C++: #include <iostream>
#include <iomanip>
#include <array>
#include <string>
#include <tuple>
#include <algorithm>
using namespace std;

template<int N = 8>
class Board 
{
public:
    array<pair<int, int>, 8> moves;
    array<array<int, N>, N> data;

    Board() 
    {
        moves[0] = make_pair(2, 1);
        moves[1] = make_pair(1, 2);
        moves[2] = make_pair(-1, 2);
        moves[3] = make_pair(-2, 1);
        moves[4] = make_pair(-2, -1);
        moves[5] = make_pair(-1, -2);
        moves[6] = make_pair(1, -2);
        moves[7] = make_pair(2, -1);
    }

    array<int, 8> sortMoves(int x, int y) const 
    {
        array<tuple<int, int>, 8> counts;
        for(int i = 0; i < 8; ++i) 
        {
            int dx = get<0>(moves[i]);
            int dy = get<1>(moves[i]);

            int c = 0;
            for(int j = 0; j < 8; ++j) 
            {
                int x2 = x + dx + get<0>(moves[j]);
                int y2 = y + dy + get<1>(moves[j]);

                if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N)
                    continue;
                if(data[y2][x2] != 0)
                    continue;

                c++;
            }

            counts[i] = make_tuple(c, i);
        }

        
        random_shuffle(counts.begin(), counts.end());

        
        sort(counts.begin(), counts.end());

        array<int, 8> out;
        for(int i = 0; i < 8; ++i)
            out[i] = get<1>(counts[i]);
        return out;
    }

    void solve(string start) 
    {
        for(int v = 0; v < N; ++v)
            for(int u = 0; u < N; ++u)
                data[v][u] = 0;

        int x0 = start[0] - 'a';
        int y0 = N - (start[1] - '0');
        data[y0][x0] = 1;

        array<tuple<int, int, int, array<int, 8>>, N*N> order;
        order[0] = make_tuple(x0, y0, 0, sortMoves(x0, y0));

        int n = 0;
        while(n < N*N-1) 
        {
            int x = get<0>(order[n]);
            int y = get<1>(order[n]);

            bool ok = false;
            for(int i = get<2>(order[n]); i < 8; ++i) 
            {
                int dx = moves[get<3>(order[n])[i]].first;
                int dy = moves[get<3>(order[n])[i]].second;

                if(x+dx < 0 || x+dx >= N || y+dy < 0 || y+dy >= N)
                    continue;
                if(data[y + dy][x + dx] != 0) 
                    continue;

                get<2>(order[n]) = i + 1;
                ++n;
                data[y+dy][x+dx] = n + 1;
                order[n] = make_tuple(x+dx, y+dy, 0, sortMoves(x+dx, y+dy));
                ok = true;
                break;
            }

            if(!ok) 
            {
                data[y][x] = 0;
                --n;
            }
        }
    }

    template<int N>
    friend ostream& operator<<(ostream &out, const Board<N> &b);
};

template<int N>
ostream& operator<<(ostream &out, const Board<N> &b) 
{
    for (int v = 0; v < N; ++v) 
    {
        for (int u = 0; u < N; ++u) 
        {
            if (u != 0) out << ",";
            out << setw(3) << b.data[v][u];
        }
        out << endl;
    }
    return out;
}

int main() 
{
    Board<5> b1;
    b1.solve("c3");
    cout << b1 << endl;

    Board<8> b2;
    b2.solve("b5");
    cout << b2 << endl;

    Board<31> b3; 
    b3.solve("a1");
    cout << b3 << endl;
    return 0;
}



Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)


const startRow = 0
const startCol = 0

func main() {
    rand.Seed(time.Now().Unix())
    for !knightTour() {
    }
}

var moves = []struct{ dr, dc int }{
    {2, 1},
    {2, -1},
    {1, 2},
    {1, -2},
    {-1, 2},
    {-1, -2},
    {-2, 1},
    {-2, -1},
}




func knightTour() bool {
    
    board := make([][]int, 8)
    for i := range board {
        board[i] = make([]int, 8)
    }
    r := startRow
    c := startCol
    board[r][c] = 1 
    for move := 2; move <= 64; move++ {
        minNext := 8
        var mr, mc, nm int
    candidateMoves:
        for _, cm := range moves {
            cr := r + cm.dr
            if cr < 0 || cr >= 8 { 
                continue
            }
            cc := c + cm.dc
            if cc < 0 || cc >= 8 { 
                continue
            }
            if board[cr][cc] > 0 { 
                continue
            }
            
            p := 0 
            for _, m2 := range moves {
                r2 := cr + m2.dr
                if r2 < 0 || r2 >= 8 {
                    continue
                }
                c2 := cc + m2.dc
                if c2 < 0 || c2 >= 8 {
                    continue
                }
                if board[r2][c2] > 0 {
                    continue
                }
                p++
                if p > minNext { 
                    continue candidateMoves
                }
            }
            if p < minNext { 
                minNext = p 
                nm = 1      
                mr = cr     
                mc = cc
                continue
            }
            
            
            nm++                    
            if rand.Intn(nm) == 0 { 
                mr = cr
                mc = cc
            }
        }
        if nm == 0 { 
            return false
        }
        
        r = mr
        c = mc
        board[r][c] = move
    }
    
    for _, r := range board {
        for _, m := range r {
            fmt.Printf("%3d", m)
        }
        fmt.Println()
    }
    return true
}