Bees make honeycombs of hexagonal wax cells. The shape of the cells provides a highly efficient layout, increases strength and reduces the amount of wax required to produce a robust structure. As a result, the available space is used in an optimal way for storing honey and energy is saved in wax production, because the production of one kilogram of wax costs four to six kilos of honey.
In nature, hexagonal structures also exists in the form of graphite, where each sheet of graphene resembles chicken wire, with strong covalent carbon bonds. Tubular graphene sheets called carbon nanotubes are also being synthesized. They have many potential applications, due to their high tensile strength and electrical properties.
The beauty of nature is also mimicked indoors, where mosaic patterns of hexagon tiles add unique character and geometric elegance to kitchens, bathrooms, living rooms and bedrooms. Offering a timeless finish, these versatile tiles seamlessly complement subtle and bold interiors alike, making them an increasing popular walling and flooring option for a multitude of interior environments.
To describe patterns in grids of hexagonal cells, we need a coordinate system that uniquely determines the position of each cell. We consider grids in which the hexagons are pointing up and use an axial coordinate system. In it, the position of each cell is indicated by a pair of coordinates $$(q, r)$$, with $$q, r \in \mathbb{N}$$.
Each hexagonal cell has six neighbors that are east (E), southeast (SE), southwest (SW), west (W), northwest (NW) and northeast (NE) of the cell. The directions of these six neighbors are indicated by strings (str) with one or two uppercase letters, as shown in the preceding listing. This is the relationship between the axial coordinates $$(q, r)$$ of a cell an the axial coordinates of its six neighbors:
If we choose a reference cell with axial coordinates $$(0, 0)$$ in a grid of hexagonal cells, the axial coordinates of its surrounding cells are:
The distance between a hexagon $$h$$ with coordinates $$(q, r)$$ and a hexagon $$\bar{h}$$ with coordinates $$(\bar{q}, \bar{r})$$ is defined as the minimal number of steps to neighboring cells needed to go from cell $$h$$ to cell $$\bar{h}$$. This distance is computed as \[ \frac{1}{2}(|q - \bar{q}| + |r - \bar{r}| + |q + r - \bar{q} - \bar{r}|) \] where $$|x|$$ represents the absolute value of $$x$$.
Define a class Hexagon that can be used to represent hexagonal cells (pointing up) in a grid with an axial coordinate system. When creating a hexagon (Hexagon), the coordinates $$q$$ (int) and $$r$$ (int) of the cell must be passed. Hexagons are immutable.
If a hexagon (Hexagon) is passed to the built-in function str, a description (str) of the position of the hexagon must be returned. If a hexagon (Hexagon) is passed to the built-in function repr, a string representation (str) must be returned that reads as a Python expression to create a new hexagon (Hexagon) at the same position as the hexagon passed to the function repr.
To enable adding hexagons (Hexagon) to sets (set), the built-in function hash must return the hash value of hexagons and the operator == must determine if two hexagons are equal. Make sure a hexagon (Hexagon) with coordinates $$(q, r)$$ has the same hash value as a tuple $$(q, r)$$. Make sure that two hexagons (Hexagon) are equal if and only if they are at the same position in the grid.
In addition, it should be possible to call at least the following methods on a hexagon $$h$$ (Hexagon):
A method distance that takes a hexagon $$\bar{h}$$ (Hexagon). The method must return the distance (int) between $$h$$ and $$\bar{h}$$.
A method neighbor that takes a direction (str). The method must return the neighbor (Hexagon) of $$h$$ in the given direction.
A method path that takes a description (str) of the directions of neighboring cells that must be visited successively, starting from $$h$$. These directions are joined together without a separator. The method must return the hexagon (Hexagon) that is finally reached.
A method neighbors that takes no arguments. The method must return a set (set) with the six neighbors (Hexagon) of $$h$$.
>>> tile = Hexagon(0, 0)
>>> tile
Hexagon(0, 0)
>>> print(tile)
(0, 0)
>>> tile.distance(Hexagon(4, 3))
7
>>> tile.neighbor('E').neighbor('SE').neighbor('NE').neighbor('E')
Hexagon(3, 0)
>>> tile.neighbor('NW').neighbor('W').neighbor('SW').neighbor('E').neighbor('E')
Hexagon(0, 0)
>>> tile.path('ESENEE')
Hexagon(3, 0)
>>> tile.path('NWWSWEE')
Hexagon(0, 0)
>>> tile.path('ESENEE') == tile
False
>>> tile.path('NWWSWEE') == tile
True
>>> hash(tile)
3713080549408328131
>>> tile.neighbors()
{Hexagon(0, 1), Hexagon(-1, 1), Hexagon(-1, 0), Hexagon(0, -1), Hexagon(1, 0), Hexagon(1, -1)}