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.
%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