refactor pentagons.3

This commit is contained in:
queue-miscreant 2025-03-23 22:05:24 -05:00
parent 6caf4640ac
commit bbf141785e
4 changed files with 286 additions and 326 deletions

View File

@ -33,8 +33,6 @@ import matplotlib.pyplot as plt
from tabulate import tabulate
from goldberg.common import (
GoldbergData,
GoldbergOperator,
hexagons_to_polyhedron,
group_dict,
link_polyhedronisme,

1
posts/pentagons/3/goldberg Symbolic link
View File

@ -0,0 +1 @@
../1/goldberg

View File

@ -12,27 +12,11 @@ categories:
- geometry
- combinatorics
- symmetry
# Get rid of the figure label
crossref:
fig-title: ""
fig-labels: " "
tbl-title: ""
tbl-labels: " "
title-delim: ""
custom:
- key: fig
kind: float
reference-prefix: Figure
space-before-numbering: false
- key: tbl
kind: float
reference-prefix: Table
space-before-numbering: false
---
<style>
.image-wide {
width: 384px;
width: 192px;
object-fit: contain;
}
@ -43,8 +27,7 @@ crossref:
</style>
```{python}
#| echo: false
from dataclasses import dataclass
from dataclasses import dataclass, asdict
import itertools
from typing import Callable, TypeAlias
@ -52,28 +35,91 @@ from IPython.display import Markdown
import sympy
from tabulate import tabulate
@dataclass
class PolyData:
hexagon_count: int
vertex_count: int
edge_count: int
from goldberg.common import (
hexagons_to_polyhedron,
group_dict,
link_polyhedronisme,
)
from goldberg.operators import (
t_param,
GoldbergOperator,
goldberg_operators,
goldberg_operators_to_parameters,
loeschian_numbers,
loeschian_norm,
)
@classmethod
def from_hexagons(cls, hexagon_count: int):
return cls(
hexagon_count=hexagon_count,
vertex_count=2*hexagon_count + 20,
edge_count=3*hexagon_count + 30,
n_param, aux_t_param, temp_param = sympy.symbols("n T' x")
from_base_case = lambda x: (t_param * (x + 10) - 10)
@dataclass
class MiniConwayTable:
conway: str
hexagon_count: str
vertex_count: str
edge_count: str
as_maybe_tex = lambda x: x if isinstance(x, int) or not x.has_free(t_param) else f"${sympy.latex(x)}$"
as_maybe_recipe_link = lambda x, recipe: x if recipe is None else link_polyhedronisme(x, recipe)
def display_mini_conway_table(
base_case_hexagons: int,
base_case_name: str,
recipes: dict[str, str] = {},
) -> Markdown:
headers = MiniConwayTable(
"Conway",
"$F_6$",
"V",
"E",
)
rows = [
MiniConwayTable(
conway=recipe,
hexagon_count=str(as_maybe_tex(polyhedron.face_count - 12)),
vertex_count=str(as_maybe_tex(polyhedron.vertex_count)),
edge_count=str(as_maybe_tex(polyhedron.edge_count)),
)
# base row list
for operator in ["", "dk", "c", "w", "tk", "g_T"]
# try lookup (a, b) tuple in parameter dict
for maybe_parameter in (goldberg_operators_to_parameters.get(operator),)
# combinatorially construct polyhedron from the base case and (maybe) the parameter
for polyhedron in (
(
hexagons_to_polyhedron(base_case_hexagons)
if operator == ""
else hexagons_to_polyhedron(
from_base_case(base_case_hexagons).expand().subs(
# if the lookup failed, leave the T parameter free
t_param,
loeschian_norm(*maybe_parameter)
if maybe_parameter is not None
else t_param
)
)
),
)
# pull the recipe from the `recipes` dict
for recipe in (
as_maybe_recipe_link(
f"${operator + base_case_name.split(' ')[-1]}$"
if operator == ""
else f"${base_case_name}$",
recipes.get(operator),
),
)
]
@dataclass
class GoldbergData:
parameter: tuple[int, int]
conway: str
parameter_link: str | None = None
conway_recipe: str | None = None
return Markdown(tabulate(
{
field: [name] + [getattr(item, field) for item in rows]
for field, name in asdict(headers).items()
},
headers="firstrow",
numalign="left",
))
```
@ -91,59 +137,79 @@ Yet more unconventional solutions are presented below.
Combinatorics of Goldberg-Coxeter Operators
-------------------------------------------
In the first post, we established that a solution figure *S* has feature counts
which are parametrized entirely by $F_6$:
$$
S = \begin{pmatrix} v \\ e \\ f \end{pmatrix}
= \begin{pmatrix}
2F_6 + 20 \\
3F_6 + 30 \\
F_6 + 12
\end{pmatrix}
= \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
+ \begin{pmatrix} 20 \\ 30 \\ 12 \end{pmatrix}
$$
In the last post, it was discovered that certain solutions cannot be created easily from seed polyhedra
in a polyhedron viewer.
This prompts the question of how to calculate the vertex, edge, and face counts
without acquiring them from the output of such a program.
Each of the simple GC operators (*c*, *dk*, and *w*) has a combinatoric matrix form
which can be applied to a vector of the vertex, edge, and face counts of a figure *S*.
Fortunatelly, each of the simple GC operators (*dk*, *c*, and *w*) has a combinatoric matrix form[^1].
$$
\begin{gather*}
S = \begin{pmatrix} v \\ e \\ f \end{pmatrix}
= \begin{pmatrix}
2F_6 + 20 \\
3F_6 + 30 \\
F_6 + 12
\end{pmatrix}
= \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
+ \begin{pmatrix} 20 \\ 30 \\ 12 \end{pmatrix} \\
\underset{
\text{Class I}
}{
c = \begin{pmatrix}
1 & 2 & 0 \\
0 & 4 & 0 \\
0 & 1 & 1
\end{pmatrix}
} \quad
\underset{
\text{Class II}
}{
dk = \begin{pmatrix}
0 & 2 & 0 \\
0 & 3 & 0 \\
1 & 0 & 1
\end{pmatrix}
} \quad
\underset{
\text{Class III}
}{
w = \begin{pmatrix}
1 & 4 & 0 \\
0 & 7 & 0 \\
0 & 2 & 1
\end{pmatrix}
}
\end{gather*}
\underset{
\text{Class I}
}{
c = \begin{pmatrix}
1 & 2 & 0 \\
0 & 4 & 0 \\
0 & 1 & 1
\end{pmatrix}
} \quad
\underset{
\text{Class II}
}{
dk = \begin{pmatrix}
0 & 2 & 0 \\
0 & 3 & 0 \\
1 & 0 & 1
\end{pmatrix}
} \quad
\underset{
\text{Class III}
}{
w = \begin{pmatrix}
1 & 4 & 0 \\
0 & 7 & 0 \\
0 & 2 & 1
\end{pmatrix}
}
$$
[^1]:
These matrices can be derived by closely observing the vertex, edge, and face counts of a figure before
and after applying the operator.
Gather the feature counts of the tetrahedron, dodecahedron, and icosahedron into a matrix.
$$
\begin{gather*}
f \begin{pmatrix} | & | & | \\ T & D & I \\ | & | & | \end{pmatrix}
= f \begin{pmatrix} 4 & 20 & 12 \\ 6 & 30 & 30 \\ 4 & 12 & 20 \end{pmatrix}
= \begin{pmatrix} | & | & | \\ fT & fD & fI \\ | & | & | \end{pmatrix} \\
f = \begin{pmatrix} | & | & | \\ fT & fD & fI \\ | & | & | \end{pmatrix}
\begin{pmatrix} 4 & 20 & 12 \\ 6 & 30 & 30 \\ 4 & 12 & 20 \end{pmatrix}^{-1}
\end{gather*}
$$
This matrix is invertible, and the feature counts for *fT*, *fD*, and *fI* can be acquired from a viewer
implementing the operator *f*.
These operators are labelled with the classes of Goldberg polyhedra they construct
when applied to the dodecahedron.
- *cD* = GC(2, 0)
- *dkD* = *tI* = GC(1, 1)
- *cD* = GC(2, 0)
- *wD* = GC(2, 1)
It's worth noting again that *dk* alternates between producing Class I and Class II solutions.
@ -156,83 +222,41 @@ Unlike it, it preserves solution class.
Powers of a matrix are more readily expressed when the matrix is diagonalized.
Diagonalizing each of these operators shows that they have something in common.
$$
\begin{align*}
c &= \begin{pmatrix}
1 & 2 & 0 \\
0 & 4 & 0 \\
0 & 1 & 1
\end{pmatrix}
= \textcolor{red}{
\begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
}
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 4
\end{pmatrix}
\textcolor{blue}{
\begin{pmatrix}
1 & -2/3 & 0 \\
1 & -1 & 1 \\
0 & 1/3 & 0
\end{pmatrix}
} \\
dk &= \begin{pmatrix}
0 & 2 & 0 \\
0 & 3 & 0 \\
1 & 0 & 1
\end{pmatrix}
= \textcolor{red}{
\begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
}
\begin{pmatrix}
0 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 3
\end{pmatrix}
\textcolor{blue}{
\begin{pmatrix}
1 & -2/3 & 0 \\
1 & -1 & 1 \\
0 & 1/3 & 0
\end{pmatrix}
}
\\
w &= \begin{pmatrix}
1 & 4 & 0 \\
0 & 7 & 0 \\
0 & 2 & 1
\end{pmatrix}
= \textcolor{red}{
\begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
}
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 7
\end{pmatrix}
\textcolor{blue}{
\begin{pmatrix}
1 & -2/3 & 0 \\
1 & -1 & 1 \\
0 & 1/3 & 0
\end{pmatrix}
}
\end{align*}
$$
```{python}
# diagonalizing dk gives an eigenspace which shows the 3V = 2E condition
# and Euler characteristic more clearly
eigenspace, _ = goldberg_operators["dk"].diagonalize()
def show_diagonalized(operator: GoldbergOperator):
assert operator != "g_T"
matrix = goldberg_operators[operator]
diag = eigenspace.inv() @ matrix @ eigenspace
return f"""{
sympy.latex(matrix)
} = \\textcolor{{red}}{{{
sympy.latex(eigenspace)
}}}{
sympy.latex(diag)
}\\textcolor{{blue}}{{{
sympy.latex(eigenspace.inv(), fold_short_frac=True)
}}}"""
Markdown(f"""
$$
\\begin{{align*}}
dk &= {show_diagonalized("dk")} \\\\
c &= {show_diagonalized("c")} \\\\
w &= {show_diagonalized("w")}
\\end{{align*}}
$$
""".replace(
"\\left[\\begin{matrix}", "\\begin{pmatrix}"
).replace(
"\\end{matrix}\\right]", "\\end{pmatrix}"
)
)
```
All of these operators share the same eigenvectors, which can be seen
in the columns of the left outer matrix and rows of the right outer one.
@ -243,7 +267,7 @@ Some of these eigenvectors have special interpretations:
- The left eigenvector (1, -1, 1) (right matrix, middle row) always has eigenvalue 1.
- This means that the operation does not change the Euler characteristic.
- The left eigenvector (3, -2, 0) (right matrix, top row), when applied to general polyhedra
- The left eigenvector (3, -2, 0) (right matrix, top row), when applied to general polyhedra,
corresponds to the edges and vertices added by the operation:
- In *dk*, this vector has eigenvalue 0, forcing $3V = 2E$, i.e., all vertices to have degree 3.
- In *c* and *w*, this vector has eigenvalue 1. These operators only add degree-3 vertices.
@ -265,10 +289,10 @@ $$
Call this number $T = \|a + bu\| = a^2 + ab + b^2$.
We know that integers of this form are never congruent to 2 (mod 3).
Conveniently, this matches with the upper-left eigenvalue.
Assuming for the sake of argument that this is true, it implies something interesting:
**the GC operators produced from *T* are (combinatorially) closed under composition**.
This captures all powers of a given *T*, as well as products between it and other possible *T*s.
However, this combinatorial view misses some of the picture, since some feature counts
can be shared between two different classes at once.
This comes down to the existence of chiral pairs.
@ -282,53 +306,21 @@ This doesn't affect hexagon counts, so it means we can characterize the possible
$$
\begin{align*}
g_T S &= \begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
\begin{pmatrix}
x & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & T
\end{pmatrix}
\begin{pmatrix}
1 & -{2 \over 3} & 0 \\
1 & -1 & 1 \\
0 & {1 \over 3} & 0
\end{pmatrix}
\begin{pmatrix} v \\ e \\ f \end{pmatrix} \\[8pt]
&=
\begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
\begin{pmatrix}
x & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & T
\end{pmatrix}
\begin{pmatrix}
v - {2 \over 3} e = 0 \\
v - e + f = 2 \\
{1 \over 3} e = F_6 + 10
\end{pmatrix} \\[8pt]
&=
\begin{pmatrix}
-1 & 0 & 2 \\
0 & 0 & 3 \\
1 & 1 & 1
\end{pmatrix}
\begin{pmatrix} 0 \\ 2 \\ T (F_6 + 10) \end{pmatrix} \\
&=
\begin{pmatrix} T(2F_6 + 20) \\ T(3F_6 + 30) \\ T(F_6 + 10) + 2 \end{pmatrix} \\[8pt]
g_T S &= g_T \left(
\begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
+ \begin{pmatrix} 20 \\ 30 \\ 10 \end{pmatrix}
+ \begin{pmatrix} 0 \\ 0 \\ 2 \end{pmatrix}
\right) \\
&= T \begin{pmatrix} 2 \\ 3 \\ 1 \end{pmatrix} F_6
+ T \begin{pmatrix} 20 \\ 30 \\ 10 \end{pmatrix}
+ \begin{pmatrix} 0 \\ 0 \\ 2 \end{pmatrix} \\
&= \begin{pmatrix} T(2F_6 + 20) \\ T(3F_6 + 30) \\ T(F_6 + 10) + 2 \end{pmatrix} \\[8pt]
F'_6 &= T(F_6 + 10) - 10
\end{align*}
$$
This demonstrates two things: the initial $F_6$ count from the choice of seed polygon *S* matters,
and the possible values of *T* can be used to grow this sequence
and we can use valid values of *T* to produce a sequence of solutions.
Searching for Other Seeds
@ -399,72 +391,13 @@ It inherits the dihedral symmetry of degree 3 from the vertices of the dodecahed
](./truncated gyroelongated bipyramid pole.png)
:::
::: {.column}
```{python}
#| echo: false
t_param = sympy.symbols("T")
norm = lambda a, b: a**2 + a*b + b**2
@dataclass
class GCOperator:
name: str
parameter: int | sympy.Symbol
gc_operators = [
GCOperator("dk", norm(1, 1)),
GCOperator("c", norm(2, 0)),
GCOperator("w", norm(2, 1)),
GCOperator("tk", norm(3, 0)),
GCOperator("g_T", t_param),
]
def polyhedronisme(recipe: str) -> str:
return f"https://levskaya.github.io/polyhedronisme/?recipe={recipe}"
as_maybe_tex = lambda x: x if isinstance(x, int) or not x.has_free(t_param) else f"${sympy.latex(x)}$"
as_maybe_recipe_link = lambda x, recipe: f"[{x}]({polyhedronisme(recipe)})" if recipe is not None else x
def mini_conway_table(
base_case_hexagons: int,
base_case_name: str,
recipes: dict[str, str] = {},
) -> list[tuple[str, PolyData]]:
return [
(
as_maybe_recipe_link(f"${base_case_name}$", recipes.get("")),
PolyData.from_hexagons(base_case_hexagons),
)
] + [
(
as_maybe_recipe_link(
f"${operator.name + base_case_name.split(' ')[-1]}$",
recipes.get(operator.name),
),
PolyData.from_hexagons((
t_param * (base_case_hexagons + 10) - 10
).expand().subs(t_param, operator.parameter)),
)
for operator in gc_operators
]
def display_mini_conway_table(
base_case_hexagons: int,
base_case_name: str,
recipes: dict[str, str] = {},
) -> Markdown:
return Markdown(tabulate(
[[
conway,
as_maybe_tex(polyhedron.hexagon_count),
as_maybe_tex(polyhedron.vertex_count),
as_maybe_tex(polyhedron.edge_count),
] for conway, polyhedron in mini_conway_table(base_case_hexagons, base_case_name, recipes)],
headers=["Conway", "$F_6$", "V", "E"],
numalign="left",
))
#| classes: plain
display_mini_conway_table(6, "F")
```
:::
::::
@ -497,7 +430,7 @@ The pentagons gather in groups of 4 and are separated by three bands of hexagons
The symmetry inherited by this figure is also dihedral of degree 3, but centered about a hexagon,
rather than (a complex of) pentagons.
:::: {layout-ncol="2" layout-valign="center"}
::: {layout-ncol="2" layout-valign="center"}
[
![
One-third of the figure, showing a group of four pentagons.<br>
@ -506,11 +439,11 @@ The symmetry inherited by this figure is also dihedral of degree 3, but centered
](./frustum_third.png){target="_blank_"}
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(8, "F")
```
::::
:::
#### Others
@ -567,18 +500,18 @@ This is a symmetry beyond that of the icosahedron, but exists due to the symmetr
](./polyhedronisme-K300t6dA6.png)
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(
2,
"t_6dA_6 = T_6",
recipes = {
"": "K300t6dA6",
"dk": "dkK300t6dA6",
"c": "K300cK30t6dA6",
"w": "K300wK30t6dA6",
"tk": "K300tkK30t6dA6"
}
2,
"t_6dA_6 = T_6",
recipes = {
"": "K300t6dA6",
"dk": "dkK300t6dA6",
"c": "K300cK30t6dA6",
"w": "K300wK30t6dA6",
"tk": "K300tkK30t6dA6",
},
)
```
::::
@ -608,11 +541,13 @@ The resultant figure has dihedral symmetry of degree 5.
](./petrial expanded dodecahedron.png)
:::
::: {.column}
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(5, "D_\\pi")
```
:::
::::
Interestingly, this is also the first solution polyhedron with an odd number of faces.
@ -632,43 +567,47 @@ Solution polyhedra can be found by examining the pentagonal ($t_5 g Y_5$) and he
The former has dihedral symmetry of degree 5 and the latter has that of degree 6.
:::: {layout-ncol="2" layout-valign="center"}
::: {.column .slim-column}
![
Base case 1: truncated pentagonal gyro-pyramid
](./polyhedronisme-K300t5K30gY5.png){.column .slim-column}
:::
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(
10,
"t_5gY_5 = G_5",
recipes = {
"": "K300t5K30gY5",
"dk": "dkK300t5K30gY5",
"c": "K300dudt5K30gY5",
"w": "K300wK30t5K30gY5",
"tk": "tkK300t5K30gY5",
},
10,
"t_5gY_5 = G_5",
recipes = {
"": "K300t5K30gY5",
"dk": "dkK300t5K30gY5",
"c": "K300dudt5K30gY5",
"w": "K300wK30t5K30gY5",
"tk": "tkK300t5K30gY5",
},
)
```
::: {.column .slim-column}
![
Base case 2: truncated hexagonal gyro-pyramid
](./polyhedronisme-K300t6K30gY6.png){.column .slim-column}
](./polyhedronisme-K300t6K30gY6.png)
:::
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(
14,
"t_6gY_6 = G_6",
recipes = {
"": "K300t6K30gY6",
"dk": "dkK300t6K30gY6",
"c": "K300dudK40t6gY6",
"w": "K300wK30t6K30gY6",
"tk": "tkK300t6K30gY6",
},
14,
"t_6gY_6 = G_6",
recipes = {
"": "K300t6K30gY6",
"dk": "dkK300t6K30gY6",
"c": "K300dudK40t6gY6",
"w": "K300wK30t6K30gY6",
"tk": "tkK300t6K30gY6",
},
)
```
::::
@ -718,9 +657,13 @@ In fact, the graph of the whirl operation on the surface of a cube
:::: {#fig-tatami-polyhedron}
::: {layout="[[-1,2,-1,2,-1]]"}
<a title="Tomruen, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Conway_wC.png"><img width="384" alt="Conway wC" src="https://upload.wikimedia.org/wikipedia/commons/f/f4/Conway_wC.png"></a>
<a title="Tomruen, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Conway_wC.png">
<img width="384" alt="Conway wC" src="https://upload.wikimedia.org/wikipedia/commons/f/f4/Conway_wC.png">
</a>
<a title="See page for author, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Tearoom_layout.svg"><img style="background-color: white !important; padding: 5px" width="384" alt="Tearoom layout" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Tearoom_layout.svg/256px-Tearoom_layout.svg.png"></a>
<a title="See page for author, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons" href="https://commons.wikimedia.org/wiki/File:Tearoom_layout.svg">
<img style="background-color: white !important; padding: 5px" width="384" alt="Tearoom layout" src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Tearoom_layout.svg/256px-Tearoom_layout.svg.png">
</a>
:::
Images were retrieved from Wikimedia and belong to their respective owners.
@ -739,14 +682,14 @@ Next to it is an equivalent graph with a regular hexagon as an outer face.
As a 3D figure, it has only three hexagons and degree-3 dihedral symmetry, another odd number.
:::: {layout-ncol="2" layout-valign="center"}
::: {.column .slim-column}
::: {.column .slim-column .text-center}
![](./tatami_graph.png){.image-wide}
![](./regularized_tatami_graph.png){.image-wide}
:::
```{python}
#| echo: false
#| classes: plain
display_mini_conway_table(3, "M")
```
@ -791,10 +734,11 @@ Final Tabulation
The solutions examined have been collected in the table below.
```{python}
#| echo: false
#| classes: plain
#| tbl-cap: "T, T' are members of the sequence 1, 3, 4, 7, 9, 12, 13, 16, 19, 21... ([OEIS A003136](http://oeis.org/A003136))\
#| <br>\\\\*: This is the result of a GC operator applied to $2T - 14$, which requires *T* > 7"
TFilter: TypeAlias = Callable[[int], bool] | None
n_param, t_param, aux_t_param, temp_param = sympy.symbols("n T T' x")
@dataclass
class TotalHexagonRow:
@ -803,8 +747,6 @@ class TotalHexagonRow:
f6_expression: sympy.Expr
t_filter: TFilter = None
from_base_case = lambda x: (t_param * (x + 10) - 10)
antitruncation = TotalHexagonRow(
symmetry_group="Tetrahedral",
class_name="Tetrahedral Goldberg Antitruncations",
@ -880,18 +822,10 @@ full_tabulation_rows = [
),
]
def loeschian():
"""
Loeschian numbers -- those of the form a^2 + ab + b^2
See https://oeis.org/A003136
"""
for a in itertools.count(1):
for b in range(a + 1):
yield a*a + a*b + b*b
def get_example_counts(expr: sympy.Expr, amount: int, t_filter: TFilter = None):
t_params = list(itertools.islice(loeschian(), 2*amount))
"""Build values from the expression in terms of the number of hexagons"""
t_params = list(itertools.islice(loeschian_numbers(), 2*amount))
return [
count
@ -931,18 +865,20 @@ Markdown(tabulate(
))
```
T, T' are members of the sequence 1, 3, 4, 7, 9, 12, 13, 16, 19, 21... ([OEIS A003136](http://oeis.org/A003136))
\*: This is the result of a GC operator applied to $2T - 14$, which requires *T* > 7
Sorting the entries in this table, we get the following possible hexagon counts:
Here are a few hexagon counts from the table, sorted in ascending order:
```{python}
#| echo: false
Markdown(", ".join(list(map(str, sorted(itertools.chain(*[
get_example_counts(row.f6_expression, 10, row.t_filter) for row in full_tabulation_rows
]))))[:15]))
Markdown(
", ".join([
str(i)
for i in group_dict(
itertools.chain(*[
get_example_counts(row.f6_expression, 10, row.t_filter)
for row in full_tabulation_rows
])
).keys()
][:20]) + "..."
)
```
However, keep in mind that this list is *not* exhaustive.

View File

@ -0,0 +1,25 @@
# freeze computational output
freeze: auto
# Enable banner style title blocks
title-block-banner: true
execute:
echo: false
# Get rid of the figure label
crossref:
fig-title: ""
fig-labels: "&#32;"
tbl-title: ""
tbl-labels: "&#32;"
title-delim: ""
custom:
- key: fig
kind: float
reference-prefix: Figure
space-before-numbering: false
- key: tbl
kind: float
reference-prefix: Table
space-before-numbering: false