Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	n := getNextInt(scanner)
	s := getNextString(scanner)
	cc := makeGrid(9, 9)
	for i := 0; i < n-1; i++ {
		cc[s[i]-'0'-1][s[i+1]-'0'-1]++
	}
	p := make(permutation, 9)
	ans := make([]int, 9)
	p.dfs(0, 9, 0, ans, cc)
	for i := 0; i < 9; i++ {
		fmt.Fprint(writer, ans[i]+1)
		if i%3 == 2 {
			fmt.Fprintln(writer, "")
		}
	}
}
func makeGrid(h, w int) [][]int {
	index := make([][]int, h, h)
	data := make([]int, h*w, h*w)
	for i := 0; i < h; i++ {
		index[i] = data[i*w : (i+1)*w]
	}
	return index
}

var min int = math.MaxInt32

type permutation []int

func (p permutation) dfs(i, n int, used uint32, ans []int, cc [][]int) {
	if i == n {
		sum := getsum(p, cc)
		if min > sum {
			for i := 0; i < 9; i++ {
				ans[i] = p[i]
			}
			min = sum
		}
		return
	}
	for b := 0; b < 9; b++ {
		if used&(1<<uint(b)) != 0 {
			continue
		}
		p[i] = b
		p.dfs(i+1, n, used|(1<<uint(b)), ans, cc)
	}
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}
func getsum(p permutation, cc [][]int) int {
	sum := 0
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			if i == j {
				continue
			}
			sum += (abs(i/3-j/3) + abs(i%3-j%3)) * cc[p[i]][p[j]]
		}
	}
	return sum
}

C++: #include <iostream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <map>
#include <utility>
#include <list>
#include <climits>
#include <bitset>
#include <numeric>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)
#define repi(i, n) for(auto i = (n).begin(); i != (n).end(); i++)
#define in_arr(type, a, n) copy_n(istream_iterator<type>(cin), n, (a).begin());
#define ll long long int

int main(){
    vector< vector<int> > f(9);
    repi(i, f){
        *i = vector<int>(9, 0);
    }
    int n;
    string s;
    cin >> n >> s;
    rep(i, n - 1){
        ++f[s[i] - '0' - 1][s[i + 1] - '0' - 1];
    }
    vector<int> res(9);
    vector<int> vi = {0, 1, 2, 3, 4, 5, 6, 7, 8};
    int ret = INT_MAX;
    do{
        int exp_res = 0;
        rep(i, 9){
            rep(j, 9){
                int xi = i % 3;
                int yi = i / 3;
                int xj = j % 3;
                int yj = j / 3;
                int dist = abs(xi - xj) + abs(yi - yj);
                exp_res += dist * f[vi[i]][vi[j]];
            }
        }
        if(exp_res < ret){
            ret = exp_res;
            rep(i, 9){
                res[i] = vi[i];
            }
        }
    }while(next_permutation(vi.begin(), vi.end()));
    rep(i, 3){
        rep(j, 3){
            cout << res[i * 3 + j] + 1;
            if(j == 2){
                cout << endl;
            }
        }
    }
    return 0;
}

C++: #include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

int cnt[9][9];
int dist[9][9];

int dx[] = {0, -1, 0, 1};
int dy[] = {-1, 0, 1, 0};

int main(){
    rep(i, 9) rep(j, 9) dist[i][j] = INF;
    rep(i, 9) dist[i][i] = 0;
    rep(y, 3) rep(x, 3) {
        int cur = y * 3 + x;
        rep(i, 4) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx < 0 || nx >= 3 || ny < 0 || ny >= 3) continue;
            int nxt = ny * 3 + nx;
            dist[cur][nxt] = 1;
        }
    }
    rep(k, 9) rep(i, 9) rep(j, 9) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    // rep(i, 9) {
    //     rep(j, 9) cout << dist[i][j] << " ";
    //     cout << endl;
    // }

    // cout << endl;
    // rep(i, 9) {
    //     rep(j, 9) cout << cnt[i][j] << " ";
    //     cout << endl;
    // }

    int n;
    string s;
    cin >> n >> s;
    rep(i, n-1) {
        cnt[s[i]-'1'][s[i+1]-'1']++;
    }
    // cout << n << endl << s << endl;


    // cout << endl;
    // rep(i, 9) {
    //     rep(j, 9) cout << cnt[i][j] << " ";
    //     cout << endl;
    // }

    auto calc = [&](const vector<int>& a) {
        int ret = 0;
        rep(i, 9) rep(j, 9) ret += cnt[a[i]][a[j]] * dist[i][j];
        return ret;
    };

    vi a(9);
    rep(i, 9) a[i] = i;

    vi ans;
    int ans_cnt = INF;
    do {
        int tmp = calc(a);
        if(tmp < ans_cnt) {
            ans_cnt = tmp;
            ans = a;
        }
        // for(auto&& x : a) cout << " " << x;
        //     cout << " -> " << tmp << endl;
    }while(next_permutation(all(a)));
    rep(i, 3) {
        rep(j, 3) {
            cout << ans[i*3+j]+1;
        }
        cout << endl;
    }
    return 0;
}