⚡ Early vs. Late Restriction

 

⚡ Early vs. Late Restriction in Combinatorial Search

One of the core design strengths of @fizzwiz/fluent is its ability to optimize combinatorial search through early restriction of the search space — a subtle distinction that can have profound performance implications.

🚧 The Problem

Suppose you want to generate all paths of length 3 from the items [0, 1], without repetitions.

In many libraries, you generate all possible paths and then filter out the bad ones. But @fizzwiz/fluent allows you to go one step better: filter the bad paths before they’re ever constructed.


⚙️ The Code

Here’s a side-by-side comparison of early and late restriction:

const 
  // the static version of the `each()` method of the class `Each` provides a `What` of paths rather than an `Each` of arrays
  space = Each.each([0, 1], [0, 1], [0, 1]),

  // ✅ Early restriction: discarding intermediate paths like [0, 0] avoid generation of all its descendant paths like [0, 0, 0]
  earlier = new Search()
    .from(new Path())
      .through(space.which(predicate)),

  // ❌ Late restriction: filter paths after they are generated
  latter = new Search()
    .from(new Path())
      .through(space)
        .which(predicate),

In both versions, the predicate enforces that each path contains no repeated items.

🧪 Same Results, Different Cost

Both strategies produce the same final set of valid paths — but their performance is dramatically different:

⚡ Early restriction prevents the combinatorial explosion of invalid paths.

🐌 Late restriction wastes time building and examining paths that are doomed from the start.

For deep or recursive searches, the difference isn’t just academic — it’s the difference between tractable and impossible.


Thanks for exploring this idea with us.
— @fizzwiz ✨

Comments

Popular posts from this blog

🧱 v0.0.0-dev.1

✨ Bridging Natural Language and Code