Wprowadzenie
Hypercube / tesseract jest 4-wymiarowym odpowiednikiem normalnej kostki. Robi się to, biorąc siatkę sześcianu, rozciągając ją na trzeci wymiar, a następnie - używając czwartego wymiaru - składając ją w hipersześcian. Zasadniczo jest to sześcian, którego każda strona to sześcian.
Aby utworzyć hipersześcian, potrzebujesz 16 wektorów 4d (wektor z x
, a y
, a z
i w
składnikiem). Te wektory są następujące:
A(0, 0, 0, 0); B(1, 0, 0, 0); C(1, 0, 1, 0); D(0, 0, 1, 0); E(0, 1, 0, 0); F(1, 1, 0, 0); G(1, 1, 1, 0); H(0, 1, 1, 0);
I(0, 0, 0, 1); J(1, 0, 0, 1); K(1, 0, 1, 1); L(0, 0, 1, 1); M(0, 1, 0, 1); N(1, 1, 0, 1); O(1, 1, 1, 1); P(0, 1, 1, 1);
Hipersześcian ma 24 twarze. Poniższa lista zawiera je wszystkie (każda grupa oznacza quad):
ABFE, CDHG, BCGF, DAEH, DCBA, FEHG
IJNM, KLPO, JKON, LIMP, LKJI, PMNO
ABJI, DCKL, BCKJ, DAIL, FEMN, GHPO, FGON, EHPM, EAIM, BFNJ, CGOK, HDLP
Przy wszystkich tych informacjach technicznie masz hipersześcian w kodzie. Aby to obrócić, potrzebujesz 6 różnych matryc dla każdej płaszczyzny obrotu, po jednej dla płaszczyzn YZ, XZ, XY, XW, YW i ZW. Po utworzeniu każdej macierzy należy pomnożyć z nią wierzchołki sześcianu.
Poniższe obrazy przedstawiają strukturę każdej matrycy:
Dla obrotu na płaszczyźnie YZ:
Dla obrotu na płaszczyźnie XZ:
Dla obrotu na płaszczyźnie XY:
Dla obrotu na płaszczyźnie XW:
Dla obrotu na płaszczyźnie YW:
Dla obrotu na płaszczyźnie ZW:
Obroty są stosowane w tej kolejności.
Po tym wszystkim masz obróconą hipersześcian. Teraz musisz go narysować. Należy użyć rzut prostopadły połączoną z projekcją perspektywy wysłać (x, y, z, w)
do (2x/(2+z), 2y/(2+z))
.
Wkład
Twój wkład to 6 liczb całkowitych od 0 (włącznie) do 360 (wyłącznie). Reprezentują one obroty w stopniach na różnych płaszczyznach obrotu hipersześcianu.
Wydajność
Twój wynik powinien być pojedynczym obrazem zawierającym hipersześcian. Wyświetlany może być obraz rasteryzowany, obraz wektorowy lub grafika ASCII. Obraz wyjściowy powinien mieć co najmniej 100 * 100 pikseli, a kostka musi zajmować co najmniej 50% ekranu. Dowolny domyślny format wyjściowy obrazu jest dozwolony.
Przypadki testowe
0 0 0 0 0 0
0 0 0 0 0 30
30 0 0 0 0 30
0 0 0 30 30 30
45 45 45 0 0 0
45 45 45 45 45 45
Otwórz obrazy w nowej karcie, aby zobaczyć je w pełnym rozmiarze.
Zasady
- Obowiązują zasady domyślne
- Standardowe luki są zabronione
- Najkrótszy kod w bajtach wygrywa
źródło
Odpowiedzi:
Oktawa,
474433429 bajtówObrócono:
Matryce rotacyjne nadal zajmują dużo bajtów, ale cykl Eulera działał całkiem dobrze, zmniejszając liczbę odwiedzonych wierzchołków z
96120 do 33.Wierzchołki są generowane przez przyjęcie 4-bitowej reprezentacji binarnej
[0:15]
i uznanie msb za współrzędną x, a lsb współrzędną w.Edycja: Wstępne pomnożenie wszystkich macierzy obrotu było koszmarem, dlatego początkowo tego nie użyłem, ale wstępne pomnożenie ich parami pozwoliło zaoszczędzić 41 bajtów.
Teraz szukaj optymalnej kombinacji. :)Mnożenie macierzy przez trójki było gorsze niż brak pomnożenia wstępnego, więc będę zadowolony z podejścia opartego na parach.Wydajność:
źródło
Postscriptum
1075732683640631601590545542526514478470Używa mat.ps i G .
Edycja: -343 Zastosowano generowanie wektorów i obwód Eulera metodą kodowania binarnego
skradzionyzapożyczone z innych odpowiedzi. I zastosował ciągi binarne-tokena z biblioteki G.Edycja: -49 Przedefiniowano
sin
cos
ineg
skrócono nazwy.Edycja: -43 Zdefiniowane krótkie nazwy sekwencji
0 0
0 1
1 0
.Edycja: -9
al
(tj.aload
) Jest krótsza niż(")@
. Zrealizowano 3 wezwania doidi
(tj.idiv
) Kosztem bezczynności1 idiv
.Edycja: -30 Zastosowany domyślny blok definicji od G.
Edycja: -10 Kilka więcej potrójnie używanych sekwencji.
Edycja: -45 Usuń zmienne
i
j
k
l
m
n
dla kątów i zawsze definiuj aktualny kąt, ponieważt
funkcje kątów używają wartości (globalnej)t
zmienna. Odrocz wykonanie opisu kodu macierzy obrotu, aż jejt
wartość będzie gotowa.Edycja: -3 Usuń
<16>$
tj.closepath
. I przestrzeń.Edycja: -16 Wyliczenie nawiasów tablicowych z wektorów jednostkowych w macierzach obrotu (
J
K
L
iM
). Ponownie złóż wniosek porzuconymo
namod
isu
nasub
.Edycja: -12 W linii funkcja projektu i rysowania i usuń (teraz pusty) załączony słownik.
Edycja: -36 Zakodowano obwód (tj. Twarze ) w ciągu.
Edycja: -8 Usuń definicję tablicy wierzchołków
V
. Zamiast tego pozostaw na stosie idup
kopie robocze w razie potrzeby (raz, na początku i ponownie na końcu pętli). Przetłumaczyłem także kilka operatorów z ciągów znaków binarnych z powrotem na skrócone nazwy, w których BTS nie dał żadnych oszczędności, więc(I)$
terazfora
(tj.forall
).if du
może być(T8)$
, aleif du
jest zdecydowanie lepszym wyborem (to golf , a nie zaciemnianie per se). Wykonaj równieżscale
wcześniejtranslate
, aby przetłumaczone współrzędne mogły być3
i4
zamiast300
i400
.3
4
I100
w pierwszej linii drugiego bloku są parametry reprezentujące środkowy x, y i środkowy skali odpowiednio na rysunku na stronie (współrzędne środkowe są skalowanescale
). (300,400) to mniej więcej środek amerykańskiego papieru w formacie Letter (612 792) w jednostkach PS.Jeśli potrafisz z grubsza podążać za PostScriptem, ważnymi dziwacznymi rzeczami są niejawny blok procedur i zakodowane ciągi operatora. Jak pokazują komentarze w pliku roboczym poniżej, każda linia pierwszego bloku jest domyślnie nazwana przez A, B, C itd. Tak więc np.
F E D
produkuje1 0 0 1 0 0
. W przypadku zakodowanych ciągów operatora wszystko, co jest argumentem$
#
lub@
jest sekwencją wywołań operatora, przy użyciu bajtów do wybierania operatorów z systemowej tabeli nazw, PLRM 3ed Dodatek F. Te funkcje i więcej są dostępne dla PostScript z biblioteką G ( teraz obejmuje również funkcje mat.ps).Plik roboczy:
Niegolfowany i lekko komentowany:
Niektóre z moich wyników są lustrzanymi odbiciami przykładów pytania.
Dla
gs -- hc.ps 0 0 0 0 0 0
otrzymuję:gs -- hc.ps 0 0 0 0 0 30
gs -- hc.ps 30 0 0 0 0 30
gs -- hc.ps 0 0 0 30 30 30
gs -- hc.ps 45 45 45 0 0 0
gs -- hc.ps 45 45 45 45 45 45
Animacja bonusowa, którą właśnie wykonałem za pomocą tego programu. Ten obraz odpowiada sekwencji obrotu 0 30 60 0 i i , gdzie i wynosi od 0 do 360 o 2.
źródło
C # + Unity,
1060845835 bajtówC # ≈ Java
Zakłada, że ta funkcja jest umieszczona w skrypcie
MainCamera
.Edycja:
Podziękowania dla @TuukkaX za sugestie dotyczące zaoszczędzenia 19 bajtów Zapisano ~ 200 bajtów przy użyciu cyklu Eulera.
Gra w golfa:
Nowe linie + wcięcie + Pełna powłoka:
Nie mogłem wymyślić prostej formuły do konstruowania macierzy rotacji ani „ścian”, które należy narysować, tak że kodowanie kosztowało dużo bajtów.Pożyczałem cykl Eulera od @beaker. Ponadto wbudowane w Unity są bardzo gadatliwe.Możesz zweryfikować wszystkie przypadki testowe online .
źródło
0.5f
można zredukować do.5f
i0.01f
do.01f
. Myślę też, że tablice liczb całkowitych można oddzielić przecinkiem zamiast powtarzaćint[]
wiele razy.int[,]
. Wciąż dziękuję.Vector4(0.5f,0.5f,0.5f,0.5f)
co można zmniejszyćVector4(.5f,.5f,.5f,.5f)
.JavaScript ES6, 584 bajty
„Nie golf”:
Zobacz to w akcji (zmodyfikowane w celu ciągłego obracania):
Funkcja zwraca obiekt canvas HTML5, musisz na przykład dodać go do strony
document.body.appendChild(f(0,0,0,0,0,0))
.Obecnie rotacje są stosowane w kolejności, pracuję nad zmianą kolejności, ale jak to jest, to poprawnie obraca hipersześcian.
źródło
Mathematica,
453415 bajtów *Skrócono przez użycie trasy Eulerian i oczyszczenie jej w jedną instrukcję bez definiowania funkcji w zmiennych. Z jakiegoś powodu powoduje to spowolnienie kodu. Zgaduję, że Mathematica wielokrotnie ocenia te funkcje teraz, gdy nie są one przechowywane w zmiennej.
* Liczę
°
i==
jako pojedyncze bajty, ponieważ są one reprezentowane jako pojedynczy znak w Mathematica. Myślę, że to uczciwe, ponieważ wiele języków używa dziwnych kodowań znaków.Nie golfił z komentarzami. Wejście jest na stałe zakodowane na górze jako
a={30,0,0,0,0,30};
. Nie wliczałem tego do mojego wyniku.0 0 0 0 0 30
0 0 0 30 30 30
405 10 -14 -8 -9 205
źródło