minizinc

Concatenate 2 Arrays minizinc


Below I have 2, 2D Arrays (A-2Rows x 3Columns, B-2Rows x 1Column )

A=[|1,2,3     B=[|1
   |4,5,6|]      |1|]

I need to concatenate these 2 Arrays and make a new array C like below (2 Rows & 4 Columns)

C=[|1,2,3,1
   |4,5,6,1|]

PS: I am aware of adding a new row.But adding a column seems different. Could you help me to generate the array c using the concatenating of array a and b.


Solution

  • Column concatenation certainly provides more of a challenge than using rows. MiniZinc currently does not contain any nice transpose or zip features that would usually allow you to write this feature with relative ease. Instead, we have to write a recursive function that concatenates one row at a time and then appends the remaining rows:

    array[int, int] of int: A=[|1,2,3|4,5,6|];
    array[int, int] of int: B=[|1|1|];
    
    function array[int] of int: concat_row_elements(array[int, int] of int: X, array[int, int] of int: Y, int: start) =
      if start in index_set_1of2(X) then
          row(X, start) ++ row(Y, start) ++ concat_row_elements(X, Y, start+1)
      else
          []
      endif;
    
    function array[int, int] of int: concat_rows(array[int, int] of int: X, array[int, int] of int: Y) =
      let {
        constraint assert(index_set_1of2(X) == index_set_1of2(Y), "Concatenation of rows can only occur if they have the same number of rows");
      } in array2d(
        index_set_1of2(X),
        1..card(index_set_2of2(X)) +  card(index_set_2of2(Y)), 
        concat_row_elements(X, Y, min(index_set_1of2(X)))
      );
    
    array[int, int] of int: C ::add_to_output = concat_rows(A, B);
    

    This function will give the expected output: C = array2d(1..2, 1..4, [1, 2, 3, 1, 4, 5, 6, 1]);