cp's OEIS Frontend

This is a front-end for the Online Encyclopedia of Integer Sequences, made by Christian Perfect. The idea is to provide OEIS entries in non-ancient HTML, and then to think about how they're presented visually. The source code is on GitHub.

A303331 a(n) is the minimum size of a square integer grid allowing all triples of n points to form triangles of different areas.

This page as a plain text file.
%I A303331 #43 May 22 2025 10:21:47
%S A303331 0,1,1,2,4,6,9,11,15,19
%N A303331 a(n) is the minimum size of a square integer grid allowing all triples of n points to form triangles of different areas.
%C A303331 Place n points on integer coordinates of a square grid of dimension L x L, so that no 3 points are collinear and the areas of the triangles formed by the binomial(n,3) possible triples are all different. a(n) is the minimum L for which this can be achieved. (Note that there are (L+1)^2 lattice points.)
%C A303331 The fact that all triangle areas are multiples of 1/2 and the maximum area supported by the grid is L^2/2 provides us with a lower bound for a(n).
%C A303331 The problem can be considered a 2-dimensional extension of a Golomb ruler and scales to higher dimensions. In general, consider k points on integer coordinates of a D-dimensional hypercube, forming binomial(k,D+1) D-simplices of which the volumes are all different. For D = 1, we recognize the Golomb ruler; for D = 2, we have the problem defined above.
%C A303331 Just like for Costas arrays (another 2-D extension of Golomb rulers), no 2 displacement vectors can be identical, as the diagonal of a parallelogram cuts the shape in triangles of identical area.
%C A303331 a(11) <= 24, a(12) <= 29. - _Hugo Pfoertner_, Nov 05 2018
%H A303331 IBM Research, <a href="https://www.research.ibm.com/haifa/ponderthis/challenges/October2018.html">Ponder This Challenge October 2018</a>. Similar problem for rectangular grids.
%F A303331 a(n+1) >= a(n) (trivial).
%F A303331 a(n) >= sqrt(n*(n-1)*(n-2)/6) for n >= 2 (proven lower bound).
%e A303331 For n = 5, a solution satisfying unequal triangle areas is {(0,4),(1,1),(3,0),(3,3),(4,3)}, which can be verified by considering the binomial(5,3) = 10 possible triangles by selecting vertices from this set. Each coordinate is contained in the range [0..4]. No smaller solution is possible without creating areas that are no longer unique, hence a(5) = 4.
%e A303331 From _Jon E. Schoenfield_, Apr 30 2018: (Start)
%e A303331 Illustration of the above solution:
%e A303331                         vertices   area
%e A303331   4   1  .  .  .  .     --------   ----
%e A303331                           1 2 3     2.5
%e A303331   3   .  .  .  4  5       1 2 4     4.0
%e A303331                           1 2 5     5.5
%e A303331   2   .  .  .  .  .       1 3 4     4.5
%e A303331                           1 3 5     6.5
%e A303331   1   .  2  .  .  .       1 4 5     0.5
%e A303331                           2 3 4     3.0
%e A303331   0   .  .  .  3  .       2 3 5     3.5
%e A303331   y                       2 4 5     1.0
%e A303331     x 0  1  2  3  4       3 4 5     1.5
%e A303331 (End)
%o A303331 (Python)
%o A303331 def addNewAreas(plist, used_areas):
%o A303331     # Attempt to add last point in plist. 'used_areas' contains all (areas*2)
%o A303331     # between preplaced points and is updated
%o A303331     m=len(plist)
%o A303331     for i in range(m-2):
%o A303331         for j in range(i+1,m-1):
%o A303331             k=m-1
%o A303331             p,q,r=plist[i],plist[j],plist[k]
%o A303331             # Area = s/2 - using s enables us to use integers
%o A303331             s=(p[0]*q[1]-p[1]*q[0]) + (q[0]*r[1]-q[1]*r[0]) + (r[0]*p[1]-r[1]*p[0])
%o A303331             if s<0:
%o A303331                 s=-s
%o A303331             if s in used_areas:
%o A303331                 return False # Area not unique
%o A303331             else:
%o A303331                 used_areas[s]=True
%o A303331     return True
%o A303331 def solveRecursively(n, L, plist, used_areas):
%o A303331     m=len(plist)
%o A303331     if m==n:
%o A303331         #print plist (uncomment to show solution)
%o A303331         return True
%o A303331     newlist=plist+[None]
%o A303331     if m>0:
%o A303331         startidx=(L+1)*plist[m-1][0] + plist[m-1][1] + 1
%o A303331     else:
%o A303331         startidx=0
%o A303331     for idx in range(startidx, (L+1)**2):
%o A303331             newlist[m]=( idx/(L+1) , idx%(L+1) )
%o A303331             newareas=dict(used_areas)
%o A303331             if addNewAreas(newlist, newareas):
%o A303331                 if solveRecursively(n, L, newlist, newareas):
%o A303331                     return True
%o A303331     return False
%o A303331 def A303331(n):
%o A303331     L=0
%o A303331     while not solveRecursively(n, L, [], {0:True}):
%o A303331         L+=1
%o A303331     return L
%o A303331 def A303331_list(N):
%o A303331     return [A303331(n) for n in range(1,N+1)]
%o A303331 # _Bert Dobbelaere_, May 01 2018
%Y A303331 For optimal Golomb rulers, see A003022.
%Y A303331 Cf. A193838, A193839, A271490, A322740.
%K A303331 nonn,hard,more
%O A303331 1,4
%A A303331 _Bert Dobbelaere_, Apr 30 2018