CJam, 23 16 bajtów
Prawdopodobnie istnieje eleganckie matematyczne rozwiązanie tego problemu. Ale nie mam pojęcia, jak je znaleźć, więc jest to bardzo skompresowane kodowanie!
Znalazłem jedno! Cóż, nie jest to klasycznie eleganckie rozwiązanie matematyczne, ponieważ wykorzystuje operacje bitowe, ale ma całkowicie formułę.
li_o1^_p_6|o3+6%
Wypróbuj online.
Układ kostki
4-----7 4-----7 3-----2
/| /| / 0 /| / 3 /|
1-----0 | 1-----0 | 6-----5 |
| | | | | |2| | |4|
| 5---|-2 | 1 | 2 | 5 | 7
|/ |/ | |/ | |/
6-----3 6-----3 1-----4
Wyjaśnienie
Moja stara odpowiedź już ułożyła sześcian w taki sposób, że każdą twarz można opisać za pomocą pierwszego (lewego górnego) numeru wierzchołka równego numerowi twarzy. Ale chciałem móc obliczyć więcej liczb wierzchołków przy użyciu numeru twarzy. W pewnym momencie wpadłem na pomysł, który postawił mi stopę w drzwiach, aby obliczyć drugi (lewy górny) numer wierzchołka jako numer twarzy XOR 1. I po pewnym czasie prób i błędów udało mi się wymyślić z powyższym układem i poniższymi wzorami, które pozwalają mi zwięźle obliczyć każdą liczbę wierzchołków dla twarzy n
:
- Lewy górny:
n
- W prawym górnym rogu:
n^1
- Na dole po lewej:
(n^1)|6
- Prawy dolny:
((n^1)+3)%6
W celach informacyjnych odtworzę wynik dla każdej twarzy w pożądanym układzie tutaj:
Face: 0 1 2 3 4 5
Vertices: 01 10 23 32 45 54
74 63 70 65 72 61
Cały program sprowadza się więc do odczytu wejściowej liczby twarzy i generowania tych wartości w kolejności, choć z nieco inną logiką drukowania dla różnych wierzchołków. Zauważ, że ponieważ każdy wierzchołek po pierwszym zaczyna się od podstawy n^1
, muszę go tylko obliczyć raz, co jeszcze bardziej upraszcza logikę.
Dla potomności, a ponieważ uważam, że było to całkiem dobre podejście, oto moja stara odpowiedź.
CJam, 23 bajty
Prawdopodobnie istnieje eleganckie matematyczne rozwiązanie tego problemu. Ale nie mam pojęcia, jak je znaleźć, więc jest to super skompresowane kodowanie!
"pÜ×ñè¨"487b8b3/ri_o=~p
Wypróbuj online.
Układ kostki
0-----7 0-----7 3-----6
/| /| / 0 /| / 3 /|
1-----2 | 1-----2 | 4-----5 |
| | | | | |2| | |5|
| 5---|-6 | 1 | 6 | 4 | 7
|/ |/ | |/ | |/
4-----3 4-----3 1-----0
Wyjaśnienie
Podstawowym zastosowanym podejściem jest sztywne kodowanie wierzchołków dla każdej twarzy na możliwie jak najmniejszej przestrzeni. Podobnie do podstawowego rozwiązania konwersji Optimizera, traktuje listę wierzchołków jako liczbę ósemkową upakowaną jako dane znakowe ASCII. Ale na tym kończą się podobieństwa, aby zrobić miejsce na dalsze optymalizacje!
Oto trzy kluczowe optymalizacje, które wprowadziłem do „naiwnego” rozwiązania:
- Rozłóż sześcian w taki sposób, aby każdą ścianę można opisać za pomocą numeru ściany jako pierwszego numeru wierzchołka. Patrząc na mój układ kostki, jak pokazano powyżej, widać, że lewy górny numer wierzchołka każdej powierzchni jest równy numerowi powierzchni. To pozwala mi zakodować sześć mniej wierzchołków kosztem konieczności wydrukowania danych wejściowych z powrotem, co okazuje się, aby zaoszczędzić bajt.
- Spakuj dane wierzchołków do łańcucha, dla którego każdy „znak” ma maksimum większe niż 256. Gdy to maksimum wzrasta powyżej 256, długość łańcucha powoli maleje, ale staje się coraz bardziej prawdopodobne, że dowolny „znak” przekracza 256 i jest dlatego nie jest już częścią 1-bajtowego zestawu znaków ASCII. Napisałem więc program, który próbuje zakodować dane wierzchołków w każdej bazie od 256 do 1000, przy pomocy których znalazłem około 10 zasad, które zapisują jeden bajt danych znakowych w porównaniu do bazy 256. Wybrałem 487, ponieważ ma to również fajną właściwość: wynikowy ciąg składa się całkowicie z drukowalnego ASCII.
- W połączeniu z pierwszą optymalizacją produkuje się asymetrycznie. Zwykłym podejściem w CJam byłoby sformatowanie danych wierzchołków jako 2-elementowej listy 2-elementowej listy, wstawienie nowego wiersza na środku i pozwolenie na wydrukowanie danych wyjściowych. Zamiast tego drukuję pierwszy wierzchołek (równy wejściowej liczbie ścian) za pomocą operatora, który nie dodaje nowego wiersza, pobieram 3-elementową listę pozostałych wierzchołków, chwytam następny wierzchołek i drukuję go za pomocą operatora, który dodaje nowa linia i pozwól, aby pozostałe dwa wierzchołki zostały wydrukowane niejawnie. To oszczędza bajt.
6+n%2 --> 6|n
(już to uwzględniłem w mojej odpowiedzi Ruby). Zauważ, że wykonując transformacjęn --> n^1
na twarzach, możesz uprościć formuły, ale zgaduję, że odrzucającn
i kontynuującn^1
, wygrałeś nie pomóż swojemu wynikowi.n
in^1
pary wokół sześcianu pozwolą mi obliczyć kolejny wierzchołek za pomocą just|6
. I nie widziałem tejn --> n^1
transformacji, co zdecydowanie ma sens. Ale poprawnie przypuszczałeś, że tak naprawdę nie wpłynie to na mój wynik, więc prawdopodobnie zostawię go takim, jaki jest.6+n%2 --> 6|n
) Mam nadzieję, że nie masz nic przeciwko. Użyłemn --> n^1
transformacji na twarzach, więc moja najnowsza wersja daje te same wyniki, co twoje, ale z różnymi danymi wejściowymi. BTW, nie sądzę, że operacje bitowe są nieeleganckie, wszystko zależy od tego, jak ich używasz!~.1^..n@6|@3+6%
C, 69
Niegolfowany w programie testowym
Wyjaśnienie
Po rozłożeniu numeracja kostki wygląda następująco:
Lewy górny róg ma ten sam numer co twarz.
Prawy dolny róg ma numer
(n+2)%6
Dla nieparzystych
n
prawy górny róg jest,(n+1)%6
a lewy dolny -6
Bo nawet
n
prawy górny róg jest,7
a dolny lewy jest(n+1)%6
Program wyświetla liczby nieparzyste, jak pokazano, a liczby parzyste zostały obrócone o 180 stopni. Oznacza to, że prawy górny róg jest zawsze,
(n+1)%6
a lewy dolny zawsze(n+1)%2+6
. Odwracanien
in+2
jest łatwiejsze (odbywa się to przez ustawieniec=n+1
i użycied
do dodawania lub odejmowania1
lub-1
w razie potrzeby).Wynik
źródło
c%6
sięc%=6
i obracając twarz tak chodzi po pierwsze, powinno być możliwe do wyeliminowania pewnych obliczeń moduł sprężystości). Kolejną rzeczą do eksperymentowania z Is przesuwając etykietę twarzy o jedno miejsce, więc rozumiemn-1,n,n+1
zamiastn,n+1,n+2
.n
globalny, więc możesz zaoszczędzić kilka bajtów, deklarując go wyżej, zmienić podpis naf()
? A może patrzymy tylko na tęf
funkcję tutaj?"You may write a function instead of a program"
więc liczę tylko funkcję. W każdym razie był to tylko dowód koncepcji w języku, który znam najlepiej. Bardziej interesuje mnie skrócenie mojej rubyowej odpowiedzi, która od samego początku była już znacznie krótsza.Element, 18
W przeciwieństwie do wielu bardziej zaawansowanych języków golfowych, Element nie ma operatora kompresji, więc zwięzłość rozwiązania jest ściśle związana z zastosowanym dokładnym schematem numeracji. Po kilku eksperymentach stworzyłem nowy schemat numeracji, który umożliwia obliczanie wierzchołków przy użyciu prostych operacji arytmetycznych.
Lewy górny róg to 6, jeśli parzysty i 7, jeśli nieparzysty. Prawy górny róg to sam numer twarzy. Lewy dolny róg to numer twarzy plus 2, mod 6. Dolny prawy róg to 5 minus numer twarzy.
Oto wyjaśnienie kodu.
Oto wyniki dla każdej z twarzy:
źródło
Oktawa,
1081006850 bajtówOczywiście jest to sposób na zrobienie tego o wiele bardziej elegancki niż moje poprzednie podejście, zwykłe twarde kodowanie. Dziwi mnie, jak Octave jest bardziej odpowiedni dla codegolfa niż Matlab =)
Układ:
(Przepraszam, zapomniałem to dodać).
Układ kostki
Stare wersje:
Nawet starsze wersje:
To naprawdę zrobi tablicę 2x2x2, a następnie wybierze „plasterek”. Wykonujemy permutację macierzy 3D i za każdym razem wybieramy górny lub dolny wycinek. (Ten nie działa w Matlabie z powodu indeksowania wyrażenia, a nie macierzy). Jestem pewien, że byłyby bardziej bezpośrednie sposoby, które byłyby krótsze.
źródło
CJam,
3128 (lub 26) bajtówktóry można również skompresować za pomocą konwersji podstawowej do wersji 26-bajtowej .
Zakłada, że sześcian jest podobny do:
z twarzami takimi jak
Wypróbuj online tutaj
źródło
CJam (25 bajtów)
Zawiera znak niedrukowalny i zakładkę (która zostanie zniekształcona przez oprogramowanie StackExchange), więc w formacie xxd:
Demo online
Sześcian:
Jest to czyste kodowanie, z wybranymi wierzchołkami sześcianu, aby zmaksymalizować ściśliwość podstawy. Dekoduję na liczby dwucyfrowe, więc żadna z nich nie może zaczynać się od 0. Nie chcę też, aby liczba zaczynała się od 7, ponieważ przesuwa to drugą podstawę zbyt wysoko. Dlatego 0 i 7 muszą znajdować się na długiej przekątnej. Chcę, aby pierwsza krawędź 10 poszła pierwsza, aby zmniejszyć wartość, którą koduję. Poza tym istnieje duża elastyczność bez zmiany liczby bajtów.
Jestem nieco rozczarowany, że po wyjęciu pierwszej postaci z magicznego sznurka, konieczne jest rzucenie go na int, zanim użyje się go jako podstawy do konwersji bazy. Mam nadzieję, że przyszłe wersje CJam uratują ten bajt, chociaż będzie za późno, aby go tutaj wykorzystać.
źródło
JavaScript (ES6), 53
62Edytuj Zapisz 8 bajtów za pomocą ciągów szablonów, dzięki @NinjaBearMonkey. Uwaga, nowe znaki w cudzysłowie są znaczące i nie można ich zwinąć.
Nie może być sprytny w Javascript, jest zbyt gadatliwy.
Wynik
for(i=0;i<6;i++)console.log(f(i),i)
Zobacz fragment do veify skojarzenia numer ( to było zabawne)
Pokaż fragment kodu
źródło
\n
, co powinno zaoszczędzić 8 bajtów.Ruby Rev 1,
4036->(c){print(c^1,c,"\n",6|c,(c+3)%6)}
Dzięki @rcrmn za sugestię użycia lambda do zapisania 4 bajtów. Nie byłam pewna, czy zostawię to anonimowe, ale wydaje się, że omawiano ją tutaj na meta i zdecydowałem, że to OK.
Tutaj jest to funkcja 40-bajtowa, dla porównania z moją odpowiedzią Ruby Rev 0, również poniżej (Oryginalna odpowiedź C jest w osobnym poście).
Dalsze inspiracje z Runer112: Opiera się to na modyfikacji schematu numeracji zastosowanej w jego najnowszej (16 bajtowej!) Odpowiedzi. Bezpośredni port programu PhiNotPi dałby ten sam wynik.
Przesuwając numerację z Rev 0 rundy o jeden krok i biorąc wszystko XOR 1, otrzymujemy następującą kostkę:
Wynik
Ruby Rev 0,
56 5250Zapisano 4 bajty, usuwając niepotrzebne
()%6
zc-d
i kolejne 2 (inspirowany runer112) o6+c%2 --> 6|c
.Wynik dotyczy funkcji, która jest tylko pierwszą linią. Jestem nowy w Ruby i dziwi mnie, że nie mogę znaleźć krótszej drogi niż 12 znaków (11 plus nowa linia), aby wprowadzić numer wejściowy użytkownika w n. W rezultacie wykonanie funkcji zamiast programu pozwala zaoszczędzić 1 bajt.
To jest port mojej odpowiedzi C. W C
%
operator zwraca wartość ujemną z liczbą ujemną. W Ruby zawsze zwraca wartość dodatnią, więc nie ma potrzeby dodawania 1 doc
. W rezultacie korzystne jest przesunięcie numeracji twarzy o 1, jak poniżej:Dzięki nowej numeracji twarzy program drukuje wyrównania, jak pokazano powyżej, a szanse zostały obrócone o 180 stopni:
źródło
->(x){...code...}
co pozostawia twoją definicję funkcji o 4 znaki krótszą. Następnie musisz przypisać ją do zmiennej, aby z niej skorzystać, i wywołać ją za pomocąf=->(c){print(c^1,c,"\n",6|c,(c+3)%6)}
działa i ma 2 znaki krótsze (4 znaki krótsze, jeśli pominęf=
). Nie jestem pewien, czy można to pominąć,f=
ale pytanie nie mówi, że funkcja nie może być anonimowa. Dziwne jest dla mnie to, że ta składnia jest zupełnie inna niż ta pokazana początkującym, która ma parametr przekazywany w nawiasach klamrowych:f=lambda{|c|print(c^1,c,"\n",6|c,(c+3)%6)}
Pyth, 30
Dzięki @Jakube za 2 bajty.
Wypróbuj tutaj.
Porady golfistów od ekspertów pyta będą mile widziane. W szczególności myślę, że sekcja wyników może zawierać pewne ulepszenia.
Port następującego python: ...
Python, 109
... który jest portem
Pure Bash, 130
W celu wyjaśnienia:
Wierzchołki sześcianu są ponumerowane w ten sposób:
A twarze są ponumerowane w ten sposób:
The
Swap
Kolumnie podana jest kolejność, w wierzchołkach powinien być włączony na wyjściu.Algorytm zaczyna się od wszystkich wierzchołków {0..7}. Wierzchołki są eliminowane zgodnie z bitami ustawionymi w liczbach wierzchołków:
„Zachowane” wierzchołki są dołączane do łańcucha. Łańcuch jest znakami wyjściowymi 0,1, a następnie 2,3 lub odwrotnie, w zależności od tego, czy ustawiona jest flaga wymiany (numer twarzy mod 2).
źródło
J - 26 bajtów
Funkcja przyjmuje numer twarzy jako argument i zwraca siatkę cyfr.
Używamy następującej kostki:
Przykład (spróbuj sam na tryj.tk ):
Chleb i masło są
0&(|:|.)
. Jest to czasownik, który odwraca i obraca kostkę w taki sposób, aby odwiedzać każdą twarz po iteracyjnym zastosowaniu, co robimy za pomocą argumentu wejściowego. Wierzchołki sześcianu są generowane przezi.3#2
, więc używamy tego jako punktu początkowego i bierzemy przednią powierzchnię0...{
gdy skończymy.Drukowanie cyfr w postaci łańcucha kosztuje 8 znaków:
{.@":"0@
Jeśli pozwolono nam po prostu zwrócić tablicę, oznacza to oszczędność 8 całych znaków. [zaczyna się trząść pięścią i chwytać za niedostrzegalne]źródło
> <> (Ryby) , 38 bajtów
Każde wyjście jest przechowywane jako dwa 2-cyfrowe wiersze. Wiersze są przechowywane jako ciągi znaków
'/ =/2= 28"H'
(oprócz wiersza)10
który jest dołączany po ciągu jakoa
). Pierwszy znak (/ = 47
) służy do przekierowania przepływu programu podczas drugiej interakcji.Szczyt
2*(53-n)
elementy są odrzucane (gdzie n jest kodem znaku liczby wejściowej), a kolejne dwa kody są drukowane z nową linią między.Układ:
źródło