19
1
Background
I was inspired by 3Blue1Brown's recent video about the necklace splitting problem (or as he calls it, the stolen necklace problem) and its relationship to the Borsuk-Ulam theorem.
In this problem, two thieves have stolen a valuable necklace consisting of several different types of jewels. There are an even number of each type of jewel and the thieves wish to split each jewel type evenly amongst the two of them. The catch is that they must do so by splitting the necklace into some number of contiguous segments and distribute the segments between the two of them.
Here is an example with four jewel types denoted S
, E
, D
, and R
(for sapphire, emerald, diamond, and ruby, respectively). Let's say the necklace is as follows:
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
There are 8
sapphires, 10
emeralds, 4
diamonds, and 6
rubies. We can split the necklace as follows:
[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
Then if we give the first, third, and fifth segments to one thief and the second and fourth segments to the other thief, each will end up with 4
sapphires, 5
emeralds, 2
diamonds, and 3
rubies:
[S], [S,E,S,D,E,R,S], [R,R,D,E,E,E]
[S], [R,E,S,S,S,D,R,E,E,R,E,D,E],
Using 0
-indexing, these cuts occur at the indices [1,2,9,22]
.
Goal
It turns out that such a fair division can always be done using at most n
cuts, where n
is the number of jewel types. Your task is to write a complete program or function which takes a necklace as input and outputs a minimal such division (fewest number of cuts).
Input
Input may be in any convenient format. The necklace should be a sequence of jewels and nothing more; e.g. a list of integers, dictionary with keys representing the jewel types and values being lists of indices. You may optionally include the length of the necklace or the number of distinct jewel types, but you should not take any other input.
You may assume that the input necklace is valid. You do not need to handle the case where there is an odd number of jewels of a given type or the necklace is empty.
Output
Again, output may be in any convenient format; e.g. a list of segments, a list of cut positions, a dictionary with keys representing the two thieves and values being lists of segments, etc. Segments may be represented by their starting index, ending index, list of consecutive indices, list of jewels, their lengths, etc. You may use 0
- or 1
- indexing. If the ordering is not significant to your format, then your output may be in any order. Here is the above output in several different formats:
list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
list of cuts: [1,2,9,22]
list of lengths: [1,1,7,13,6]
dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]}
Note that order is important in the list of segments (segments alternate between the thieves) and the list of lengths (in order to identify the segments), but not in the list of cuts or the dictionary. Edit: Greg Martin pointed out that these wouldn't be valid outputs since a fair division can be obtained in two cuts
Test cases
[1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]]
[1,1,1,1,2,2,3,3,3,3,3,3] -> [[1,1],[1,1,2],[2,3,3,3],[3,3,3]]
[1,1,1,1,1,1,1,1,1,1,1,1] -> [[1,1,1,1,1,1],[1,1,1,1,1,1]]
[1,1,1,1,2,3,4,2,3,4,2,2] -> [[1,1],[1,1,2,3,4,2],[3,4,2,2]]
Notes
- Standard loopholes are forbidden.
- This is code-golf; shortest answer (in bytes) wins.
2Is the necklace circular? – Dennis – 2017-02-10T21:41:53.507
1@Dennis No, the necklace is linear. – ngenisis – 2017-02-10T21:45:09.287
May we represent each segment in the output by its length? – John Dvorak – 2017-02-10T21:47:46.693
@JanDvorak I will add that as an option. – ngenisis – 2017-02-10T21:50:26.187
Note to adjust note #2 as it clashes with that option. – John Dvorak – 2017-02-10T21:51:24.930
@JanDvorak Noted. I hope I've covered my bases sufficiently now. – ngenisis – 2017-02-10T21:55:26.823
I think you did. Still not sure why you don't allow outputting just the segments themselves instead of indices. – John Dvorak – 2017-02-10T21:56:14.430
@JanDvorak To be honest, I don't know either. I'll remove it. – ngenisis – 2017-02-10T21:57:16.040
1Can we take the input as letters/tokens indicating the different jewel types, instead of integers? – Greg Martin – 2017-02-10T22:34:51.260
1So, is there anything wrong with just returning a list of the segments themselves? – Jonathan Allan – 2017-02-10T22:49:42.607
3If the order of segments isn't changed, the pieces alternate between theif A and theif B. As such, including that information in the output is redundant. Can we omit the theif indication if the answer doesn't change the order of the jewels? Do you have some test cases? – Luke – 2017-02-10T22:53:27.370
@GregMartin Yes, you may take input in any reasonable format. – ngenisis – 2017-02-10T23:49:47.013
@JonathanAllan That's fine. – ngenisis – 2017-02-10T23:49:59.687
@Luke I added a few. – ngenisis – 2017-02-11T00:01:39.423
2For your example
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
, it seems that the output should be[[S,S,S,E,S,D,E,R],[S,R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
, since that has fewer cuts than[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
. Am I understanding the spec correctly? – Greg Martin – 2017-02-11T06:13:19.833@GregMartin Indeed I was just about to ask the same question. The spec says "a minimal such division" which doesnt make sense semantically, because OP just stated it can be done in at most
n
cuts son
is in a way the maximum. The minimum in this case is 2, notn=4
. Given the example, my understanding was the exact opposite of yours,i.e. it is sufficient to do it inn
cuts.. – Level River St – 2017-02-11T08:26:16.997I agree the example seems to imply that; however, "minimal such division (fewest number of cuts)" is a quote from the problem statement. – Greg Martin – 2017-02-11T08:39:54.707
@GregMartin You're correct. The intention with that example wasn't to show a minimal division, but I didn't do a good job explaining that. – ngenisis – 2017-02-11T17:32:48.690