New Exercise Proposal: Essential Accords

Ciao!
I hope you haven’t missed me too much. Today, our boutique is offering you a wide range of perfumes!

Exercism currently lacks exercises exploring Boolean function simplification, digital logic, and switching theory. General Boolean minimization can produce multiple non-unique minimal covers (e.g. cyclic charts in Petrick’s method), making automated cross-track testing difficult.

Essential Accords resolves this by focusing on identifying Essential Prime Implicants (EPIs) with support for don’t-care conditions. Because the set of Essential Prime Implicants is mathematically unique for any Boolean function, inputs and outputs are 100% deterministic.

The problem is wrapped in an artisanal perfumery narrative, where binary variables are fragrance notes, minterms are bespoke client recipes, and essential prime implicants are indispensable base accords that the atelier must prepare.


Introduction

Nestled in the sun-drenched hills of Grasse, the historic perfume capital, stands the venerable atelier of Maison l’Essence.
As the junior apprentice to the atelier’s renowned Nez (Master Perfumer), you spend your days in front of the perfumer’s organ—a tiered semi-circular console holding hundreds of amber crystal flacons of precious aromatic extracts.

For the upcoming Grand Solstice Gala, the atelier has been commissioned to produce a collection of bespoke perfumes.
Each creation in the commission is defined by a precise harmony of fragrance notes—such as Bergamot, Jasmine, Cedarwood, and Amber.
An ingredient is either present (1) or omitted (0).
The master ledger lists every approved formula as a unique recipe.

The gala is only days away, and the workshop is in crisis.

Mixing every bespoke perfume individually from scratch would require dozens of custom vials, quickly overwhelming the atelier’s limited bench space and glassware.
Fortunately, the master perfumer knows a trade secret: perfumers rarely mix every recipe from scratch.
Instead, they pre-blend versatile base accords—foundational combinations that leave certain notes open, allowing multiple client perfumes to be crafted from a single shared decanter.

The Master opens a grid ledger and begins sketching a geometric map of the scents:

“Observe! When recipes differ by only a single note, they blend together into a larger accord.
But beware: some rare, fragile perfumes can only ever be produced by a single, specific accord.
These are our Essential Accords.
If you fail to prepare even one of them, those signature fragrances cannot be bottled!”

Before the distillation alembics are lit, you must examine the commission’s scent ledger, map out the fragrance combinations, and identify every essential accord that the atelier must prepare.


Instructions

Your task is to identify all essential base accords needed to satisfy a commission of bespoke perfumes.

The Fragrance Ledger

Each perfume formula is defined by N binary fragrance notes.
A formula is represented as an integer minterm whose binary representation indicates which notes are present:

  • Bit 1: Note is included.
  • Bit 0: Note is omitted.

Notes are ordered from most significant bit to least significant bit.
For example, with N = 4 notes ordered A, B, C, D:

  • Formula 13 (1101_2) contains notes A, B, and D, but omits note C.
  • Formula 3 (0011_2) contains notes C and D, but omits notes A and B.

Commission Types

You will be given two sets of formulas:

  1. Mandatory Perfumes (minterms): The official client requests for the gala.
    Every single one of these formulas must be covered by at least one base accord.
  2. Optional Formulas (dontCares): Experimental or seasonal variations known to the atelier.
    You may freely use these formulas to expand and simplify base accords, but they do not require coverage.

The Accord Map

To find which formulas can be blended together, place all possible formulas on a grid arranged in Gray code order (where adjacent rows and columns differ by exactly one note):

       CD
    \  00  01  11  10
  AB +---+---+---+---+
  00 |   | 1 | 1 |   |
     +---+---+---+---+
  01 | 1 | 1 |   |   |
     +---+---+---+---+
  11 | 1 | 1 |   |   |
     +---+---+---+---+
  10 |   |   |   |   |
     +---+---+---+---+

The grid wraps around in all directions:

  • The top edge is adjacent to the bottom edge.
  • The left edge is adjacent to the right edge.
  • The four corners are adjacent to one another.

Building Accords

Formulas that are adjacent can be grouped into rectangular accords whose dimensions are powers of two (1, 2, 4, 8, \dots).
Merging adjacent cells eliminates the note that differs:

An accord is represented as a string of length N using cube notation:

  • '0': The note is omitted in this accord.
  • '1': The note is present in this accord.
  • '-': The note was eliminated (it can be present or absent).

A prime accord is an accord that has been expanded as large as possible—it cannot be doubled in size without including an invalid (unapproved) cell.
Both mandatory perfumes and optional formulas can be included when forming prime accords.

Identifying Essential Accords

Some perfumes might be covered by multiple overlapping prime accords.
However, if a mandatory perfume is covered by only one prime accord, that accord is essential (indispensable): without it, that client perfume cannot be crafted!

Optional formulas do not make an accord essential; only mandatory perfumes can do so.

Step-by-Step Example

Suppose N = 4 notes (A, B, C, D) with:

  • minterms = [1, 3, 4, 5, 12, 13]
  • dontCares = []

1. Find Prime Accords

  • Formulas 1 (0001) and 3 (0011) merge into accord "00-1".
  • Formulas 1 (0001) and 5 (0101) merge into accord "0-01".
  • Formulas 4 (0100), 5 (0101), 12 (1100), and 13 (1101) merge into accord "-10-".

2. Check Coverage of Mandatory Perfumes

  • Perfume 3 is only covered by "00-1": therefore, "00-1" is essential.
  • Perfumes 4, 12, and 13 are only covered by "-10-": therefore, "-10-" is essential.
  • Accord "0-01" covers perfumes 1 and 5.
    However, perfume 1 is already covered by "00-1", and perfume 5 is already covered by "-10-".
    Therefore, "0-01" is not essential.

3. Result

The essential accords are:

["-10-", "00-1"]

Output Requirements

Return an array containing all essential accords as strings in cube notation.
The strings must be sorted in lexicographical order (ASCII order: '-' < '0' < '1').
If no essential accords exist, return an empty array [].


Canonical Data Structure

{
  "uuid": "8f8b8098-ff25-4b00-8451-b062ca3f31cf",
  "description": "instructions example walkthrough",
  "property": "essentialAccords",
  "input": {
    "variableCount": 4,
    "minterms": [1, 3, 4, 5, 12, 13],
    "dontCares": []
  },
  "expected": ["-10-", "00-1"]
}

On the one hand, I like this idea. On the other hand, I’m having a hard time parsing and understanding all of that, let alone figuring out how to even start approaching this with code.

This exercise could easily be classified as upper-intermediate or lower-advanced.
We could simplify it by removing the dontCares.
Let me know if you need anything: a complete canonical-data, a Python code example, or anything else.
As always, I’m open to suggestions.

The worked example is super helpful. The prose just feels more dense and technical/complicated than any of the other exercises. I’m eager to hear what others think.

Thanks for the exercise!

Our general rule is to make exercises read like more natural stories and less like equations. I’m having to work very hard to understand this language as someone who is not used to phrases like “…represented as an integer minterm whose binary representation …”

So I’d suggest we rewrite this to be in more simple english, such as the variant below.

Each perfume formula can be expressed as a series of 1s and 0s for each different fragrance notes they contain. For example:

  • A formula of 1101 contains notes A, B, and D, but omits note C.
  • A formula of 0011 contains notes C and D, but omits notes A and B.

I don’t know what the subscript 2 is doing here, so maybe that’s important. And I’m not sure if the 13 == 1101 is important here from this first section.

We’d need to work through the rest of this to simplify it too, before my tired brain could make enough sense of it all to know how to start with code :slight_smile:

Instructions

Your task is to identify which base accords are essential (indispensable) to prepare for a perfume commission.

The Fragrance Recipes

In this atelier, each perfume is defined by a list of N ingredients (notes), numbered from left to right.
For each ingredient, a recipe either includes it (1) or leaves it out (0).

A recipe can be written as a binary code or as its decimal number:

  • With 4 ingredients, recipe 3 is 0011 (leaves out the first two ingredients, includes the last two).
  • Recipe 13 is 1101 (leaves out the third ingredient).

What is an Accord?

Instead of bottling every recipe separately, you can merge similar recipes into a shared blend called an accord.
An accord uses a wildcard dash (-) to mean: “this ingredient does not matter—it can be in or out”.

For example:

  • Recipe 0001 (third ingredient is out)
  • Recipe 0011 (third ingredient is in)

Because these two recipes differ by only that single ingredient, they merge into a single accord: 00-1.
One bottle of 00-1 can satisfy both recipes!

Rules for Accords

  1. Powers of two: Recipes can only merge in groups of 1, 2, 4, 8, 16, etc.
    • 2 recipes that differ in 1 ingredient merge into an accord with 1 dash (e.g. 00-1).
    • 4 recipes that differ in 2 ingredients merge into an accord with 2 dashes (e.g. -10-).
  2. Prime accords: You always want to make an accord as general as possible (with as many dashes as possible).
    An accord is prime if it cannot be merged any further without accidentally including recipes that nobody ordered.

Commission Types

You will be given two lists of recipes:

  • Mandatory Perfumes (minterms): The official client orders. Every single one of these recipes must be covered by at least one prepared accord.
  • Optional Recipes (dontCares): Experimental formulas from the workshop. You do not have to make them, but you may freely borrow them if they help you merge recipes into larger accords with more dashes!

What Makes an Accord “Essential”?

An accord is essential if it is the only prime accord that can make a specific mandatory perfume.

If you don’t prepare an essential accord, that client’s perfume cannot be made at all!
However, if an accord only covers perfumes that are already covered by other accords, it is not essential.
(Optional recipes never make an accord essential on their own).

Step-by-Step Example

Suppose we have 4 ingredients with:

  • minterms = [1, 3, 4, 5, 12, 13]
  • dontCares = []

1. Write the recipes in binary

  • 1 = 0001
  • 3 = 0011
  • 4 = 0100
  • 5 = 0101
  • 12 = 1100
  • 13 = 1101

2. Merge adjacent recipes into prime accords

  • Recipes 0001 and 0011 merge into 00-1 (Accord A).
  • Recipes 0001 and 0101 merge into 0-01 (Accord B).
  • Recipes 0100, 0101, 1100, and 1101 all merge together into -10- (Accord C).

3. Check which accord makes each recipe

Recipe Can be made by Is an accord forced to be essential?
1 (0001) Accord A (00-1) or Accord B (0-01) No (there is a choice)
3 (0011) Only Accord A (00-1) Yes! Accord A is essential.
4 (0100) Only Accord C (-10-) Yes! Accord C is essential.
5 (0101) Accord B (0-01) or Accord C (-10-) No (already covered by C)
12 (1100) Only Accord C (-10-) Already essential
13 (1101) Only Accord C (-10-) Already essential

Notice that Accord B (0-01) is not essential because all recipes it produces (1 and 5) are already produced by Accords A and C.

4. Result

The essential accords to bottle are:

["-10-", "00-1"]

A Helpful Mental Picture: The Scent Grid

If you like visual puzzles, you can picture the recipes arranged on a grid where neighboring cells differ by only one ingredient:

      00   01   11   10
    +----+----+----+----+
 00 |    |  1 |  3 |    |
    +----+----+----+----+
 01 |  4 |  5 |    |    |
    +----+----+----+----+
 11 | 12 | 13 |    |    |
    +----+----+----+----+
 10 |    |    |    |    |
    +----+----+----+----+

On this grid, accords are simply rectangles of size 1, 2, 4, or 8!
The grid wraps around in all directions (like a classic video game screen):
the top row connects to the bottom row, the left column connects to the right column, and the 4 corners touch each other.

Output Requirements

Return an array containing all essential accords as strings in cube notation.
The strings must be sorted in lexicographical order (ASCII order: '-' < '0' < '1').
If no essential accords exist, return an empty array [].


I’ve rewritten all the instructions, removing the various technical details from the text. Would this be alright?

This is much better to my eyes. Thank you. I still get about half way through and my brain explodes a little though! But I’d be interested in hearing if it’s clear to others. And then think about how we can simply the instructions a little more - probably around the order of introduced ideas.