Skip to content

UniqueSpaceCount

Namespace Nfty.Core.Generation in assembly Nfty.Core.

public record UniqueSpaceCount

How many distinct DNA a cookbook can produce. Counts only rollable recipes — a zero-weight recipe is shelved and never rolled, so its space is excluded from UniqueSpaceCount.Total even though it still appears in UniqueSpaceCount.Recipes.

UniqueSpaceCount.Total is a BigInteger, and that is not future-proofing. A layer's shapes are its variants times its reachable colors, and the recipe's space is those multiplied together — so six layers of ten variants at a 10°/10% quantize is (10 × 360)^6 ≈ 2.2e21, which is two hundred times what a Int64 holds. On a long that book reported more than 9,223,372,036,854,775,807: a constant, printed where the headline figure goes, on a card whose entire job is to let an author size a collection. The old ceiling was raised from a million to long.MaxValue for exactly this reason and merely moved the wall; there is no wall now, and the arithmetic cannot make a count inexact at all.

Constructors

UniqueSpaceCount(BigInteger, SpaceCertainty, long, IReadOnlyDictionary<string, RecipeSpace>)

public UniqueSpaceCount(BigInteger Total, SpaceCertainty Certainty, long Budget, IReadOnlyDictionary<string, RecipeSpace> Recipes);

Parameters

  • Total (BigInteger) - The distinct DNA the rollable recipes admit between them.
  • Certainty (SpaceCertainty) - What UniqueSpaceCount.Total is: the figure, a floor, a ceiling, or nothing.
  • Budget (long) - The enumeration budget the count ran under, for a message that has to name the limit somebody would raise.
  • Recipes (IReadOnlyDictionary<string, RecipeSpace>) - The per-recipe breakdown, shelved recipes included.

Properties

Budget

public long Budget { get; init; }

The enumeration budget the count ran under, for a message that has to name the limit somebody would raise.

Certainty

public SpaceCertainty Certainty { get; init; }

What UniqueSpaceCount.Total is: the figure, a floor, a ceiling, or nothing.

IsCountable

public bool IsCountable { get; }

Whether this figure means anything to show a user. UniqueSpaceCount.IsExact alone is false for two unrelated situations: a bucket set was under-counted ("more than UniqueSpaceCount.Total", a real lower bound), and the space is undefined because the book is invalid in a way that makes the question meaningless. The second reports Total == 0, and rendering that as "more than 0" states a bound that is technically true and reads like an answer.

Every front-end needs this distinction — the CLI's stats, the GUI's identity card and its per-recipe rows — so it is decided once here instead of three times, differently.

IsExact

public bool IsExact { get; }

Whether UniqueSpaceCount.Total is the real figure rather than a bound.

Recipes

public IReadOnlyDictionary<string, RecipeSpace> Recipes { get; init; }

The per-recipe breakdown, shelved recipes included.

Total

public BigInteger Total { get; init; }

The distinct DNA the rollable recipes admit between them.

this[string]

public RecipeSpace this[string recipeId] { get; }

An unknown recipe id has no space at all, and no space is exactly known.

Parameters

  • recipeId (string) - The recipe's id.

Methods

Over(IEnumerable<string>)

public RecipeSpace Over(IEnumerable<string> recipeIds);

The combined space of a SUBSET of the book's recipes — the ones a given run can actually roll.

Parameters

  • recipeIds (IEnumerable<string>) - The recipes in play. An id this count does not know contributes nothing, exactly as the indexer says.

Returns. Their summed total and combinations, and what that sum is.

Remarks

The certainty fold belongs here, not in the caller. Generator needs precisely this to say how big a space a failing run had, and built it itself — a hand-rolled overflow guard beside an &= over IsExact. That &= is the operator UniqueSpace.Combine() replaces: it cannot express a floor summed with a ceiling, which is the case that has no answer. The overflow guard is gone with the type that needed one — a BigInteger sum has nothing to clamp, and the follow-up check for "did this land on the ceiling honestly or by saturating?" is a question that can no longer be asked.