When stacking books you usually want to put the largest ones at the bottom and the smallest ones at the top. However, my latent OCD makes me feel very uneasy if I've got two books where one is shorter (in height) but wider than the other. No matter which order I place them in, the top book will extend beyond the bottom book on one side.
As an example, say one book has dimensions (10,15)
and another has dimensions (11,14)
. No matter which way around I put them, I get an overhang. But if I have books with dimensions (4,3)
and (5,6)
, I can avoid an overhanging by placing the latter below the former.
For the purposes of this challenge we will consider overhangs only in relation to the book immediately below. E.g. if I have a stack (5,5)
, (3,3)
, (4,4)
(not that any sane person would do that), the top book counts as an overhang, although it does not extend beyond the bottom book. Similarly, the stack (3,3)
, (3,3)
, (4,4)
also has only one overhang, despite the top book extending beyond the bottom one.
The Challenge
Given a list of integer pairs for book dimensions, sort those pairs/books such that the number of overhangs is minimal. You must not rotate the books - I want all the spines facing the same direction. If there are multiple solutions with the same number of overhangs, you may choose any such order. Your sorting algorithm does not have to be stable. Your implementation may assume that book dimensions are less than 216 each.
Time complexity: To make this a bit more interesting, the asymptotic worst-case complexity of your algorithm must be polynomial in the size of the stack. So you can't just test every possible permutation. Please include a short proof of your algorithm's optimality and complexity and optionally a plot that shows the scaling for large random inputs. Of course, you can't use the maximum size of the input as argument that your code runs in O(1).
You may write a program or function, take input via STDIN, ARGV or function argument in any convenient (not preprocessed) list format and either print or return the result.
This is code golf, so the shortest answer (in bytes) wins.
I am confident that a polynomial-solution exists, but if you can prove me wrong, you may submit such a proof instead of a golfed submission. In this case, you may assume P ≠ NP. I will accept the first correct such proof and award a bounty to it.
Examples
In: [[1, 1], [10, 10], [4, 5], [7, 5], [7, 7], [10, 10], [9, 8], [7, 5], [7, 5], [3, 1]]
Out: [[10, 10], [10, 10], [9, 8], [7, 7], [7, 5], [7, 5], [7, 5], [4, 5], [3, 1], [1, 1]]
In: [[4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [5, 4], [4, 5]]
Out: [[4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [5, 4]]
or [[5, 4], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5]]
In: [[2, 3], [1, 1], [5, 5], [7, 1]]
Out: [[5, 5], [2, 3], [7, 1], [1, 1]]
or [[5, 5], [2, 3], [1, 1], [7, 1]]
or [[7, 1], [5, 5], [2, 3], [1, 1]]
or [[7, 1], [1, 1], [5, 5], [2, 3]]
I created these by hand, so let me know if you spot any mistakes.