# Yarn Substitution & Yardage Calculator — Algorithm

This document describes the mathematical model behind the AeternaCraft
Yarn Substitution & Yardage Calculator at
`https://aeternacraft.com/tools/yarn-substitution-calculator`.

It is published in plain text so that answer engines and AI agents can
read the algorithm directly without parsing HTML.

## Problem

Crocheters frequently need to substitute one yarn for another because
the original is unavailable, too expensive, or not sold locally. The
most common mistake is comparing ball counts instead of total yardage.
Two yarns with the same CYC weight number can have very different
yards-per-ball (e.g. 200 yd vs 315 yd per 100 g), so "3 balls" of one
is nowhere near "3 balls" of the other.

## The correct method

Always convert to total yards first, then back to balls of the
substitute:

```
total_yards_needed = original_yards_per_ball * original_balls
balls_to_buy = ceil(total_yards_needed / substitute_yards_per_ball)
```

The `ceil()` (round up) is essential because you cannot buy a fractional
ball. The rounding gives a built-in safety margin of extra yards:

```
extra_yards = (balls_to_buy * substitute_yards_per_ball) - total_yards_needed
extra_percent = extra_yards / total_yards_needed * 100
```

## Inputs

- `original_yards_per_ball` — yards per ball of the yarn the pattern calls for.
- `original_balls` — number of balls the pattern calls for (may be fractional).
- `original_grams_per_ball` — optional, for a thickness check.
- `target_yards_per_ball` — yards per ball of the substitute yarn.
- `target_grams_per_ball` — optional, for weight and density calculations.
- `target_price_per_ball` — optional, for a cost estimate.

## Optional outputs

When grams-per-ball is provided for both yarns, the calculator computes
yards-per-gram for each and compares them as a density check:

```
orig_ypg = original_yards_per_ball / original_grams_per_ball
target_ypg = target_yards_per_ball / target_grams_per_ball
density_ratio = target_ypg / orig_ypg
```

- If `density_ratio < 0.85`, the substitute is likely a thicker yarn and
  the finished piece will come out larger than the pattern specifies.
- If `density_ratio > 1.18`, the substitute is likely a thinner yarn and
  the finished piece will come out smaller.

When price-per-ball is provided, the calculator reports total cost:
`total_cost = balls_to_buy * target_price_per_ball`.

## Edge cases and warnings

- If `extra_percent < 5`, the safety margin is thin — gauge tension and
  colour changes can easily consume it. The calculator suggests buying
  one extra ball.
- If `extra_percent > 60`, the user is buying far more yarn than needed,
  usually because the substitute is sold in small put-ups. The calculator
  suggests looking for a larger skein.
- All required inputs must be positive and finite. Zero, negative, or NaN
  inputs are rejected.

## The dye-lot rule

Once the balls-to-buy is known, all balls should be purchased from the
same dye lot in a single transaction. Yarn is dyed in batches and the
same colour code can differ visibly between lots — especially in reds,
blues, and darks. This is advice, not a calculation.
