flattenminizinc

Flatten array of counted items to array of items


I have a parameter array of record items with an amount field each, and I'd like to flatten it to an explicit list of items:

type Item = record(int: size, string: colour);
type Batch = Item ++ record(int: amount);

list of Batch: input;
int: itemsAmount = sum (batch in input) (batch.amount);
array[1..itemsAmount] of Item: items = [ ? ];

I know that:

This seems a common enough modelling scenario to warrant a standard approach, but I can't think of any. For example a global counting constraint would still weight on the solver side.

Originally I had the inputs available in this "flattened" format, but I want to switch to the succinct one which plays better with further reasoning.

If this really can't be done, is there a fundamental reason for it? I'd like to learn more


Solution

  • The construct I was looking for was in the "Indexed Array Comprehensions" section in the docs. Nested generators (with scoping) are supported and I didn't notice.

    array[1..itemsAmount] of Item: items =
    [(size: batch.size, colour: batch.colour) | batch in input, _ in 1..batch.amount];
    

    input:

    [(size: 13, colour: "red", amount: 2),
    (size: 17, colour: "blue", amount: 3),
    (size: 29, colour: "violet", amount: 0)]
    

    out:

    (colour: "red", size: 13)
    (colour: "red", size: 13)
    (colour: "blue", size: 17)
    (colour: "blue", size: 17)
    (colour: "blue", size: 17)
    

    playground

    ops!