I'm really banging my head against the wall with this, as I have very little experience with algorithms.
Consider an app that maintains a set of TV shows and the episodes for those shows. The user is allowed to rank the shows (rank, not rate; so from 0 to n-1, 0 being the highest ranking).
The app is designed to present a list of episodes based on ranking of the shows. At any given time there are 0, 1, or 2 episodes that the app will display in the list for each show (ie, if the user has watched all episodes of TheFooShow, no episodes will appear in the list; if she has 10 unwatched episodes of TheBarShow, two will appear in the list). Those episodes will be considered primary
and secondary
.
The ordering of episodes within the list should adhere to some rules as best as possible:
- The primary episode of a show in the list should appear before any episodes of lower-ranked shows
- The secondary episode of a show should never appear before the primary episode of the same show
- If possible, no two episodes of a show should be within 4 positions of each other
- The secondary episode of a show can appear before the primary episode of a show ranked seven or more positions worse
- etc
The point here is that episodes from a high ranking show will be listed before lower ranking shows, but only to the degree that a certain amount of variety is introduced whenever possible.
An example set could be (not strictly following the above rules): [0, 1, 3, 0', 3', 4, 5, 10, 4', 11, 11', 23]
I can get close to achieving the desired results when constructing the list from scratch, adding all the primary episodes, and then inserting the secondary episodes as necessary. Unfortunately given how the rest of the app works, I need to be able to insert episodes into an already-constructed list.
Given how the underlying episode data changes, whenever an episode needs to be inserted, all episodes for that show already in the list will be removed, the current set of episodes for that show will be discovered, and they (or it) will be inserted back-to-back.
I would essentially like a function such as:
- (int, int)indexesForEpisodesFromShow:(TVShow)aShow currentList:(List)aList
Which can take a list in any state and, given a show, take the appropriate episodes and determine where in the list they should be inserted.
My current solution is fairly primitive, and as I said only works in certain situations. I have tried other solutions that are more complex (read: more if statements), but they tend to become very fragile, and when I add additional complexity to handle edge cases, tests start to contradict other tests.
I feel like the given the kinds of rules I'm trying to implement, and how few there are, this should be solvable, but after many attempts I'm still stuck. Any help would be greatly appreciated.