Repeated letters. There are six positions, with two copies of each of two letters. Counting labeled arrangements and dividing by the permutations of each repeated pair gives
Single-occupancy cells. For indistinguishable particles, specifying which of the distinct cells are occupied completely specifies a configuration. ThusFor distinguishable particles, each chosen occupied set admits assignments of particle labels:Equivalently, successively place labeled particles in available cells. The single-occupancy constraint is essential: this is not unrestricted stars and bars. Both counts give one empty configuration at ; at they give one unlabeled occupation pattern and labeled assignments.
One particle. Use the classical phase-space normalization of one quantum state per volume , with no unspecified internal degeneracy. For and , the canonical partition function factorizes into momentum and position integrals:The Gaussian momentum integral is . In spherical coordinates, put :Therefore the classical ideal gas in a spherical linear trap hasHere is a force, in , so is a length and is dimensionless. A nonconfining would not give this finite spatial integral. As required by the classical phase-space approximation, the temperature must exceed the trap's discrete level scale.
Indistinguishable dilute particles. Independent labeled particles would give . In the classical dilute regime, division by removes the overcounting of permutations of identical particles:This is the Maxwell-Boltzmann limit, not an exact quantum canonical partition function at high occupation. Exchange effects cannot be captured merely by continuing this formula beyond its dilute regime.
Free energy, energy and entropy. The Helmholtz free energy isWith leading Stirling's approximation, , this becomesAt fixed trap strength, . Differentiating gives the requested entropy,The is : the first term comes from indistinguishability through Stirling's formula, and the second from the temperature dependence of . Without the large- approximation, . Independently,The kinetic contribution is and the linear-trap potential contribution is , also obtained from generalized equipartition.
Entropy curves and reversible cooling. For a fixed and a reference pair , the dependence can be written without logarithms of dimensional quantities:At each fixed , the entropy increases logarithmically and is concave downward in ; decreasing shifts the curve upward. Its formal classical divergence as marks failure of classical statistics, not a physical negative-infinite entropy.
Original classical entropy curves for two linear-trap strengths; a horizontal constant-entropy arrow shows cooling on reversible decompression, within the dilute regime
. Details. For a reversible adiabatic change, is constant at fixed , soHence reducing lowers the temperature: this is isentropic decompression of a spherical linear trap. The gas does work on the control that weakens the trap. Equivalently , with ; inserting gives the same relation. Reversibility requires an equilibrium sequence without heat input or entropy production. Because stays constant on this adiabat, also stays constant: this mechanism cools the cloud but does not by itself increase quantum degeneracy.
Chemical potential and quantum threshold. From the extensive free energy,Thus the quantum gas fugacity is . Classical statistics requires ; quantum effects become important as the chemical potential comes within order of the lowest one-particle energy. With the semiclassical zero at the potential minimum, the quantum degeneracy threshold in a spherical linear trap is consequentlyThere are no numerical values of in the paper, so this parameter-dependent estimate is the requested atom number. It also follows from the peak density: , and degeneracy starts when is order one. The criterion is a crossover estimate, not an assertion that the classical formula remains valid at . For spinless bosons the continuum excited-state saturation is more specifically , while for fermions the onset is occupation constrained by exclusion. At temperatures comparable with the quantum trap spacing, the actual ground energy must be included consistently rather than identified exactly with the classical minimum.
Use permutation generation by insertion: recursively arrange the tail, then insert the removed head in every possible position.
inserts x [] = [[x]]
inserts x (y:ys) = (x:y:ys) : map (y:) (inserts x ys)
perms [] = [[]]
perms (x:xs) = concat (map (inserts x) (perms xs))The map function in
inserts prefixes y to each placement after the first position. For a list of length , the number of results obeys and , so mathematical induction gives . Every result still contains the same old elements and the one inserted element.Let be the length of
perms xs for an input of length . There is exactly one permutation of the empty list, namely the empty list itself: hence perms [] is [[]], with length one. For a nonempty input, each recursively obtained permutation has length and gives placements. ThusLength alone would not exclude repeated answers. Since the input elements are distinct, removing the distinguished element from any result uniquely recovers both its placement and the shorter permutation. Hence different construction choices give different outputs, and every desired permutation is obtained by inserting into its restriction to xs. For [a,b,c], this code yields [a,b,c], [b,a,c], [b,c,a], [a,c,b], [c,a,b], [c,b,a], each exactly once.Maintain a processed prefix split into values below the pivot and values at least the pivot. The remaining suffix has not yet been classified. Here The loop invariant isIn addition, the active segment remains a permutation of its original contents, and every entry outside it remains unchanged. If
a and N are the given array and its length.def partition(l: Int, r: Int, p: Int): Int = {
require(0 <= l && l <= r && r <= N)
var k = l
var j = l
while (j < r) {
if (a(j) < p) {
val t = a(k); a(k) = a(j); a(j) = t
k += 1
}
j += 1
}
k
}a(j) < p, swapping it with a(k) extends the first region; the displaced entry, when the two positions differ, already belongs in the second region. Otherwise only the second region grows. The loop variant is . At termination , soThere are exactly iterations, giving time complexity and constant auxiliary space.Use missing-value search by deficient value intervals: halve the candidate value interval, and apply array partitioning only to the array segment whose entries lie in that interval.The loop invariant is , , andMore precisely, the segment contains all occurrences of original values in , and the complete array remains a permutation of its original state. The occurrences statement is essential: absence from the final segment must imply absence from the original array.
def missing(): Int = {
require(N < Int.MaxValue)
var lo = 0; var hi = N + 1
var l = 0; var r = N
while (hi - lo > 1) {
val p = lo + (hi - lo) / 2
val k = partition(l, r, p)
if (k - l < p - lo) {
hi = p; r = k
} else {
lo = p; l = k
}
}
lo
}After array partitioning, let , , , and . If , retain the left side. Otherwise the right side hasoccurrences. Either choice preserves the strict deficiency and the all-occurrences condition. The positive integer width decreases, proving termination. At width one, the active segment has fewer than one entry and is empty. ThereforeFor the time complexity, after splits the width is at most , and the scan length is smaller than that width. Summing over the levels gives a geometric series plus logarithmic overhead, hence overall, conventionally for . This proof bounds the retained occurrence count by the retained value width; it does not assume that each array partitioning splits the number of occurrences in half. The case returns zero immediately.
Use merge sort, stopping before an empty or singleton linked list would be split.By induction on the length, each recursive call returns a sorted permutation of its input. Part (d) makes both child lengths smaller than the parent whenever the parent length exceeds one; part (e) combines the sorted children. No data linked list nodes are newly allocated or lost. Unreachable headers may be reclaimed by garbage collection.
PROCEDURE MergeSort(less: LESS; VAR p: List);
VAR q, r: List;
BEGIN
IF p.count > 1 THEN
Split(p, q, r);
MergeSort(less, q); MergeSort(less, r);
Merge(less, q, r, p)
END
END MergeSort;At each level the total splitting and merge algorithm work is linear; approximately equal halves give logarithmic depth. ConsequentlyThere are header allocations over the whole execution; those allocations should not be confused with the logarithmic call stack bound.
Let be the original sequence and . The loop invariant isHere denotes the multiset of entries. The capacity condition uses the question's assumption of sufficient space. Removing two runs of combined length and appending their merge preserves the length and multiset. It also leaves all live values in one contiguous segment.
For a nonempty live sequence, let be its number of maximal initial runs obtained by repeatedly cutting at strict adjacent descents. The loop variant is . If
x = d, there is one run and the procedure returns a sorted permutation. Otherwise the iteration removes two runs and appends one; it cannot create a new descent inside that appended run. The appended run may join the last old run, further reducing , so decreases by at least one. There are at most merges.For , the loop is skipped and the empty segment is already sorted. No global stability claim is needed: moving a merged run behind other runs can change the order of equal-labelled occurrences.Write the determinant in its Leibniz formula for determinants, where is the set of permutations of :The permutation sign is justified by the given row-interchange property: a permutation matrix is obtained from the identity matrix by row interchanges, and every interchange changes its determinant by a factor . Reversing a sequence of interchanges constructs the inverse permutation with the same number of interchanges. Consequently . The Leibniz formula for determinants can itself be obtained by expanding the rows multilinearly in the standard basis: repeated selected coordinate rows contribute zero, and the remaining terms are precisely these signed permutation matrices.
Since , the same formula givesReindex the product with and reindex the sum with . Both reindexings are bijections, soThus for every real square matrix, including singular matrices. This proof does not assume the analogous column-operation rules in order to establish the transpose identity.
Use the convention , as required by the paper's rotation example. Follow each permutation cycle once. Temporarily encode a visited value as , and restore the whole permutation before returning:Require
PROCEDURE Permute(VAR p: ARRAY OF INTEGER);
VAR s, j, next: INTEGER; saved: T;
BEGIN
s := 0;
WHILE s < N DO
IF p[s] >= 0 THEN
IF p[s] = s THEN
p[s] := -p[s]-1
ELSE
saved := a[s]; j := s;
next := p[j]; p[j] := -next-1;
WHILE next # s DO
a[j] := a[next]; j := next;
next := p[j]; p[j] := -next-1
END;
a[j] := saved
END
END;
s := s+1
END;
s := 0;
WHILE s < N DO p[s] := -p[s]-1; s := s+1 END
END Permute;LEN(p) >= N and that p[0..N) is the stipulated permutation. Its cells must be writable and distinct from the data array. The marking map is reversible and fits whenever the original valid indices and fit in the signed integer type.At each outer test, all marked indices belong to fully completed cycles; all unmarked cycles still contain their original data and permutation entries. Within a cycle the same shifting loop invariant as part (d) applies, with successor given by the original
p: all previously filled positions have their final values, and saved preserves the overwritten first source. A permutation has no path into a different cycle, so every new successor is unmarked until it returns to s; no encoded negative value is used as a source index. At outer-loop exit every index is marked and correct. The restoration loop has decoded precisely the indices below s.The procedure uses one extra value of type
T, time, and at most data reads plus data writes, with no data access for fixed points. It returns p unchanged, though it marks it temporarily. If p must remain read-only even during execution, test whether each index is its cycle's smallest member by traversing p before moving that cycle. That preserves constant space and the same optimal data accesses, but can require index-array accesses.One example is the identity function, . A second is the permutationBoth are bijections of , whichever convention includes or excludes zero. For the second, applying three times returns every input to itself. Thus , and composing with the inverse function gives . This permutation cube identity criterion also shows why three-cycles work whereas a nontrivial two-cycle would not.
A derangement of a finite set is a permutation with no fixed point: for every . Thus every element is moved, although the permutation remains a bijection.
There are choices for the first position, then choices for the second, and so on down to one choice. The multiplication principle therefore gives permutations. This also agrees with the empty permutation convention .
Let be the set of permutations fixing object . If a specified collection of objects is fixed, the remaining objects can be arranged in ways. There are such collections. Applying the inclusion-exclusion principle to exclude all fixed objects givesFor , the terms and cancel. Thus the number of derangements is , interpreting the remaining sum as empty when . The full inclusion-exclusion formula also gives .
Check entries against their own indices, stopping on the first mismatch:The loop invariant is and for every . The loop variant is . A false guard means either every position has passed or the next position is wrong, so the returned Boolean is true exactly for the identity permutation. Neither the game nor its history is changed. Short-circuit evaluation protects the final indexed comparison.
def isIdentity: Boolean = {
var i = 0
while (i < game.length && game(i) == i) {
i += 1
}
i == game.length
}Allocate a distinct game and copy every destination entry from the corresponding source position:The loop invariant says that the receiver is unchanged and destination positions before
def flip(k: Int): Flip = {
require(1 < k && k <= game.length)
val result = new Flip(game.length)
var i = 0
while (i < game.length) {
val source = if (i < k) k - 1 - i else i
result.game(i) = game(source)
i += 1
}
result.flips = k :: flips
result
}i equal the reversal of the first source entries followed by the untouched suffix. The loop variant is . At exit the copying is complete. Reversal is a bijection on positions, so the destination remains a permutation. The returned object's array is independent of the receiver's array, while the immutable tail of its history list can safely be shared. The source's only supplied constructor randomizes the new array before the copy; that work is redundant but does not affect correctness. An additional private constructor could avoid it without changing the required result.Use breadth-first search with the supplied FIFO queue, taking one edge to mean one permitted prefix reversal:The FIFO queue holds pending paths in nondecreasing history length. Initially it holds only the zero-move path. Removing a path at depth and appending its children at depth preserves that order. The inner loop invariant says that precisely moves of the removed state have been appended; its loop variant is while the guard holds. The first identity state removed therefore has the minimum possible number of moves. A stack-based depth-first search does not generally have that property.
def solve(puzzle: Flip): Flip = {
val pending = scala.collection.mutable.Queue[Flip]()
pending.enqueue(puzzle)
while (!pending.isEmpty) {
val current = pending.dequeue()
if (current.isIdentity) return current
var k = 2L
while (k <= current.game.length.toLong) {
pending.enqueue(current.flip(k.toInt))
k += 1L
}
}
throw new IllegalStateException("No solution")
}
val puzzle = new Flip(n)
println("Solving:")
println(puzzle)
val answer = solve(puzzle)
println("Solved:")
println(answer)Termination does not rely on avoiding repeats in this first version. Every permutation can be sorted by prefix reversal sorting: place the largest misplaced value at the front if necessary, flip it into its final position, and repeat on the shorter prefix. This constructs a route of at most moves. Each search depth has finitely many paths, with at most children per path, so breadth-first search reaches some solution depth after finitely many expansions. This gives a finite bound on remaining expansions before the first solution even though the repeated-state path tree is infinite. The one-element game is already solved. Repeated paths can nevertheless make time and storage enormous; part (e) removes that waste.
Give each solving session a shared visited set keyed by immutable snapshots of permutation contents, for example
game.toList, and insert the initial snapshot immediately. Have all successor objects refer to that same session's set. The refined flip first constructs the candidate state; if its key is present, return None. Otherwise add the key immediately and return Some(candidate). The search enqueues only Some results. Keys must compare contents rather than array identities, and a fresh solving session must start with a fresh visited set.Marking at generation time prevents the same state from being queued repeatedly, including the immediate cycle made by applying the same reversal twice. First discovery in breadth-first search already has minimum depth, so discarding later discoveries cannot remove a shorter solution. The graph now has at most admitted states. If only cycles along one path were to be rejected, a path-local set would suffice, but it would still repeat states reached by different paths; the shared session-wide set avoids both kinds of repetition. Public game fields must not be externally mutated while their states are being searched.
Keep a deficient interval of possible values and only the array segment containing occurrences from that interval. This is missing-value search by deficient value intervals:The precondition is that every original entry lies in . The loop invariant istogether with: every active entry lies in , and every original occurrence with a value in that interval is in the active segment. The whole array remains a permutation of its initial contents. Initially these assertions follow from the precondition and .
def missing(): Int = {
val n = a.length
var lo = 0L
var hi = n.toLong + 1L
var l = 0
var r = n
while (hi - lo > 1L) {
val p = lo + (hi - lo) / 2L
val k = partition(l, r, p.toInt)
if ((k - l).toLong < p - lo) {
hi = p
r = k
} else {
lo = p
l = k
}
}
lo.toInt
}After array partitioning, the low subinterval has occurrences and possible values. If it is deficient, retaining it preserves the loop invariant. Otherwise , while the original active count is strictly less than ; subtraction givesThus the high subinterval is deficient and retaining it also preserves the loop invariant. Discarded occurrences lie outside the new candidate interval. The loop variant is the positive integer , which strictly decreases because the midpoint is strictly internal. At exit the interval has one possible value and fewer than one occurrence, so
lo is absent from the entire original array. For the loop is skipped and zero is returned. The Long value bounds avoid overflowing ; every internal pivot is at most , so its checked mathematical range fits Int.For the time complexity, let be the interval width and its active occurrence count before iteration . The loop invariant gives , and binary search gives . Each two-way array partition costs . Until the width reaches one, the widths are bounded by , so the total scan work is bounded by a geometric series plus loop overhead: overall, hence for positive . Partitioning the full array again at every iteration would instead lose this bound. Auxiliary space complexity is .
For , choose an ordered list of distinct elements: there are such lists. Every -element subset occurs in exactly orders, the number of permutations of its elements. Thus the count is the binomial coefficientFor fixed and , every numerator factor lies between and . ConsequentlyThe constants depend on the fixed , not on . These inequalities prove in big theta notation. More precisely, dividing the product by gives the fixed-cardinality binomial coefficient asymptotic . For , there is exactly one empty subset, and the assertion is .
Every position in the random permutation has the same marginal colour probability, so . One can verify this with the law of total probability, conditioning on the first card:Here because both colour counts are positive.
