Project Euler Problem 209

A k-input binary truth table is a map from k input bits (binary digits, 0 [false] or 1 [true]) to 1 output bit.

Project Euler Problem 209

Solution

Answer: 15964587728784

Let

$$T(a,b,c,d,e,f)=(b,c,d,e,f,a\oplus (b\land c)).$$

The condition in the problem is

$$\tau(x)\land \tau(T(x))=0$$

for every $6$-bit state $x$.

We must count all Boolean functions

$$\tau:{0,1}^6\to{0,1}$$

such that no state and its image under $T$ are both assigned $1$.

The key is to understand the structure of the permutation $T$ on the $64$ states.


Step 1 — Interpret the condition graph-theoretically

Define a directed graph on the 64 states by

$$x\to T(x).$$

Since $T$ is invertible (it is a linear-feedback shift-register type transformation), every node has indegree $1$ and outdegree $1$. Therefore the graph decomposes into disjoint directed cycles.

For each edge $x\to T(x)$, the condition says:

$$(\tau(x),\tau(T(x)))\neq (1,1).$$

So on every cycle, we must assign $0/1$ labels such that no adjacent vertices are both $1$.

Thus:

  • each cycle contributes independently,
  • and for a cycle of length $n$, the number of valid assignments is the number of binary circular strings of length $n$ with no adjacent $1$'s.

That quantity is well known:

$$N(n)=F_{n-1}+F_{n+1},$$

where $F_n$ are Fibonacci numbers.

(Equivalently, this is the Lucas number $L_n$.)

So the problem reduces to:

  1. Find the cycle decomposition of $T$,
  2. Multiply the corresponding Lucas numbers.

Step 2 — Analyze the transformation

The map is

$$(a,b,c,d,e,f)\mapsto (b,c,d,e,f,a\oplus (b\land c)).$$

We now determine the cycle structure on the 64 states.

A direct computation (shown below in code) gives:

  • one cycle of length $1$,
  • one cycle of length $2$,
  • one cycle of length $3$,
  • two cycles of length $6$,
  • one cycle of length $46$.

Check:

$$1+2+3+6+6+46=64.$$

Therefore the total number of valid truth tables is

$$L_1L_2L_3L_6^2L_{46}.$$

Using Lucas numbers:

$$L_1=1,\quad L_2=3,\quad L_3=4,\quad L_6=18.$$

Also,

$$L_{46}=4106118243.$$

Hence

$$1\cdot 3\cdot 4\cdot 18^2\cdot 4106118243.$$

Compute:

$$3\cdot 4=12,$$

$$18^2=324,$$

$$12\cdot 324=3888,$$

$$3888\cdot 4106118243=15964587728784.$$


Step 3 — Why the cycle count formula is correct

For a cycle of length $n$, let the binary labels be

$$x_1,x_2,\dots,x_n,$$

with indices cyclic modulo $n$.

The constraint is

$$x_i x_{i+1}=0.$$

The number of binary cyclic strings avoiding consecutive $1$'s equals

$$F_{n-1}+F_{n+1}.$$

A quick derivation:

  • linear strings of length $m$ with no adjacent $1$'s are counted by $F_{m+2}$,

  • for cyclic strings:

  • either first bit is $0$: $F_{n+1}$,

  • or first bit is $1$: neighbors forced $0$, leaving $F_{n-1}$,

  • giving

$$F_{n+1}+F_{n-1}.$$


Step 4 — Python implementation

from collections import defaultdict

# ---------------------------------------------------------
# Transformation T on 6-bit states
# ---------------------------------------------------------

def T(x):
    """
    x is an integer from 0..63 representing bits abcdef.
    Returns T(x).
    """

    # Extract bits
    a = (x >> 5) & 1
    b = (x >> 4) & 1
    c = (x >> 3) & 1
    d = (x >> 2) & 1
    e = (x >> 1) & 1
    f = x & 1

    # New last bit
    g = a ^ (b & c)

    # Shift left
    y = (b << 5) | (c << 4) | (d << 3) | (e << 2) | (f << 1) | g

    return y

# ---------------------------------------------------------
# Find cycle decomposition
# ---------------------------------------------------------

visited = [False] * 64
cycle_lengths = []

for start in range(64):

    if visited[start]:
        continue

    cur = start
    cycle = []

    while not visited[cur]:
        visited[cur] = True
        cycle.append(cur)
        cur = T(cur)

    cycle_lengths.append(len(cycle))

print(sorted(cycle_lengths))

# ---------------------------------------------------------
# Fibonacci / Lucas
# ---------------------------------------------------------

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

def lucas(n):
    return fibonacci(n - 1) + fibonacci(n + 1)

# ---------------------------------------------------------
# Compute total count
# ---------------------------------------------------------

answer = 1

for n in cycle_lengths:
    answer *= lucas(n)

print(answer)

Step 5 — Code walkthrough

Transformation

def T(x):

Represents the mapping

$$(a,b,c,d,e,f)\mapsto (b,c,d,e,f,a\oplus(b\land c)).$$

The integer $x\in[0,63]$ encodes the six bits.


Cycle decomposition

visited = [False] * 64

Tracks which states have already been assigned to cycles.

For every unvisited state, we repeatedly apply $T$ until returning to the start.

The program prints:

[1, 2, 3, 6, 6, 46]

confirming the cycle structure.


Lucas numbers

For a cycle of length $n$, the number of valid assignments is:

lucas(n)

which equals

$$F_{n-1}+F_{n+1}.$$


Final multiplication

The total number of truth tables is the product over all cycles.

The program outputs:

15964587728784

Step 6 — Final verification

We have:

  • total state space size $64$,
  • cycle lengths sum correctly,
  • each cycle contributes independently,
  • Lucas numbers are the standard count for circular binary strings with no adjacent $1$'s.

Magnitude also makes sense:

  • unrestricted truth tables: $2^{64}\approx 1.84\times 10^{19}$,
  • our constraint substantially reduces the count,
  • result $1.596\times 10^{13}$ is plausible.

Therefore the computation is consistent.

Answer: 15964587728784