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 <bits/stdc++.h>

int n, ntop[9]{}, move[9][9]{};
// 距離abs(a-b)/3+abs(a-b)%3

bool jisho(int[9], int[9]);

int main()
{
	scanf("%d", &n);
	char pre{};
	scanf(" %c", &pre);
	for (int i{1}; i < n; i++)
	{
		char s;
		scanf(" %c", &s);
		move[pre - '1'][s - '1']++;
		pre = s;
	}
	// for (int i{}; i < 9; i++)
	// {
	// 	for (int j{}; j < 9; j++)
	// 		printf("%d ", move[i][j]);
	// 	putchar('\n');
	// }
	for (int i{}; i < 9; i++) ntop[i] = i;
	long long min{1LL << 60};
	int ans[9]{};
	for (int i{}; i < 9; i++) ans[i] = 9;
	do
	{
		long long cost{};
		for (int i{}; i < 9; i++)
			for (int j{}; j < 9; j++)
				cost += move[i][j] * (std::abs(ntop[i] / 3 - ntop[j] / 3) + std::abs(ntop[i] % 3 - ntop[j] % 3));
		if (cost > min) continue;
		int tmp_ans[9]{};
		for (int i{}; i < 9; i++) tmp_ans[ntop[i]] = i;
		if (cost == min && !jisho(tmp_ans, ans)) continue;
		min = cost;
		for (int i{}; i < 9; i++) ans[i] = tmp_ans[i];
	} while (std::next_permutation(ntop, ntop + 9));
	for (int i{}; i < 3; i++)
	{
		for (int j{}; j < 3; j++)
		{
			putchar('1' + ans[3 * i + j]);
		}
		putchar('\n');
	}
	
	return 0;
}

bool jisho(int ntop[9], int min_arr[9])
{
	for (int i{}; i < 9; i++)
		if (ntop[i] > min_arr[i])
			return false;
		else if (ntop[i] < min_arr[i])
			return true;
	assert(true);
	return false;
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007 
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

int ans;
int x[9];
int n;
string s;
int mv[10][10];
P pos[10];

int main(){
	cin>>n>>s;
	for(int i=1;i<n;i++){
		mv[s[i-1]-'0'][s[i]-'0']++;
	}
	ans = INF;
	int p[9];
	rep(i,9) p[i] = i+1;
	do{
		rep(i,9){
			pos[p[i]] = mp(i/3,i%3);
		}
		int sum = 0;
		repn(i,9)repn(j,9){
			sum += mv[i][j] * (abs(pos[i].fi-pos[j].fi)+abs(pos[i].sc-pos[j].sc));
		}
		if(ans > sum){
			ans = sum;
			rep(i,9) x[i] = p[i];
		}
	}while(next_permutation(p,p+9));
	int C = 0;
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++){
			cout<<x[C++];
		}
		cout<<endl;
	}
}

C++: #define _CRT_SECURE_NO_WARNINGS
#define _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <math.h>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <math.h>
#include <iostream>
#include <random>
#include <map>
#include <fstream>
#include <iomanip>
#include <time.h>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <assert.h>
#include <complex>
using namespace std;
#define LONG_INF 10000000000000
#define GOLD 1.61803398874989484820458
#define MAX_MOD 1000000007
#define MOD 998244353LL
#define seg_size 65536*4
#define REP(i,n) for(long long i = 0;i < n;++i)
int main() {
	int n;
	cin >> n;
	string s;
	cin >> s;
	int cnt[10][10] = {};
	for (int i = 1; i < s.length(); ++i) {
		cnt[s[i - 1] - '0'][s[i] - '0']++;
	}
	vector<int> input;
	REP(i, 9) {
		input.push_back(i + 1);
	}
	long long ans = 10000000;
	vector<int> gogo;
	do {
		long long now = 0;
		for (int q = 0; q < input.size(); ++q) {
			int visited[10] = {};
			visited[q] = 1;
			queue<pair<int,int>> next;
			next.push(make_pair(q, 1));
			while (next.empty() == false) {
				pair<int, int> go = next.front();
				next.pop();
				now += go.second * cnt[input[q]][input[go.first]];
				go.second++;
				if (go.first - 3 >= 0 && visited[go.first - 3] == 0) {
					visited[go.first - 3] = 1;
					next.push(make_pair(go.first - 3, go.second));
				}
				if (go.first % 3 != 0&&visited[go.first - 1] == 0) {
					visited[go.first - 1] = 1;
					next.push(make_pair(go.first - 1, go.second));
				}
				if (go.first + 3 < 9 && visited[go.first + 3] == 0) {
					visited[go.first + 3] = 1;
					next.push(make_pair(go.first + 3, go.second));
				}
				if (go.first % 3 != 2 && visited[go.first + 1] == 0) {
					visited[go.first + 1] = 1;
					next.push(make_pair(go.first + 1, go.second));
				}
			}
		}
		if (ans > now) {
			ans = now;
			gogo = input;
		}
	} while (next_permutation(input.begin(), input.end()));
	REP(i, 3) {
		REP(q, 3) {
			cout << gogo[i * 3 + q];
		}
		cout << endl;
	}
	return 0;
}