Schläfli Konveks Düzenli Politop Tercüman


15

Arka fon

SCHLAFLI Sembol normal polytopes ve Tessellations tanımlayan formu {p, q, r, ...} bir gösterim olup.

Schläfli sembolü, {p} şeklinde p-taraflı düzenli çokgen ile başlayan özyinelemeli bir açıklamadır. Örneğin, {3} eşkenar üçgen, {4} bir kare vb.

Her tepe noktasında q düzenli p-taraflı çokgen yüze sahip normal bir çokyüzlü {p, q} ile temsil edilir. Örneğin, küpün her tepe noktasında 3 kare vardır ve {4,3} ile temsil edilir.

Her kenarın çevresinde r {p, q} düzenli çokyüzlü hücreleri olan normal bir 4 boyutlu politop, {p, q, r} ile temsil edilir. Örneğin, bir tesserat, {4,3,3}, bir kenar etrafında 3 küp ({4,3}) içerir.

Genel olarak düzenli bir politop {p, q, r, ..., y, z} her tepe noktasında z {p, q, r, ..., y} yönlere sahiptir, burada bir tepe bir çokyüzlünün tepe noktasıdır, 4-politopta bir kenar, 5-politopta bir yüz, 6-politopta bir hücre ve n-politopta bir (n-3)-yüzü.

Düzenli bir politopun düzenli bir tepe şekli vardır. Düzenli bir politopun {p, q, r, ... y, z} tepe şekli {q, r, ... y, z} 'dır.

Düzenli politoplar, beşgen köşeleriyle temsil edilen ancak dönüşümlü olarak bağlanan, {5/2} sembollü, pentagram gibi yıldız çokgen elemanlara sahip olabilir.

Schläfli sembolü, yapının açı kusuruna bağlı olarak, sınırlı bir dışbükey polihedronu, Euclid boşluğunun sonsuz bir mozaiklemesini ya da hiperbolik boşluğun sonsuz bir mozaiklenmesini temsil edebilir. Pozitif bir açı hatası, köşe figürünün daha yüksek bir boyuta katlanmasını ve bir politop olarak kendi içine geri dönmesini sağlar. Sıfır açılı bir kusur, fasetlerle aynı boyuttaki alanı kaplar. Negatif bir açı hatası sıradan uzayda bulunamaz, hiperbolik uzayda yapılabilir.

yarışma

Amacınız, bir Schläfli Sembolü geçtiğinde dışbükey bir politopun tam bir açıklamasını döndürecek bir program oluşturmaktır. Bu sadece Schläfli Sembollerinin bir alt kümesidir, ancak en basit olanıdır, diğer olasılıklar olmasa bile bu çok zor bir görev olacağına ve politopların mozaiklerin başlangıç ​​noktası olduğuna inanıyorum. Bu sorunun kuralları, bu sonucun bir API olduğu fikri ile tasarlanmıştır ve internette böyle bir program bulamadım.

Programınız aşağıdakilerin tümünü gerçekleştirmelidir.

  • Program sonlu boyutlu düzenli dışbükey politop üretebilmelidir. 2 boyutta n-gons içerir. 3 boyutta bunlar platonik katılar, 4 boyutta tesserat, ortopleks ve birkaçını içerir)
  • Program ya (a) başlangıç ​​noktasına bir nokta koymalı veya (b) tüm noktaların ortalamasının başlangıç ​​noktası olmasını sağlamalıdır. Oryantasyon önemli değil. Genel boyut önemli değil.
  • Program, 4 boyutlu bir nesne için programın köşeleri, kenarları, yüzleri ve polihedrayı döndüreceği / yazacağı anlamına gelen eksiksiz bir açıklama sağlamalıdır . Bunların raporlanma sırası önemli değil. Polihedra için, nesneyi oluşturmak için ihtiyacınız olan bilgiler budur.

Elleçlemeye gerek yok :

  • tesselations
  • Hiperbolik Geometri
  • Kesirli Schläfli sembolleri (dışbükey olmayan)
  • Gömülü Schläfli Sembolleri (düzgün olmayan eğimler)

Bunlardan herhangi birini yapmanız istenirse bir hata döndürebilirsiniz.

Örnek: Cube

Giriş:

4 3

Çıktı:

Vertices
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1    

Edges (These are the vertex pairs that make up the edges)
0 1
0 2
0 4
1 3
1 5
2 3
2 6
3 7
4 5
4 6
5 7
6 7

Faces (These are the squares which are the faces of the cube)
0 1 3 2
0 1 5 4
0 2 6 4
6 7 5 4
7 6 2 3
7 5 1 3

Bu algoritmanın nasıl çalışabileceği ve çok özyinelemeli olabileceği konusunda bazı fikirlerim vardı, ancak şimdiye kadar başarısız oldum, ancak ilham arıyorsanız, https://en.wikipedia.org/wiki/Euler_characteristic

Köşeleri, kenarları ve yüzleri hesaplamaya bir örnek olarak, {4,3} olan küpü düşünün. İlk 4'e bakarsak, 4 kenarı ve 4 köşesi vardır. Şimdi sonraki 3'e bakarsak, her köşede 3 kenarın birleştiğini biliyoruz, her kenar 2 köşeye bağlanıyor, her kenarda 2 yüz birleşiyor, her yüz 4 köşeye bağlanıyor (kare kenarlar nedeniyle) ve Euler Karakteristik formülü.

E = 3/2 V

E = 4/2 F

V - E + F = 2

Bu da E = 12, V = 8, F = 6 verir.

puanlama

Konuyla ilgili soruyu korumak için, bu kod Golf Golf için revize edildi. En kısa kod kazanır.

Bu soru için bir github oluşturuldu


1
Googling, 4 boyutun ötesine uzanan sadece 3 normal politop ailesi olduğunu gösterir: küp, oktahedron ve tetrahedrona benzer. Bu aileler için yazmak ve geri kalanını (iki 3B politoplar, üç 4d politoplar ve 2d politopların sonsuz ailesi) yazmak daha kolay olacak gibi görünüyor. Bu geçerli bir cevap olur mu? Spesifikasyon kapsamının ötesinde topolojik grafikler oluşturmak için özyinelemeli bir algoritma yazmak mümkün olabilir, ancak spesifikasyonda bile bu yaklaşıma sahip katil koordinatları hesaplıyor.
Level River St

Gerçek köşeleri, yalnızca eşkenar olduklarını bilerek nasıl biliyoruz?
Matthew Roh

@SIGSEGV belirtilen tek gereklilik, başlangıç ​​noktasının merkeze veya noktalardan birine karşılık gelmesidir. Bu, şekli istediğiniz gibi döndürmek için bolca alan sağlar. tr.wikipedia.org/wiki/Simplex hipertetrahedronların koordinatlarını hesaplamak için bir algoritma verir (belki de icosahedron ve 4d analoga genişletilebilir, ancak bunu yapmak benim için çok fazla, bu yüzden sorum.) Hiperküpler güzel tamsayı koordinatları (ve hipertetrahedronlar da aslında, ancak genellikle sadece düzensiz şeklin kendisinden daha fazla boyutta.)
Level River St

@LevelRiverSt, evet çünkü varolan tek düzenli politoplar önerilerinizde ele alınacaktır, o zaman evet onları kodlayabilirsiniz.
Tony Ruth

Bu soruya kapanış oyu verdim çünkü ilk geçerli cevabın kazandığı batıdaki en hızlı silah tarzı bir meydan okuma. Bu genellikle geçerli bir kazanma kriteri olarak kabul edilmez. Bunun ne kadar uzun süredir açık olduğunu bilmiyorum, kapatılmış olmalı.
Post Rock Garf Hunter

Yanıtlar:


2

piton

İşte özel durumları olmayan özyinelemeli bir program. Boş satırları ve yorumları göz ardı ederek , sonunda Euler formülünün ücretsiz bir kontrolünü içeren 100 90 satırdan az . Geçici matematik fonksiyonlarının (muhtemelen bir kütüphane tarafından sağlanabilir) ve i / o tanımları hariç tutulduğunda, politop üretimi 50 satırlık koddur. Ve hatta yıldız politoplarını bile yapar!

Çıktı politopu kenar uzunluğu 1'e sahip olacak ve aşağıdaki anlamda kanonik pozisyonda ve yönde olacaktır:

  • ilk köşe başlangıç ​​noktasıdır,
  • ilk kenar + x ekseni boyunca uzanır,
  • ilk yüz xy düzleminin + y yarım düzlemindedir,
  • ilk 3 hücre xyz boşluğunun + z yarı boşluğundadır, vb.

Bunun dışında, çıktı listeleri belirli bir sırada değildir. (Aslında, bu tamamen doğru değil - aslında ilk öğeden başlayıp dışa doğru genişlemek için kabaca çıkacaklar.)

Geçersiz schlafli sembolü için kontrol yok; Eğer bir tane verirseniz, program muhtemelen raylardan çıkar (sonsuz döngü, yığın taşması veya sadece çöp).

{4,4} veya {3,6} veya {6,3} gibi sonsuz bir düzlemsel döşeme talep ederseniz, program aslında döşemeyi oluşturmaya başlar, ancak alan bitene kadar sonsuza kadar devam eder, asla ne bitirme ne de üretim üretme. Bunu düzeltmek çok zor olmaz (sadece oluşturulacak öğe sayısı için bir sınır koyun; sonuç, kabaca en geniş ilk arama sırasında üretildiğinden, sonuç sonsuz resmin oldukça tutarlı bir bölgesi olmalıdır).

Kod

#!/usr/bin/python3
# (works with python2 or python3)

#
# schlafli_interpreter.py
# Author: Don Hatch
# For: /codegolf/114280/schl%C3%A4fli-convex-regular-polytope-interpreter
#
# Print the vertex coords and per-element (edges, faces, etc.) vertex index
# lists of a regular polytope, given by its schlafli symbol {p,q,r,...}.
# The output polytope will have edge length 1 and will be in canonical position
# and orientation, in the following sense:
#  - the first vertex is the origin,
#  - the first edge lies along the +x axis,
#  - the first face is in the +y half-plane of the xy plane,
#  - the first 3-cell is in the +z half-space of the xyz space, etc.
# Other than that, the output lists are in no particular order.
#

import sys
from math import *

# vector minus vector.
def vmv(a,b): return [x-y for x,y in zip(a,b)]
# matrix minus matrix.
def mmm(m0,m1): return [vmv(row0,row1) for row0,row1 in zip(m0,m1)]
# scalar times vector.
def sxv(s,v): return [s*x for x in v]
# scalar times matrix.
def sxm(s,m): return [sxv(s,row) for row in m]
# vector dot product.
def dot(a,b): return sum(x*y for x,y in zip(a,b))
# matrix outer product of two vectors; that is, if a,b are column vectors: a*b^T
def outer(a,b): return [sxv(x,b) for x in a]
# vector length squared.
def length2(v): return dot(v,v)
# distance between two vectors, squared.
def dist2(a,b): return length2(vmv(a,b))
# matrix times vector, homogeneous (i.e. input vector ends with an implicit 1).
def mxvhomo(m,v): return [dot(row,v+[1]) for row in m]
# Pad a square matrix (rotation/reflection) with an extra column of 0's on the
# right (translation).
def makehomo(m): return [row+[0] for row in m]
# Expand dimensionality of homogeneous transform matrix by 1.
def expandhomo(m): return ([row[:-1]+[0,row[-1]] for row in m]
                         + [[0]*len(m)+[1,0]])
# identity matrix
def identity(dim): return [[(1 if i==j else 0) for j in range(dim)]
                                               for i in range(dim)]
# https://en.wikipedia.org/wiki/Householder_transformation. v must be unit.
# Not homogeneous (makehomo the result if you want that).
def householderReflection(v): return mmm(identity(len(v)), sxm(2, outer(v,v)))

def sinAndCosHalfDihedralAngle(schlafli):
  # note, cos(pi/q)**2 generally has a nicer expression with no trig and often
  # no radicals, see http://www.maths.manchester.ac.uk/~cds/articles/trig.pdf
  ss = 0
  for q in schlafli: ss = cos(pi/q)**2 / (1 - ss)
  if abs(1-ss) < 1e-9: ss = 1  # prevent glitch in planar tiling cases
  return sqrt(ss), sqrt(1 - ss)

# Calculate a set of generators of the symmetry group of a {p,q,r,...} with
# edge length 1.
# Each generator is a dim x (dim+1) matrix where the square part is the initial
# orthogonal rotation/reflection and the final column is the final translation.
def calcSymmetryGenerators(schlafli):
  dim = len(schlafli) + 1
  if dim == 1: return [[[-1,1]]]  # one generator: reflect about x=.5
  facetGenerators = calcSymmetryGenerators(schlafli[:-1])
  # Start with facet generators, expanding each homogeneous matrix to full
  # dimensionality (i.e. from its previous size dim-1 x dim to dim x dim+1).
  generators = [expandhomo(gen) for gen in facetGenerators]
  # Final generator will reflect the first facet across the hyperplane
  # spanned by the first ridge and the entire polytope's center,
  # taking the first facet to a second facet also containing that ridge.
  # v = unit vector normal to that bisecting hyperplane
  #   = [0,...,0,-sin(dihedralAngle/2),cos(dihedralAngle/2)]
  s,c = sinAndCosHalfDihedralAngle(schlafli)
  v = [0]*(dim-2) + [-s,c]
  generators.append(makehomo(householderReflection(v)))
  return generators

# Key for comparing coords with roundoff error.  Makes sure the formatted
# numbers are not very close to 0, to avoid them coming out as "-0" or "1e-16".
# This isn't reliable in general, but it suffices for this application
# (except for very large {p}, no doubt).
def vert2key(vert): return ' '.join(['%.9g'%(x+.123) for x in vert])

# Returns a pair verts,edgesEtc where edgesEtc is [edges,faces,...]
def regular_polytope(schlafli):
  dim = len(schlafli) + 1
  if dim == 1: return [[0],[1]],[]

  gens = calcSymmetryGenerators(schlafli)

  facetVerts,facetEdgesEtc = regular_polytope(schlafli[:-1])

  # First get all the verts, and make a multiplication table.
  # Start with the verts of the first facet (padded to full dimensionality),
  # so indices will match up.
  verts = [facetVert+[0] for facetVert in facetVerts]
  vert2index = dict([[vert2key(vert),i] for i,vert in enumerate(verts)])
  multiplicationTable = []
  iVert = 0
  while iVert < len(verts):  # while verts is growing
    multiplicationTable.append([None] * len(gens))
    for iGen in range(len(gens)):
      newVert = mxvhomo(gens[iGen], verts[iVert])
      newVertKey = vert2key(newVert)
      if newVertKey not in vert2index:
        vert2index[newVertKey] = len(verts)
        verts.append(newVert)
      multiplicationTable[iVert][iGen] = vert2index[newVertKey]
    iVert += 1

  # The higher-level elements of each dimension are found by transforming
  # the facet's elements of that dimension.  Start by augmenting facetEdgesEtc
  # by adding one more list representing the entire facet.
  facetEdgesEtc.append([tuple(range(len(facetVerts)))])
  edgesEtc = []
  for facetElementsOfSomeDimension in facetEdgesEtc:
    elts = facetElementsOfSomeDimension[:]
    elt2index = dict([[elt,i] for i,elt in enumerate(elts)])
    iElt = 0
    while iElt < len(elts):  # while elts is growing
      for iGen in range(len(gens)):
        newElt = tuple(sorted([multiplicationTable[iVert][iGen]
                               for iVert in elts[iElt]]))
        if newElt not in elt2index:
          elt2index[newElt] = len(elts)
          elts.append(newElt)
      iElt += 1
    edgesEtc.append(elts)

  return verts,edgesEtc

# So input numbers can be like any of "8", "2.5", "7/3"
def parseNumberOrFraction(s):
  tokens = s.split('/')
  return float(tokens[0])/float(tokens[1]) if len(tokens)==2 else float(s)

if sys.stdin.isatty():
  sys.stderr.write("Enter schlafli symbol (space-separated numbers or fractions): ")
  sys.stderr.flush()
schlafli = [parseNumberOrFraction(token) for token in sys.stdin.readline().split()]
verts,edgesEtc = regular_polytope(schlafli)

# Hacky polishing of any integers or half-integers give or take rounding error.
def fudge(x): return round(2*x)/2 if abs(2*x-round(2*x))<1e-9 else x

print(repr(len(verts))+' Vertices:')
for v in verts: print(' '.join([repr(fudge(x)) for x in v]))
for eltDim in range(1,len(edgesEtc)+1):
  print("")
  elts = edgesEtc[eltDim-1]
  print(repr(len(elts))+' '+('Edges' if eltDim==1
                        else 'Faces' if eltDim==2
                        else repr(eltDim)+'-cells')+" ("+repr(len(elts[0]))+" vertices each):")
  for elt in elts: print(' '.join([repr(i) for i in elt]))

# Assert the generalization of Euler's formula: N0-N1+N2-... = 1+(-1)**(dim-1).
N = [len(elts) for elts in [verts]+edgesEtc]
eulerCharacteristic = sum((-1)**i * N[i] for i in range(len(N)))
print("Euler characteristic: "+repr(eulerCharacteristic))
if 2.5 not in schlafli: assert eulerCharacteristic == 1 + (-1)**len(schlafli)

Bazı durumlarda denemek

Giriş ( küp ):

4 3

Çıktı:

8 Vertices:
0.0 0.0 0.0
1.0 0.0 0.0
0.0 1.0 0.0
1.0 1.0 0.0
0.0 0.0 1.0
1.0 0.0 1.0
0.0 1.0 1.0
1.0 1.0 1.0

12 Edges (2 vertices each):
0 1
0 2
1 3
2 3
0 4
1 5
4 5
2 6
4 6
3 7
5 7
6 7

6 Faces (4 vertices each):
0 1 2 3
0 1 4 5
0 2 4 6
1 3 5 7
2 3 6 7
4 5 6 7

Bir unix komut kabuğundan giriş ( 120 hücreli polikoron ):

$ echo "5 3 3" | ./schlafli_interpreter.py | grep ":"

Çıktı:

600 Vertices:
1200 Edges (2 vertices each):
720 Faces (5 vertices each):
120 3-cells (20 vertices each):

Giriş (10 boyutlu çapraz politop ):

$ echo "3 3 3 3 3 3 3 3 4" | ./schlafli_interpreter.py | grep ":"

Çıktı:

20 Vertices:
180 Edges (2 vertices each):
960 Faces (3 vertices each):
3360 3-cells (4 vertices each):
8064 4-cells (5 vertices each):
13440 5-cells (6 vertices each):
15360 6-cells (7 vertices each):
11520 7-cells (8 vertices each):
5120 8-cells (9 vertices each):
1024 9-cells (10 vertices each):

Giriş (15 boyutlu simpleks ):

$ echo "3 3 3 3 3 3 3 3 3 3 3 3 3 3" | ./schlafli_interpreter.py | grep ":"

16 Vertices:
120 Edges (2 vertices each):
560 Faces (3 vertices each):
1820 3-cells (4 vertices each):
4368 4-cells (5 vertices each):
8008 5-cells (6 vertices each):
11440 6-cells (7 vertices each):
12870 7-cells (8 vertices each):
11440 8-cells (9 vertices each):
8008 9-cells (10 vertices each):
4368 10-cells (11 vertices each):
1820 11-cells (12 vertices each):
560 12-cells (13 vertices each):
120 13-cells (14 vertices each):
16 14-cells (15 vertices each):

Yıldız politoplar

Ha, ve doğal olarak yıldız politopları da var! Denememe bile gerek kalmadı :-) Sonunda Euler formülü hakkında biraz başarısız, çünkü bu formül yıldız politoplar için geçerli değil.

Giriş ( küçük yıldız şeklinde dodecahedron ):

5/2 5

Çıktı:

12 Vertices:
0.0 0.0 0.0
1.0 0.0 0.0
0.8090169943749473 0.5877852522924732 0.0
0.19098300562505266 0.5877852522924732 0.0
0.5 -0.36327126400268034 0.0
0.8090169943749473 -0.2628655560595667 0.5257311121191336
0.19098300562505266 -0.2628655560595667 0.5257311121191336
0.5 0.162459848116453 -0.3249196962329062
0.5 0.6881909602355867 0.5257311121191336
0.0 0.32491969623290623 0.5257311121191336
0.5 0.1624598481164533 0.8506508083520398
1.0 0.32491969623290623 0.5257311121191336

30 Edges (2 vertices each):
0 1
0 2
1 3
2 4
3 4
0 5
1 6
5 7
6 7
0 8
2 9
7 8
7 9
1 8
0 10
3 11
5 9
4 10
7 11
4 9
2 5
1 10
4 11
6 11
6 8
3 10
3 6
2 10
9 11
5 8

12 Faces (5 vertices each):
0 1 2 3 4
0 1 5 6 7
0 2 7 8 9
1 3 7 8 11
0 4 5 9 10
2 4 5 7 11
1 4 6 10 11
0 3 6 8 10
3 4 6 7 9
2 3 9 10 11
1 2 5 8 10
5 6 8 9 11
Traceback (most recent call last):
  File "./schlafli_interpreter.py", line 185, in <module>
    assert sum((-1)**i * N[i] for i in range(len(N))) == 1 + (-1)**len(schlafli)
AssertionError

Giriş ( mükemmel yıldızlanmış 120 hücreli ):

$ echo "5/2 3 5" | ./schlafli_interpreter.py | grep ":"

Çıktı:

120 Vertices:
720 Edges (2 vertices each):
720 Faces (5 vertices each):
120 3-cells (20 vertices each):

Bu soruyu tekrar canlandırdığınız için teşekkür ederiz ve cevabınız oldukça etkileyici görünüyor. Özyinelemeli doğayı ve yıldız figürlerini severim. Kodunuzu politoplar çizmek için bazı opengl'e bağladım (yukarıdaki github bağlantısına bakın).
Tony Ruth

14

Yakut

Arka fon

Sonsuz boyutlara uzanan üç düzenli politop ailesi vardır:

  • tetrahedronun üyesi olduğu simpleksler (simpleks terimi daha doğru olmasına rağmen, burada sık sık hipertetrahedra olarak anlatacağım.) Onların schlafi sembolleri formda {3,3,...,3,3}

  • küpün üyesi olduğu n küpleri. Schlafi sembolleri şu şekildedir{4,3,...,3,3}

  • oktahedronun üyesi olduğu ortopleksler (sık sık burada hyperoctahedra olarak bahsedeceğim) Schlafi sembolleri formdadır {3,3,...,3,4}

{m}Herhangi bir sayıda m kenarına sahip olabilen 2 boyutlu çokgenlerin sonsuz bir düzenli politop ailesi sembolü vardır .

Buna ek olarak, sadece beş özel düzenli politop vakası vardır: 3 boyutlu ikosahedron {3,5}ve dodekahedron {5,3}; bunların 4-boyutlu analogları 600-hücre {3,3,5}ve 120-hücre {5,3,3}; ve bir diğer 4 boyutlu politop, 24 hücreli {3,4,3}(3 boyuttaki en yakın analogları küboktahedron ve ikilisi eşkenar dodekahedron olan).

Ana işlev

Aşağıda polytopeschlafi sembolünü yorumlayan ana işlev bulunmaktadır. Bir sayı dizisi bekler ve aşağıdaki gibi bir dizi dizi içeren bir dizi döndürür:

  • Tüm köşelerin bir dizisi, her biri n öğeli bir koordinat dizisi olarak ifade edilir (burada n, boyut sayısıdır)

  • Her kenarın bir dizi köşe indeksleri olarak ifade edilen tüm kenarlardan oluşan bir dizi

  • Her yüzün, köşe indekslerinin bir m elemanı olarak ifade edildiği tüm yüzlerden oluşan bir dizi (burada m, yüz başına köşe sayısıdır)

ve böylece boyut sayısına uygun şekilde devam eder.

2d politoplarını kendisi hesaplar, 3 sonsuz boyutlu aile için işlevleri çağırır ve beş özel durum için arama tablolarını kullanır. Üzerinde belirtilen fonksiyonları ve tabloları bulmayı bekler.

include Math

#code in subsequent sections of this answer should be inserted here 

polytope=->schl{
  if schl.size==1                                #if a single digit calculate and return a polygon
    return [(1..schl[0]).map{|i|[sin(PI*2*i/schl[0]),cos(PI*2*i/schl[0])]},(1..schl[0]).map{|i|[i%schl[0],(i+1)%schl[0]]}]  
  elsif  i=[[3,5],[5,3]].index(schl)             #if a 3d special, lookup from tables
    return [[vv,ee,ff],[uu,aa,bb]][i]
  elsif i=[[3,3,5],[5,3,3],[3,4,3]].index(schl)  #if a 4d special. lookup fromm tables
    return [[v,e,f,g],[u,x,y,z],[o,p,q,r]][i]
  elsif schl.size==schl.count(3)                 #if all threes, call tetr for a hypertetrahedron
    return tetr[schl.size+1]
  elsif schl.size-1==schl.count(3)               #if all except one number 3
    return cube[schl.size+1] if schl[0]==4       #and the 1st digit is 4, call cube for a hypercube
    return octa[schl.size+1] if schl[-1]==4      #and the last digit is 4, call octa for a hyperoctahedron
  end
  return "error"                                 #in any other case return an error
}

Tetrahedron, küp ve oktahedron familyaları için fonksiyonlar

https://en.wikipedia.org/wiki/Simplex

https://en.wikipedia.org/wiki/5-cell (4d simpleks)

http://mathworld.wolfram.com/Simplex.html

Tetrahedron ailesi açıklaması - koordinatlar

n-boyutlu bir simpleks / hipertetrahedron n + 1 puana sahiptir. N-boyutlu simpleks köşelerini n + 1 boyutlarında vermek çok kolaydır.

Böylece (1,0,0),(0,1,0),(0,0,1)3 boyutlu gömülü bir 2d üçgen ve (1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)4 boyutlu gömülü bir 3d tetrahedron açıklanmaktadır. Bu, köşeler arasındaki tüm mesafelerin sqrt (2) olduğunu doğrulayarak kolayca doğrulanabilir.

N-boyutlu uzayda n-boyutlu simpleks için köşeleri bulmak için internette çeşitli karmaşık algoritmalar verilmiştir. Https://mathoverflow.net/a/38725 adresindeki Will Jagy'nin yorumlarında oldukça basit bir tane buldum . Son nokta p=q=...=x=y=z, diğerlerinden sqrt (2) mesafede hatta yatıyor . Bu nedenle, yukarıda üçgen ya da bir noktaya eklenmesiyle bir tetrahedron dönüştürülebilir (-1/3,-1/3,-1/3)ya da (1,1,1). Son nokta için koordinatların bu 2 olası değeri (1-(1+n)**0.5)/nve(1+(1+n)**0.5)/n

Soru n-tope büyüklüğü önemli değil diyor, ben n tarafından aracılığıyla çarpın tercih ve koordinatları kullanmak (n,0,0..0)kadar (0..0,0,n)final noktası ile (t,t,..,t,t)t = uygulama 1-(1+n)**0.5basitlik için.

Bu tetrahedronun merkezi başlangıç ​​noktasında olmadığından s.map!{|j|j-((1-(1+n)**0.5)+n)/(1+n)}, merkezin başlangıç ​​noktasından ne kadar uzak olduğunu bulan ve onu çıkaran çizgi tarafından tüm koordinatlarda bir düzeltme yapılmalıdır . Bunu ayrı bir işlem olarak sakladım. Bununla birlikte , dizi tarafından başlatıldığında buraya doğru ofseti koyabileceğimize ve merkezleme düzeltmesini sondan ziyade başlangıçta yapabileceğimize değinmek için s[i]+=nnerede yaptım .s[i]=ns=[0]*n

Tetrahedron ailesi açıklaması - grafik topolojisi

Tek yönlü grafiğin tamamı grafiktir: her tepe noktası, diğer tepe noktalarına tam olarak bir kez bağlanır. Bir n simpleksimiz varsa, n-1 simpleks vermek için herhangi bir tepe noktasını, bir üçgene veya bir kenara sahip olduğumuz noktaya kadar kaldırabiliriz.

Bu nedenle, her biri bir ikili sayıyla temsil edilen toplam 2 ** (n + 1) öğeye sahibiz. Bu 0, hiçlik için tüm s'den, 1bir tepe 1için bir s ve bir kenar için iki s 1, tam politop için tüm s'ye kadar değişir .

Her boyuttaki öğeleri saklamak için bir dizi boş dizi ayarladık. Ardından, olası köşe alt kümelerinin her birini oluşturmak için sıfırdan (2 ** n + 1) döngüye girer ve her alt kümenin boyutuna göre bunları dizide saklarız.

Kenardan (tepe noktası veya sıfır) daha küçük bir şeyle veya tam politopla (sorudaki örnekte tam küp verilmediğinden) ilgilenmiyoruz, bu nedenle tg[2..n]bu istenmeyen öğeleri kaldırmaya geri dönüyoruz. Geri dönmeden önce, tepe koordinatlarını içeren [tv] 'yi başa yapıştırıyoruz.

kod

tetr=->n{

  #Tetrahedron Family Vertices
  tv=(0..n).map{|i|
    s=[0]*n
    if i==n
      s.map!{(1-(1+n)**0.5)}
    else
      s[i]+=n
    end
    s.map!{|j|j-((1-(1+n)**0.5)+n)/(1+n)}
  s}

  #Tetrahedron Family Graph
  tg=(0..n+1).map{[]}
  (2**(n+1)).times{|i|
    s=[]
    (n+1).times{|j|s<<j if i>>j&1==1}
    tg[s.size]<<s
  }

return [tv]+tg[2..n]}

cube=->n{

  #Cube Family Vertices
  cv=(0..2**n-1).map{|i|s=[];n.times{|j|s<<(i>>j&1)*2-1};s}

  #Cube Family Graph
  cg=(0..n+1).map{[]}
  (3**n).times{|i|                         #for each point
    s=[]
    cv.size.times{|j|                      #and each vertex
      t=true                               #assume vertex goes with point
      n.times{|k|                          #and each pair of opposite sides
        t&&= (i/(3**k)%3-1)*cv[j][k]!=-1   #if the vertex has kingsmove distance >1 from point it does not belong      
      }
      s<<j if t                            #add the vertex if it belongs
    }
    cg[log2(s.size)+1]<<s if s.size > 0
  } 

return [cv]+cg[2..n]}

octa=->n{

  #Octahedron Family Vertices
  ov=(0..n*2-1).map{|i|s=[0]*n;s[i/2]=(-1)**i;s}

  #Octahedron Family Graph
  og=(0..n).map{[]}
  (3**n).times{|i|                         #for each point
    s=[]
    ov.size.times{|j|                      #and each vertex
      n.times{|k|                          #and each pair of opposite sides
        s<<j if (i/(3**k)%3-1)*ov[j][k]==1 #if the vertex is located in the side corresponding to the point, add the vertex to the list      
      }    
    }
    og[s.size]<<s
  } 

return [ov]+og[2..n]}

küp ve oktahedron aileleri açıklama - koordinatlar

N-küp olan 2**nköşe, n, bir dizi ile temsil edilen her bir 1S ve -1(bütün olasılığı da mümkün olduğunda). Biz, yineleme dizinlerini s 0için 2**n-1tüm tepe noktaları listesinin ve bit yineleme ile her bir köşe için bir dizi oluşturmak dizin ve diziye -1veya ekleme 1(en az anlamlı bit en anlamlı bit.) Böylece İkili 11014d noktası olur [1,-1,1,1].

N-sekiz yüzlü veya n-orthoplex sahip 2ntüm koordinatlar bir olması olan, biri dışında sıfır ile, köşe 1ya da -1. Oluşturulan dizideki köşe noktalarının sırası [[1,0,0..],[-1,0,0..],[0,1,0..],[0,-1,0..],[0,0,1..],[0,0,-1..]...]. Oktahedron, küpün ikizi olduğu için, oktahedronun köşelerinin, küpü çevreleyen yüzlerin merkezleri tarafından tanımlandığını unutmayın.

küp ve oktahedron aileleri açıklama - grafik topolojisi

Hypercube taraflarından ve hiperoktahedronun hiperküpün ikili olması gerçeğinden biraz ilham alındı .

N-küp 3**niçin kataloglanacak öğeler var . Örneğin, 3 küp3**3 = 27 elemente sahiptir. Bu, 1 merkez, 6 yüz, 12 kenar ve 8 köşeye sahip bir rubik küpünü toplam 27 için inceleyerek görülebilir. 2x2x2'lik bir n-küpü n-küpünü tanımlayan tüm boyutlarda -1,0 ve -1 arasında yineleme yaparız. .. ve küpün karşı tarafında OLMAYAN tüm köşeleri döndürün. Böylece küpün merkez noktası 2 ** n köşelerin tümünü döndürür ve bir birimi merkezden herhangi bir eksen boyunca hareket ettirmek, köşe sayısını yarı yarıya azaltır.

Tetrahedron ailesinde olduğu gibi, boş bir dizi dizisi üreterek başlıyoruz ve onu element başına köşe sayısına göre dolduruyoruz. Kenarların, yüzlerin, küplerin vb. Yukarı doğru giderken köşe sayısı 2 ** n olarak değiştiğinden log2(s.size)+1, basitçe kullanmak yerine kullanacağımızı unutmayın s.size. Yine, fonksiyondan dönmeden önce hiper küpün kendisini ve 2'den az köşesi olan tüm elemanları kaldırmamız gerekir.

Oktahedron / ortopleks ailesi, küp ailesinin çiftidir, bu nedenle yine 3**nkataloglanacak öğeler vardır . Burada -1,0,1tüm boyutlar için yineleme yapıyoruz ve bir tepe noktasının sıfır olmayan koordinatı noktanın karşılık gelen koordinatına eşitse, tepe noktası o noktaya karşılık gelen listeye eklenir. Böylece bir kenar, sıfır olmayan iki koordinatı olan bir noktaya, bir üçgen sıfır olmayan 3 koordinatı olan bir noktaya ve bir tetrahedron, sıfır olmayan temasları olan bir noktaya (4d uzayda) karşılık gelir.

Her nokta için ortaya çıkan köşe dizileri, diğer durumlarda olduğu gibi büyük bir dizide saklanır ve geri dönmeden önce 2 köşeden az olan öğeleri kaldırmamız gerekir. Ancak bu durumda, algoritmanın kaydetmediği için n-tope üst öğesinin tamamını kaldırmamız gerekmez.

Küp kod uygulamaları mümkün olduğunca benzer olacak şekilde tasarlanmıştır. Bunun belirli bir zarafeti olsa da, aynı prensiplere dayanan daha verimli algoritmaların tasarlanması muhtemeldir.

https://en.wikipedia.org/wiki/Hypercube

http://mathworld.wolfram.com/Hypercube.html

https://en.wikipedia.org/wiki/Cross-polytope

http://mathworld.wolfram.com/CrossPolytope.html

3D özel durumlar için tablo oluşturma kodu

Parçaların en tutarlı etiketlemesi için yapıldığı gibi, son boyuta paralel beş kat simetri ekseni ile yönlendirilmiş ikosahedron / dodekahedron ile bir yönlendirme kullanılmıştır. İkosahedron için köşe ve yüzlerin numaralandırılması kod yorumlarındaki şemaya göre yapılır ve dodekahedron için tersine çevrilir.

Https://tr.wikipedia.org/wiki/Regular_icosahedron'a göre , ikosahedronun polar olmayan 10 köşesinin enlemi +/- arctan (1/2) 'dir. İkosahedronun ilk 10 köşesinin koordinatları, bu, xy düzleminden +/- 2 mesafede yarıçap 2'nin iki dairesinde. Bu, ortamın toplam yarıçapını (5) yapar, böylece son 2 köşe (0,0, + / - sqrt (2)) olur.

Dodekahedronun köşe noktalarının koordinatları, onları çevreleyen üç ikosahedron tepe noktasının koordinatlarının toplanmasıyla hesaplanır.

=begin
TABLE NAMES      vertices     edges      faces
icosahedron      vv           ee         ff
dodecahedron     uu           aa         bb 

    10
    / \   / \   / \   / \   / \
   /10 \ /12 \ /14 \ /16 \ /18 \
   -----1-----3-----5-----7-----9
   \ 0 / \ 2 / \ 4 / \ 6 / \ 8 / \
    \ / 1 \ / 3 \ / 5 \ / 7 \ / 9 \
     0-----2-----4-----6-----8-----
      \11 / \13 / \15 / \17 / \19 /
       \ /   \ /   \ /   \ /   \ / 
       11
=end

vv=[];ee=[];ff=[]
10.times{|i|
  vv[i]=[2*sin(PI/5*i),2*cos(PI/5*i),(-1)**i]
  ee[i]=[i,(i+1)%10];ee[i+10]=[i,(i+2)%10];ee[i+20]=[i,11-i%2]
  ff[i]=[(i-1)%10,i,(i+1)%10];ff[i+10]=[(i-1)%10,10+i%2,(i+1)%10]

}
vv+=[[0,0,-5**0.5],[0,0,5**0.5]]

uu=[];aa=[];bb=[]
10.times{|i|
  uu[i]=(0..2).map{|j|vv[ff[i][0]][j]+vv[ff[i][1]][j]+vv[ff[i][2]][j]}
  uu[i+10]=(0..2).map{|j|vv[ff[i+10][0]][j]+vv[ff[i+10][1]][j]+vv[ff[i+10][2]][j]}
  aa[i]=[i,(i+1)%10];aa[i+10]=[i,(i+10)%10];aa[i+20]=[(i-1)%10+10,(i+1)%10+10]
  bb[i]=[(i-1)%10+10,(i-1)%10,i,(i+1)%10,(i+1)%10+10] 
}
bb+=[[10,12,14,16,18],[11,13,15,17,19]]

4d özel durumlar için tablo oluşturma kodu

Bu biraz hack. Bu kodun çalışması birkaç saniye sürer. Çıktıyı bir dosyada saklamak ve gerektiğinde yüklemek daha iyi olur.

600 hücre için 120 tepe koordinatı listesi http://mathworld.wolfram.com/600-Cell.html adresinden alınmıştır . Altın oran içermeyen 24 tepe koordinatı, 24 hücrenin köşe noktalarını oluşturur. Vikipedi aynı şemaya sahiptir, ancak bu 24 koordinatın ve diğer 96'nın göreceli ölçeğinde bir hata vardır.

#TABLE NAMES                           vertices     edges      faces   cells
#600 cell (analogue of icosahedron)    v            e          f       g
#120 cell (analogue of dodecahedron)   u            x          y       z 
#24 cell                               o            p          q       r

#600-CELL

# 120 vertices of 600cell. First 24 are also vertices of 24-cell

v=[[2,0,0,0],[0,2,0,0],[0,0,2,0],[0,0,0,2],[-2,0,0,0],[0,-2,0,0],[0,0,-2,0],[0,0,0,-2]]+

(0..15).map{|j|[(-1)**(j/8),(-1)**(j/4),(-1)**(j/2),(-1)**j]}+

(0..95).map{|i|j=i/12
   a,b,c,d=1.618*(-1)**(j/4),(-1)**(j/2),0.618*(-1)**j,0
   h=[[a,b,c,d],[b,a,d,c],[c,d,a,b],[d,c,b,a]][i%12/3]
   (i%3).times{h[0],h[1],h[2]=h[1],h[2],h[0]}
h}

#720 edges of 600cell. Identified by minimum distance of 2/phi between them

e=[]
120.times{|i|120.times{|j|
  e<<[i,j]  if i<j && ((v[i][0]-v[j][0])**2+(v[i][1]-v[j][1])**2+(v[i][2]-v[j][2])**2+(v[i][3]-v[j][3])**2)**0.5<1.3  
}}

#1200 faces of 600cell. 
#If 2 edges share a common vertex and the other 2 vertices form an edge in the list, it is a valid triangle.

f=[]
720.times{|i|720.times{|j|
  f<< [e[i][0],e[i][1],e[j][1]] if i<j && e[i][0]==e[j][0] && e.index([e[i][1],e[j][1]])
}}

#600 cells of 600cell.
#If 2 triangles share a common edge and the other 2 vertices form an edge in the list, it is a valid tetrahedron.

g=[]
1200.times{|i|1200.times{|j|
  g<< [f[i][0],f[i][1],f[i][2],f[j][2]] if i<j && f[i][0]==f[j][0] && f[i][1]==f[j][1] && e.index([f[i][2],f[j][2]])

}}

#120 CELL (dual of 600 cell)

#600 vertices of 120cell, correspond to the centres of the cells of the 600cell
u=g.map{|i|s=[0,0,0,0];i.each{|j|4.times{|k|s[k]+=v[j][k]/4.0}};s}

#1200 edges of 120cell at centres of faces of 600-cell. Search for pairs of tetrahedra with common face
x=f.map{|i|s=[];600.times{|j|s<<j if i==(i & g[j])};s}

#720 pentagonal faces, surrounding edges of 600-cell. Search for sets of 5 tetrahedra with common edge
y=e.map{|i|s=[];600.times{|j|s<<j if i==(i & g[j])};s}

#120 dodecahedral cells surrounding vertices of 600-cell. Search for sets of 20 tetrahedra with common vertex
z=(0..119).map{|i|s=[];600.times{|j|s<<j if [i]==([i] & g[j])};s}


#24-CELL
#24 vertices, a subset of the 600cell
o=v[0..23]

#96 edges, length 2, found by minimum distances between vertices
p=[]
24.times{|i|24.times{|j|
  p<<[i,j]  if i<j && ((v[i][0]-v[j][0])**2+(v[i][1]-v[j][1])**2+(v[i][2]-v[j][2])**2+(v[i][3]-v[j][3])**2)**0.5<2.1  
}}

#96 triangles
#If 2 edges share a common vertex and the other 2 vertices form an edge in the list, it is a valid triangle.
q=[]
96.times{|i|96.times{|j|
  q<< [p[i][0],p[i][1],p[j][1]] if i<j && p[i][0]==p[j][0] && p.index([p[i][1],p[j][1]])
}}


#24 cells. Calculates the centre of the cell and the 6 vertices nearest it
r=(0..23).map{|i|a,b=(-1)**i,(-1)**(i/2)
    c=[[a,b,0,0],[a,0,b,0],[a,0,0,b],[0,a,b,0],[0,a,0,b],[0,0,a,b]][i/4]
    s=[]
    24.times{|j|t=v[j]
    s<<j if (c[0]-t[0])**2+(c[1]-t[1])**2+(c[2]-t[2])**2+(c[3]-t[3])**2<=2 
    }
s}

https://en.wikipedia.org/wiki/600-cell

http://mathworld.wolfram.com/600-Cell.html

https://en.wikipedia.org/wiki/120-cell

http://mathworld.wolfram.com/120-Cell.html

https://en.wikipedia.org/wiki/24-cell

http://mathworld.wolfram.com/24-Cell.html

Kullanım ve çıktı örneği

cell24 = polytope[[3,4,3]]

puts "vertices"
cell24[0].each{|i|p i}
puts "edges"
cell24[1].each{|i|p i}
puts "faces"
cell24[2].each{|i|p i}
puts "cells"
cell24[3].each{|i|p i}

vertices
[2, 0, 0, 0]
[0, 2, 0, 0]
[0, 0, 2, 0]
[0, 0, 0, 2]
[-2, 0, 0, 0]
[0, -2, 0, 0]
[0, 0, -2, 0]
[0, 0, 0, -2]
[1, 1, 1, 1]
[1, 1, 1, -1]
[1, 1, -1, 1]
[1, 1, -1, -1]
[1, -1, 1, 1]
[1, -1, 1, -1]
[1, -1, -1, 1]
[1, -1, -1, -1]
[-1, 1, 1, 1]
[-1, 1, 1, -1]
[-1, 1, -1, 1]
[-1, 1, -1, -1]
[-1, -1, 1, 1]
[-1, -1, 1, -1]
[-1, -1, -1, 1]
[-1, -1, -1, -1]
edges
[0, 8]
[0, 9]
[0, 10]
[0, 11]
[0, 12]
[0, 13]
[0, 14]
[0, 15]
[1, 8]
[1, 9]
[1, 10]
[1, 11]
[1, 16]
[1, 17]
[1, 18]
[1, 19]
[2, 8]
[2, 9]
[2, 12]
[2, 13]
[2, 16]
[2, 17]
[2, 20]
[2, 21]
[3, 8]
[3, 10]
[3, 12]
[3, 14]
[3, 16]
[3, 18]
[3, 20]
[3, 22]
[4, 16]
[4, 17]
[4, 18]
[4, 19]
[4, 20]
[4, 21]
[4, 22]
[4, 23]
[5, 12]
[5, 13]
[5, 14]
[5, 15]
[5, 20]
[5, 21]
[5, 22]
[5, 23]
[6, 10]
[6, 11]
[6, 14]
[6, 15]
[6, 18]
[6, 19]
[6, 22]
[6, 23]
[7, 9]
[7, 11]
[7, 13]
[7, 15]
[7, 17]
[7, 19]
[7, 21]
[7, 23]
[8, 9]
[8, 10]
[8, 12]
[8, 16]
[9, 11]
[9, 13]
[9, 17]
[10, 11]
[10, 14]
[10, 18]
[11, 15]
[11, 19]
[12, 13]
[12, 14]
[12, 20]
[13, 15]
[13, 21]
[14, 15]
[14, 22]
[15, 23]
[16, 17]
[16, 18]
[16, 20]
[17, 19]
[17, 21]
[18, 19]
[18, 22]
[19, 23]
[20, 21]
[20, 22]
[21, 23]
[22, 23]
faces
[0, 8, 9]
[0, 8, 10]
[0, 8, 12]
[0, 9, 11]
[0, 9, 13]
[0, 10, 11]
[0, 10, 14]
[0, 11, 15]
[0, 12, 13]
[0, 12, 14]
[0, 13, 15]
[0, 14, 15]
[1, 8, 9]
[1, 8, 10]
[1, 8, 16]
[1, 9, 11]
[1, 9, 17]
[1, 10, 11]
[1, 10, 18]
[1, 11, 19]
[1, 16, 17]
[1, 16, 18]
[1, 17, 19]
[1, 18, 19]
[2, 8, 9]
[2, 8, 12]
[2, 8, 16]
[2, 9, 13]
[2, 9, 17]
[2, 12, 13]
[2, 12, 20]
[2, 13, 21]
[2, 16, 17]
[2, 16, 20]
[2, 17, 21]
[2, 20, 21]
[3, 8, 10]
[3, 8, 12]
[3, 8, 16]
[3, 10, 14]
[3, 10, 18]
[3, 12, 14]
[3, 12, 20]
[3, 14, 22]
[3, 16, 18]
[3, 16, 20]
[3, 18, 22]
[3, 20, 22]
[4, 16, 17]
[4, 16, 18]
[4, 16, 20]
[4, 17, 19]
[4, 17, 21]
[4, 18, 19]
[4, 18, 22]
[4, 19, 23]
[4, 20, 21]
[4, 20, 22]
[4, 21, 23]
[4, 22, 23]
[5, 12, 13]
[5, 12, 14]
[5, 12, 20]
[5, 13, 15]
[5, 13, 21]
[5, 14, 15]
[5, 14, 22]
[5, 15, 23]
[5, 20, 21]
[5, 20, 22]
[5, 21, 23]
[5, 22, 23]
[6, 10, 11]
[6, 10, 14]
[6, 10, 18]
[6, 11, 15]
[6, 11, 19]
[6, 14, 15]
[6, 14, 22]
[6, 15, 23]
[6, 18, 19]
[6, 18, 22]
[6, 19, 23]
[6, 22, 23]
[7, 9, 11]
[7, 9, 13]
[7, 9, 17]
[7, 11, 15]
[7, 11, 19]
[7, 13, 15]
[7, 13, 21]
[7, 15, 23]
[7, 17, 19]
[7, 17, 21]
[7, 19, 23]
[7, 21, 23]
cells
[0, 1, 8, 9, 10, 11]
[1, 4, 16, 17, 18, 19]
[0, 5, 12, 13, 14, 15]
[4, 5, 20, 21, 22, 23]
[0, 2, 8, 9, 12, 13]
[2, 4, 16, 17, 20, 21]
[0, 6, 10, 11, 14, 15]
[4, 6, 18, 19, 22, 23]
[0, 3, 8, 10, 12, 14]
[3, 4, 16, 18, 20, 22]
[0, 7, 9, 11, 13, 15]
[4, 7, 17, 19, 21, 23]
[1, 2, 8, 9, 16, 17]
[2, 5, 12, 13, 20, 21]
[1, 6, 10, 11, 18, 19]
[5, 6, 14, 15, 22, 23]
[1, 3, 8, 10, 16, 18]
[3, 5, 12, 14, 20, 22]
[1, 7, 9, 11, 17, 19]
[5, 7, 13, 15, 21, 23]
[2, 3, 8, 12, 16, 20]
[3, 6, 10, 14, 18, 22]
[2, 7, 9, 13, 17, 21]
[6, 7, 11, 15, 19, 23]

1
Vay be bu harika bir cevap! Bunu ~ 200 satırda yapabildiğinize çok şaşırdım. Küpü, tetrahedronu, 600 hücreli ve birkaçını çalıştırdım ve iyi görünüyorlardı. Çok fazla olduğu için çıktıyı doğrulamak zor; Çıktının programdan daha uzun olması oldukça kolaydır, ancak sözünüzü söyleyeceğim. Bunu openGL'ye yüklemeyi deneyeceğim ve tüm yüzler listelendiği için basit olması gereken platonik katıları göreceğim. Bence düz alana tesselasyon eklemek kolay olurdu ve bunu da deneyebilirim.
Tony Ruth

@TonyRuth anahtarı en iyi algoritmayı bulmaktı. Daha az satır = hata için daha az yer. Yaptığım ilk şey, 3 sonsuz boyutlu ailenin yanında neler olduğunu kontrol etmekti ve o zaman cevaplamaya karar verdim. Will Jagy'nin yorumları bir vaftiziydi (wikipedia'nın yöntemi zor görünüyordu, bu tür bir çözümü düşünüyordum), bu yüzden tamsayı olmayan koordinatlar minimumda tutuldu. Ödül sona ermeden önce bunu yapmak istedim, bu yüzden kontrol çok kapsamlı değildi ve onları çizmedim. Herhangi bir hatayı bana bildirin - 24 saatini birkaç saat önce düzelttim.
Level River St

@TonyRuth yüz köşeleri belirli bir sırada değildir (saat yönünde veya başka bir şeyle yüzün etrafından geçmezler). Daha yüksek boyutlar için standart bir sipariş yoktur. Hiper küpler sayısal sırayla listelenen yüzlere sahiptir, bu nedenle 2. ve 3. köşeler çapraz olarak zıttır (eğer saat yönünde / saat yönünün tersine) isterseniz 1. ve 2. veya 3. ve 4. tepe noktalarını değiştirmeniz gerekir.) Dodecahedronun yüzleri olmalıdır. saat yönünde / saat yönünün tersine sırada, ancak 120 hücrede tüm siparişlerde yüz köşeleri olacaktır.
Level River St
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.