Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	out := make([][]string, 100)
	for i := range out {
		out[i] = make([]string, 101)
	}
	dx := []int{0, 1, 0, -1}
	dy := []int{-1, 0, 1, 0}
	scanner.Scan()
	a, _ := strconv.Atoi(scanner.Text())
	for a > 0 {
		a--
		scanner.Scan()
		b, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < b; i++ {
			for j := 0; j < b; j++ {
				out[i][j] = " "
			}
			out[i][b] = "0"
		}
		if b == 1 {
			fmt.Println("#")
			if a != 0 {
				fmt.Println()
			}
			continue
		}
		if b == 2 {
			fmt.Printf("##\n# \n")
			if a != 0 {
				fmt.Println()
				continue
			}
		}
		row := b -1
		col := 0
		dir := 0
		l := 0
		out[row][col] = "#"
		for {
			nrow := row+dy[dir%4]
			ncol := col+dx[dir%4]
			if dir%4 == 0 && nrow == 0 || dir%4==3&&ncol==0 || dir%4==2&&nrow==b-1 || dir%4==1&&ncol==b-1 {
				row=nrow
				col=ncol
				out[row][col]="#"
				dir++
				l = 1
			} else if out[nrow+dy[dir%4]][ncol+dx[dir%4]]=="#" {
				if l < 3 {
					break
				}
				dir++
				l = 1
			} else {
				row=nrow
				col=ncol
				out[row][col]="#"
				l++
			}
		}
		for i := 0; i < b; i++ {
			for j := 0; j < b; j++ {
				fmt.Printf("%s", out[i][j])
			}
			fmt.Println()
		}
		if a != 0 {
			fmt.Println()
		}
	}
}

C++: #include<iostream>
#include<cassert>
#include<ctime>
#include<climits>
#include<queue>
#include<fstream>
#include<deque>
#include<iomanip>
#include<list>
#include<stack>
#include<sstream>
#include<string>
#include<cctype>
#include<cstdio>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<map>
#include<set>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS 1e-10
#define F first
#define S second
#define all(n) n.begin(),n.end()
#define pb push_back
#define insert(a,b,c,d) PP(P(a,b),P(c,d))
#define INF (1<<27)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef pair<P,P> PP;
const int dx[4] = {-1,0,+1,0};
const int dy[4] = {0,-1,0,+1};

class Solve{
private:
  int d;
  int imap[110][110];
public:

  Solve(int n):d(n){}
  ~Solve(){}

  int Connect(P p){
    int cnt = 0;
    rep(i,4){
      int nx = p.F+dx[i],ny = p.S+dy[i];
      if(!(0<=nx && nx <d && 0<= ny && ny < d))continue;
      if(imap[ny][nx] == 1)cnt++;
    }
    return cnt;
  }


  void display(){
      cout << "--- in display ---" << endl;
      rep(i,d){
	rep(j,d){
	  if(imap[i][j] == 1)cout << '#';
	  else cout << ' ';
	}
	cout << endl;
      }
      cout << endl;
    }


  void run(){
    rep(i,d+1)rep(j,d+1)imap[i][j] = 0;

    rep(i,d){
      imap[0][i] = 1;
      imap[i][0] = 1;
      imap[i][d-1] = 1;
    }

  


    P pos = P(d-1,d-1);
    int dir = 0;
    int cnt = 0;
    bool fin = false;
    while(true){

      int nx,ny;
      nx  = pos.F,ny = pos.S;
      while(true){
	//cout << "nx = " << nx << ",ny = "<< ny << ",dir = " << dir << endl;
	//display();


	if(!(Connect(P(nx,ny)) == 2 || Connect(P(nx,ny)) == 1)){
	  imap[ny-dy[dir]][nx-dx[dir]] = 0;
	  //cout << "Lase nx = " << nx << ",ny = "<< ny << endl;
	  //cout << "FIN! connnect = " << Connect(P(nx,ny)) << endl;
	  fin = true;
	  break;
	}

	if(imap[ny+dy[dir]][nx+dx[dir]] == 1){
	  //cout << "IN nx = " << nx+dx[dir] << ",ny = " << ny+dy[dir] << endl;
	  imap[ny][nx] = 0;
	  cnt--;
	  break;
	}
	imap[ny][nx] = 1;
	cnt++;	


	nx += dx[dir],ny += dy[dir];
      }
      //cout << "------ cnt = " << cnt << endl;
      if(fin){
	//cout << "dir = " << dir << endl;
	break;
      }
      if(cnt == 0)break;
      cnt =0;

      pos.F = nx-dx[dir],pos.S = ny-dy[dir];
      dir++;
      dir = dir%4;
    }

    rep(i,d){
      rep(j,d){
	if(imap[i][j] == 1)cout << '#';
	else cout << ' ';
      }
      cout << endl;
    }
    

  }


};


int main(){
  int T;
  cin >> T;
  while(T-- > 0){
    int _n;
    cin >> _n;
    Solve ans = Solve(_n);
    ans.run();
    if(T != 0)cout << endl;
  }
return 0;
}

C++: //Name: Spiral Pattern
//Level: 2
//Category: シミュレーション
//Note: 

/**
 * n×nの領域を用意して、左下隅から渦巻きをたどるようにして埋めていく。
 * 現在の進行方向について、壁にぶつかるときか、もう1歩進むと他の線に干渉するというときには右に曲がる。
 */
#include <iostream>
#include <vector>
#include <string>

using namespace std;

// ostream support for vector.
template<typename T>
ostream& operator <<(ostream &os, const vector<T> &v) {
    for(const T &t : v) {
        os << t << endl;
    }
    return os;
}

template<typename T>
struct Pair {
    T a, b;

    Pair() : a(T()), b(T()) {}
    Pair(const T &a, const T &b) : a(a), b(b) {}

    Pair& operator += (const Pair &p) {
        a += p.a;
        b += p.b;
        return *this;
    }

    friend Pair operator +(Pair p1, const Pair &p2) {
        p1 += p2;
        return p1;
    }

    friend ostream& operator <<(ostream &os, const Pair &p) {
        return os << "(" << p.a << ", " << p.b << ")";
    }

    /* vector accessor mixin {{{*/
    template<typename U>
    auto of(U &u) const -> decltype(u[a][b]) {
        return u[a][b];
    }

    template<typename U>
    bool valid_in(const U &u) const {
        return a < u.size() && b < u[0].size();
    }
    /*}}}*/
};

static const Pair<int> DELTA[4] = {
    Pair<int>(-1, 0), Pair<int>(0, -1), Pair<int>(1, 0), Pair<int>(0, 1)
};

bool solve(bool first) {
    if(!first) cout << endl;
    int N;
    cin >> N;

    vector<string> f(N, string(N, ' '));
    Pair<int> pos(N-1, 0);
    int dir = 1;
    bool stucked = false;
    while(true) {
        pos.of(f) = '#';
        auto next = pos + DELTA[dir];
        auto nn = next + DELTA[dir];
        auto nl = next + DELTA[(dir+3)%4];
        if(nl.valid_in(f) && nl.of(f) == '#') {
            break;
        }
        if(!next.valid_in(f) || (nn.valid_in(f) && nn.of(f) == '#')) {
            if(stucked) break;
            dir = (dir + 3) % 4;
            stucked = true;
        } else {
            stucked = false;
            pos = next;
        }
    }
    cout << f << endl;
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout.setf(ios::fixed);
    cout.precision(2);

    bool first = true;
    int N;
    cin >> N;
    while(N-- && solve(first)) {
        first = false;
    }
    return 0;
}

C++: #include <algorithm>
#include <bitset>
#include <cstdio>
#include <cassert>
#include <cmath>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <utility>
#include <vector>
using namespace std;

typedef long long LL;
typedef pair<int, int> P;
typedef pair<LL, LL> PLL;

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

constexpr char SHARP = '#';
constexpr char SPACE = ' ';

void draw(int width, int x, int y, vector<string>& a) {
    if (width == 1) {
        a[x][y] = SHARP;
    } else if (width == 2) {
        a[x][y] = a[x+1][y] = a[x][y+1] = SHARP;
    } else if (width == 3) {
        a[x][y] = a[x][y+1] = a[x][y+2] = SHARP;
        a[x+1][y] = a[x+1][y+2] = SHARP;
        a[x+2][y] = a[x+2][y+2] = SHARP;
    } else if (width == 4) {
        a[x][y] = a[x][y+1] = a[x][y+2] = a[x][y+3] = SHARP;
        a[x+1][y] = a[x+1][y+3] = SHARP;
        a[x+2][y] = a[x+2][y+3] = SHARP;
        a[x+3][y] = a[x+3][y+2] = a[x+3][y+3] = SHARP;
    } else {
        for (int j = 0; j < width; ++j) {
            a[x][y+j] = SHARP;
        }
        for (int j = 1; j < width; ++j) {
            a[x+j][y] = SHARP;
            a[x+j][y+width-1] = SHARP;
        }
        for (int j = 2; j < width; ++j) {
            a[x+width-1][y+j] = SHARP;
        }
        a[x+width-2][y+2] = SHARP;
        draw(width-4, x+2, y+2, a);
    }
}

int main() {
    int N;
    cin >> N;
    for (;N--;) {
        int W;
        cin >> W;
        vector<string> a(W, string(W, ' '));

        draw(W, 0, 0, a);
        for (int j = 0; j < W; ++j) {
            cout << a[j] << endl;
        }
        if (N > 0) {
            cout << endl;
        }
    }
    return 0;
}