Metadata-Version: 2.4
Name: oeis-seek
Version: 0.1.0
Summary: Transform-aware identifier for OEIS integer sequences
Project-URL: Homepage, https://github.com/niarenaw/oeis-seek
Project-URL: Repository, https://github.com/niarenaw/oeis-seek
Project-URL: Issues, https://github.com/niarenaw/oeis-seek/issues
Author: niarenaw
License-Expression: MIT
License-File: LICENSE
Keywords: cli,integer-sequences,mathematics,oeis,sequence
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.11
Requires-Dist: platformdirs>=4.0
Description-Content-Type: text/markdown

# oeis-seek

[![CI](https://github.com/niarenaw/oeis-seek/actions/workflows/ci.yml/badge.svg)](https://github.com/niarenaw/oeis-seek/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/oeis-seek.svg)](https://pypi.org/project/oeis-seek/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

Identify the OEIS sequence a list of integers belongs to - even when the raw
numbers are not in OEIS but a simple transform of them is.

`oeis-seek` works offline against a local copy of the
[OEIS](https://oeis.org/) bulk dump. You download the dump once, then look up
sequences with no network calls and no rate limits.

## Install

Install the released CLI from PyPI (the package is `oeis-seek`; it installs a
`oeis-seek` command):

```bash
uv tool install oeis-seek    # or: pipx install oeis-seek, or: pip install oeis-seek
```

Or work from a clone:

```bash
uv sync
```

## Usage

First, download and index the OEIS dump (one time; re-run to refresh):

```bash
oeis-seek update
```

Then identify a sequence:

```bash
oeis-seek 0,1,1,2,3,5,8,13          # -> A000045 (Fibonacci), raw match
oeis-seek 2,6,12,20,30,42           # -> hit via first differences
echo "1 2 6 24 120" | oeis-seek     # terms from stdin
oeis-seek 2,6,12,20 --json          # machine-readable output
oeis-seek 2,6,12,20 --limit 5       # cap results (default 10)
```

Terms may be comma- or whitespace-separated, passed as arguments or piped on
stdin. At least four terms are required by default (`--min-terms` lowers it).

## How it works

Three ideas do the work.

### The matcher (framed-substring contiguous match)

The index stores each sequence's terms as a comma-framed string,
`,0,1,1,2,3,5,`. A lookup frames the query the same way, `,1,2,3,5,`, and asks
which stored sequences contain that substring. Framing the run on both sides
makes substring containment exactly the contiguous-subsequence predicate OEIS
itself uses: term boundaries hold (`2,3` cannot match inside `23`), terms must be
adjacent, and signs are respected. At ~370k sequences this resolves well under a
second, so the MVP needs no inverted index.

### The transforms

Before matching, `oeis-seek` also tries simple transforms of your input and looks
each result up:

- **raw** - the input as given
- **first differences** - `a(n+1) - a(n)`
- **partial sums** - running totals
- **consecutive ratios** - `a(n+1) / a(n)` (later over earlier), used only when
  every ratio divides exactly, e.g. `1, 2, 6, 24` becomes `2, 3, 4`
- **higher-order differences** - first differences applied repeatedly (orders 2
  and 3)
- **a(n) - n** and **a(n) / n** - subtract or divide by the 0-based index (the
  latter integer-only)
- **absolute values** - `abs(a(n))`, to recognize a signed sequence by magnitude

Transforms live in a registry, so adding more later is one function plus one
registration.

### The ranking

Every hit gets a deterministic, explainable score. Matches needing no transform
rank above transformed ones, more matched terms rank higher, and sequences in
OEIS's curated `core` set are boosted so canonical sequences outrank obscure ones
that merely share a run. A run found near a sequence's opening is weak extra
evidence over one buried deep inside, and ties resolve by ascending A-number so
output is stable. All scoring weights live in one place, and each result tells
you which transform found it and why it ranked where it did.

## Development

Lint, format, and test:

```bash
uv run ruff check .
uv run ruff format .
uv run pytest
```

CI runs ruff and pytest on every push and pull request.

To refresh the embedded OEIS core set:

```bash
uv run python tools/generate_core_set.py
```
