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"
#define YES "YES"
#define NO "NO"
#define YESNO OUT(three(solve(),YES,NO))
#define ECHO OUT(solve())
#define three(A,B,C) ((A)?(B):(C))
#define FOR(i,a,b)  for(LL i=(a);i< (LL)(b);i++)
#define EFOR(i,a,b) for(LL i=(a);i<=(LL)(b);i++)
#define RFOR(i,a,b) for(LL i=(a);i>=(LL)(b);i--)
#define REP(i,b) FOR(i,zero,b)
#define EREP(i,b) EFOR(i,zero,b)
#define RREP(i,b) RFOR(i,b-1,zero)
#define ALL(c) c.begin(),c.end()
#define UNIQUE(c) sort(ALL(c));c.erase(unique(ALL(c)),c.end())
#define MAX(c) (*max_element(ALL(c)))
#define MIN(c) (*min_element(ALL(c)))
#define MP make_pair
#define FI first
#define SE second
#define SI(x) (LL(x.size()))
#define PB emplace_back
#define DEBUG(a) OUT(a)
#define DEBUG2(a,b) OUT2(a,b)
#define cat cout << __LINE__ << endl
#define OUT(a) cout << (a) << endl
#define OUT2(a,b) cout << (a) <<" "<<(b) << endl
#define int long long
#define zero 0LL
#define pb PB
using namespace std;
template<typename T> inline bool middle(T a, T b, T c) { return b <= a && a <= c; }
template<class T> inline bool MX(T &l, const T &r) { return l < r ? l = r, 1 : 0; }
template<class T> inline bool MN(T &l, const T &r) { return l > r ? l = r, 1 : 0; }
typedef long long LL;
typedef double ld;
typedef LL ut;
typedef vector<ut> VI;
typedef vector<VI> VII;
typedef pair<ut, ut> pr;
typedef pair<ut, pr> ppr;
typedef vector<pr> Vpr;
typedef vector<ppr> Vppr;
typedef priority_queue<pr, Vpr ,greater<pr> > PQ;
inline void outputVI(VI x) { REP(i, SI(x)) { cout << three(i, " ", "") << x[i]; }OUT(""); }
int dx[] = { 0,1,0,-1,0 }, dy[] = { 1,0,-1,0,0 };
const int SIZE1 =3e5 + 1000;
const int SIZE2 = 5010;
const int SIZE3 = 22;
const int SIZE = SIZE1;
const LL p = 7 + 1e9;
const LL INF = 1LL << 60;
const long double EPS = 1e-7;
ut N, M, K, X, L, Y,H,W,Q;
// ut A,B,C,D,E,F,G,H,I,J,O,P,Q,R,T,U;
VI edges[SIZE];
LL vals[SIZE], nums[SIZE], maps[SIZE3][SIZE3], answer = zero;
LL A[SIZE], B[SIZE];
bool used[11];
inline LL dist(LL a,LL b) {
	return abs(a / 3 - b / 3) + abs(a % 3 - b % 3);
}
LL solve() {
	cin >> N;
	string s;
	cin >> s;
	REP(i, N) {
		A[i] = s[i] - '0';
		if (i)
			maps[A[i]][A[i - 1]]++;
	}
	VI v(9);
	EFOR(i, 0 ,8) v[i] = i+1;
	LL minium = INF;
	VI ansv(9);
	do {
		LL ans = 0;
		REP(i,9) REP(j,9) {
			ans += maps[v[i]][v[j]] * dist(i, j);
		}
		if (MN(minium,ans )) {
			REP(i, 9) ansv[i] =v[i] ;
		}
	} while (next_permutation(ALL(v)));
	REP(i, 9) {
		cout << ansv[i];
		if (i % 3 == 2) cout << endl;
	}
	return 0;
}
signed main() {
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(10);

	solve();
//	cin >> N;
	return 0;
}

C++: #include<bits/stdc++.h>
#define INF 1e9
#define llINF 1e18
#define MOD 1000000007
#define pb push_back
#define mp make_pair 
#define F first
#define S second
#define ll long long
#define ull unsigned long long
#define vi vector<ll>
#define vvi vector<vi>
#define BITLE(n) (1LL<<(n))
#define BITCNT(n) (__builtin_popcountll(n))
#define SUBS(s,f,t) ((s).substr((f)-1,(t)-(f)+1))
#define ALL(a) (a).begin(),(a).end()
using namespace std;
struct Grid{ll x,y,t;};
struct Edge{ll to,cost;};
struct Graph{vector<vector<Edge>>E;int V;
  const ll Inf = llINF;const int MAX_V=201010;vector<ll>d;
  Graph(int n):E(n){d.resize(MAX_V);E.resize(n);V=n;}
  void init(){for(int i=0;i<MAX_V;i++)d[i]=Inf;}
  void add_edge(ll from,ll to,ll cost){E[from].pb({to,cost});}
};
ll cnt[100][100];
ll dist[10][10]={
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,1,2,1,2,3,2,3,4},
  {0,1,0,1,2,1,2,3,2,3},
  {0,2,1,0,3,2,1,4,3,2},
  {0,1,2,3,0,1,2,1,2,3},
  {0,2,1,2,1,0,1,2,1,2},
  {0,3,2,1,2,1,0,3,2,1},
  {0,2,3,4,1,2,3,0,1,2},
  {0,3,2,3,2,1,2,1,0,1},
  {0,4,3,2,3,2,1,2,1,0}
};
int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n;cin>>n;
  string s;cin>>s;
  for(int i=0;i<n-1;i++)
    cnt[s[i]-'0'][s[i+1]-'0']++;
  vi v={1,2,3,4,5,6,7,8,9};
  ll ans=llINF;
  ll pat;
  do{
    ll cn=0;
    for(int i=1;i<=9;i++)
      for(int j=1;j<=9;j++){
	cn+=dist[i][j]*(cnt[v[i-1]][v[j-1]]);
      }
    if(ans>cn){
      ans=cn;
      ll sum=0;
      ll kake=1;
      for(int i=8;i>=0;i--){
	sum+=v[i]*kake;kake*=10;
      }
      pat=sum;
    }else if(ans==cn){
      ll sum=0;
      ll kake=1;
      for(int i=8;i>=0;i--){
	sum+=v[i]*kake;kake*=10;
      }
      if(pat>sum)
	pat=sum;
    }
  }while(next_permutation(ALL(v)));
  ll an[10][10];
  an[2][2]=pat%10;
  pat/=10;
  an[2][1]=pat%10;
  pat/=10;
  an[2][0]=pat%10;
  pat/=10;
  an[1][2]=pat%10;
  pat/=10;
  an[1][1]=pat%10;
  pat/=10;
  an[1][0]=pat%10;
  pat/=10;
  an[0][2]=pat%10;
  pat/=10;
  an[0][1]=pat%10;
  pat/=10;
  an[0][0]=pat%10;
  pat/=10;

  for(int i=0;i<3;i++){
    for(int j=0;j<3;j++){
      cout<<an[i][j];
    }
    cout<<endl;
  }
  return 0;
}