Series: Modeling logic puzzles
Phần: 8 / 91. Introduction
Skyscraper is a logic puzzle described as follows: given an grid representing a city block seen from above, the player needs to fill each cell with the height of a building, from to , satisfying the following conditions:
- Each row and each column contains every height from to , each value appearing exactly once.
- Numbers placed outside the grid indicate how many buildings can be seen when looking into the grid from that side, where a building is considered visible if it is taller than all other buildings standing between it and the viewer.
Source: Conceptis Puzzles
To picture this, take a look at the example below.
Looking from the left, the building of height is visible (nothing stands in front of it), the building of height is hidden behind it, the building of height breaks through and is visible, and the remaining two buildings ( and ) are both shorter than so they stay hidden - so exactly buildings are visible.
Below is an example of a 5×5 Skyscraper puzzle and its solution.
2. Modeling the puzzle
Some symbols used in this problem
- is the size of the grid
- is the set of pairs representing the coordinates of the pre-filled cells in the grid
- is the height filled in cell
- is the set of sight lines: reading each row left-to-right and right-to-left, and each column top-to-bottom and bottom-to-top, gives sight lines in total. For a sight line , () is the cell standing at position counting from the viewer, so is the cell closest to the viewer
- is the number of buildings visible for sight line
2.1. Decision variables
For each cell in the grid and a height , we build a variable such that
2.2. Constraints
- Each cell has exactly one height
- Each row contains every height from to , each value exactly once
- Each column contains every height from to , each value exactly once
- Pre-filled cells
-
The number of buildings visible on each sight line must match the requirement.
Looking along a sight line from the viewer's side, a building is considered visible if it is taller than every building standing between it and the viewer. For each sight line , position and height , we build an additional intermediate variable such that
Let
be the number of buildings standing between the viewer and position on sight line that are taller than (this sum is simply when , since no building stands before the first one). Using the geometric method we can represent the variable through the variables and with the following conditions
Notice that we don't need to treat the closest building or the tallest building as special cases. When , for every , so the conditions above reduce to : the closest building is always visible, no matter its height. Likewise, when , for every , since no building is taller than , so : the tallest building is always visible, wherever it stands. Both edge cases hold automatically under the general formula, we don't need to add anything extra.
Finally, the requirement on the number of buildings that must be visible on sight line is satisfied by the condition
2.3. Objective function
This problem does not have an objective function, as we are not aiming to minimize or maximize anything, all we need is to find a feasible solution. Technically, when programming, we can set the objective function to a constant (I often choose 0).
3. Conclusion
The highlight of this puzzle lies in modeling the condition on the number of buildings visible along a sight line. It looks fairly simple at a glance, but turns out quite intricate once we have to build an entire system of intermediate variables and constraints to handle it.
For more Skyscraper puzzles and variations, please refer to Krazydad. The Python code for Skyscraper modeling is available at Tung-hehe.
Happy modeling!
