Brief: I have two configurations, a
and b
, of the same set of Rummikub tiles (a
may not be a valid Rummikub config) and want to find the fewest number of pickup->place tile operations to transform a
into b
.
Type Definitions:
C = Pair<int, int>
: Card represented as a suit and value pair.CL = List<C>
: Card list.S = MultiSet<CL>
: A collection of card lists.
Problem Statement:
You are given two collections s0
, s1
, and one card list h
. (s0 union {h}
= a
and s1
= b
)
Find a minimum number of "move" operations needed to convert s0 union {h}
into s1
.
Note, s0 union {h}
will be a rearrangement of s1
.
That is, if you flatten s0 union {h}
into a CL
and similarly flatten s1
into a CL
then the two CL
are equivalent up to permutation. Note, there is at most 3 copies of any C
in s1
.
Move Operation:
Move(C c, // the card to move
CL src, // the CL to move c from
CL dst, // the CL to move c to
int dstIndex) // the index in dst to insert c to
If dst
is empty then this operation can be said to create dst
.
Similarly if, after the movement, src
is empty then the operation can be said to delete src
.
Basically, creation and deletion of CL
s is free and happens implicitly.
I do not want to consider the creation of a CL
, by itself, an operation.
Only movement of cards is an operation.
First attempt:
My first attempt at solving this was to linearize (i.e. flatten) s0 union {h}
and s1
and compute their edit distance using only insertions & deletions (insert & delete pairs form a move op).
However, the total number of edit operations depends on the order between the CL
in the linearization.
Since I want the minimum number of edit ops I would need to check each permutation of CL
s, right?
Doing so is not tractable in my application since I may have collections containing 20 or more differing CL
s.
Additional Consideration:
If it helps, changing the type of CL
to Set<C>
is possible in my application.
Basically, s0
and s1
could have inner type of Set<C>
.
But I've used List<C>
since I'm unsure if, in intermediate steps of the solution, there would be a need to have duplicates in a CL
.
Note if Set<C>
is used, then the dstIndex
argument to Move
is not needed.
Also, I would prefer if the input h
was only moved from and not moved to, but this is a soft requirement.
Any help or pointers in the right direction would be greatly appreciated!