Hope someone can help me with this!
The original problem is to generate valid shifts like explained below:
I have arrays like this [m,m,m,o,o,l,l,m,m,m,l,m,m,m] with a fixed length (S) where m is work, o is office and l free. What I need to make sure is that at least every 6m I have two l together (ll). The o does not count as work or as free. Examples:
mmlmmlmmmll is not valid (7 ms without two ls)
mmlmmlmmll is valid
mmomomommll is valid
What I was trying is to create an array with 0 (for ls) and 1 (for ms) but removing from the array all the o and the non consecutive ls. So, for the above examples would be:
mmlmmlmmmll -> 111111100
mmlmmlmmll -> 11111100
mmomomommll -> 11111100
This way I could use a sliding_sum or at_least constraint to solve it. However, I cannot manage to create this new array as it would have a different size than the original (S). A valid option is to pad at the end with 0 the remaining slots until S.
Any help is appreciated
Edit. This is the code so far:
enum TypeOfShift = {l,m,o};
enum Staff = {John, Mike, Mary};
array[Staff, 1..30] of TypeOfShift: Roster=[|
m, m, m, l, l, o, m, m, m, m, l, l, l, m, m, m, m, m, m, l, l, m, m, m, m, m, l, l, l, l|
l, l, l, l, l, m, m, m, o, o, l, l, l, m, m, m, m, m, l, l, l, m, m, m, m, m, l, l, m, m|
m, m, l, l, m, o, m, m, m, m, l, l, l, m, m, m, m, m, m, m, m, m, m, m, m, m, l, l, l, m|];
array[Staff, 1..30] of var 0..2: RosterCalculated = array2d(Staff, 1..30,[if (Roster[i,d]==l) then 0 else (if (Roster[i,d]==o) then 2 else 1 endif) endif | i in Staff, d in 1..30]);
output[if (d==1) then "\n\(i) " ++ " " ++ show(RosterCalculated[i,d]) ++ " " else show(RosterCalculated[i,d]) ++ " " endif | i in Staff, d in 1..30];