Krzywa algebraiczna jest pewnym „podzbiorem 1D” „płaszczyzny 2D”, który można opisać jako zbiór zer {(x,y) in R^2 : f(x,y)=0 }
wielomianu f
. Uważamy tutaj płaszczyznę 2D za rzeczywistą, R^2
dzięki czemu możemy łatwo wyobrazić sobie, jak mogłaby wyglądać taka krzywa, w zasadzie rzecz, którą można narysować ołówkiem.
Przykłady:
0 = x^2 + y^2 -1
okrąg o promieniu 10 = x^2 + 2y^2 -1
elipsa0 = xy
przekroju kształt w zasadzie Związek osi x i na osi y0 = y^2 - x
parabola0 = y^2 - (x^3 - x + 1)
eliptyczna krzywa0 = x^3 + y^3 - 3xy
folium Kartezjusza0 = x^4 - (x^2 - y^2)
lemniscate0 = (x^2 + y^2)^2 - (x^3 - 3xy^2)
trifolium0 = (x^2 + y^2 - 1)^3 + 27x^2y^2
astroid
Zadanie
Biorąc pod uwagę wielomian f
(jak zdefiniowano poniżej) i zakresy x / y, wysyłaj czarno-biały obraz o wielkości co najmniej 100 x 100 pikseli, który pokazuje krzywą jako czarną linię na białym tle.
Detale
Kolor : możesz użyć dowolnych dwóch innych kolorów, po prostu łatwo je rozróżnić.
Fabuła : Zamiast obrazu pikselowego możesz również wyprowadzić ten obraz jako ascii-art, gdzie „piksele” w tle powinny być spacją / podkreśleniem lub innym znakiem, który „wygląda na pusty”, a linia może być utworzona z postaci, która wygląda na „ pełny ”jak M
lub X
lub #
.
Nie musisz się martwić aliasingiem.
Musisz tylko wykreślić linie, w których znak wielomianu zmienia się z jednej strony linii na drugą (co oznacza, że możesz np. Użyć algorytmu marszowego kwadratu), nie musisz poprawnie wykreślić „przypadków patologicznych, takich jak 0 = x^2
znak nie zmieniaj się, przechodząc z jednej strony linii na drugą. Ale linia powinna być ciągła i oddzielać regiony różnych znaków f(x,y)
.
Wielomian : Wielomian podano jako (m+1) x (n+1)
macierz / listę list (rzeczywistych) współczynników, w poniższym przykładzie warunki współczynników podano w ich pozycji:
[ 1 * 1, 1 * x, 1 * x^2, 1 * x^3, ... , 1 * x^n ]
[ y * 1, y * x, y * x^2, y * x^4, ... , y * x^n ]
[ ... , ... , ... , ... , ... , ... ]
[ y^m * 1, y^m * x, y^m * x^2, y^m * x^3 , ..., y^m * x^n]
Jeśli wolisz, możesz założyć, że macierz jest kwadratowa (co zawsze można zrobić z niezbędnym uzupełnieniem zerowym), a jeśli chcesz, możesz również założyć, że rozmiar matrycy jest podany jako dodatkowe dane wejściowe.
Poniżej przykłady z góry są przedstawione jako macierz zdefiniowana w następujący sposób:
Circle: Ellipse: Parabola: Cross: Elliptic Curve: e.t.c
[-1, 0, 1] [-1, 0, 1] [ 0,-1] [ 0, 0] [-1, 1, 0,-1]
[ 0, 0, 0] [ 0, 0, 0] [ 0, 0] [ 0, 1] [ 0, 0, 0, 0]
[ 1, 0, 0] [ 2, 0, 0] [ 1, 0] [ 1, 0, 0, 0]
Przypadki testowe z zakresem x / y:
(W niezbyt czytelnym, ale lepszym formacie umożliwiającym kopiowanie i wklejanie, dostępnym tutaj na pastebin .)
Circle:
[-1, 0, 1] [-2,2] [-2,2]
[ 0, 0, 0]
[ 1, 0, 0]
Ellipse:
[-1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0]
[ 2, 0, 0]
Cross:
[ 0, 0] [-1,2] [-2,1]
[ 0, 1]
Parabola:
[ 0,-1] [-1,3] [-2,2]
[ 0, 0]
[ 1, 0]
Elliptic Curve:
[-1, 1, 0,-1] [-2,2] [-3,3]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Folium of Descartes:
[ 0, 0, 0, 1] [-3,3] [-3,3]
[ 0, -3, 0, 0]
[ 0, 0, 0, 0]
[ 1, 0, 0, 0]
Lemniscate:
[ 0, 0, -1, 0, 1] [-2,2] [-1,1]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Trifolium:
[ 0, 0, 0,-1, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0]
[ 0, 3, 2, 0, 0]
[ 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0]
Astroid:
[ -1, 0, 3, 0, -3, 0, 1] [-1,1] [-1,1]
[ 0, 0, 0, 0, 0, 0, 0]
[ 3, 0, 21, 0, 3, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ -3, 0, 3, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0, 0, 0]
[ 1, 0, 0, 0, 0, 0, 0]
Inspiracja do niektórych krzywych pochodzi z tego pliku pdf.
m
xn
, ale(m+1)
x(n+1)
. Co przyjmujemy za dane wejściowe:m, n
lubm+1,n+1
? Czy możemy wybrać?Odpowiedzi:
Haskell,
283275 bajtówFunkcję
g
należy wywołać z macierzą i dwoma zakresami jako argumentami. Matryca to tylko lista list, a zakresy to lista dwóch elementów.Oto wyniki dla bardziej interesujących przypadków: Zauważ, że musiałem zmniejszyć wynik ze 100 x 100 do około 40 x 40, tak aby pasował do konsoli (wystarczy zmienić kod na 102 na mniejszą liczbę). Zauważ też, że oś y jest skierowana w dół.
źródło
$
do zapisania bajtu. Oba miejsca, w których korzystasz,map
mogą być(<$>)
, a ponieważ używasz tylkoe
raz, kiedy możesz wyciągnąć(0<)
wnętrze, jest to definicja. Równieże
może być nazwane(!)
, aby zapisać 3 bajty.z
w definicjiv
pozwala pozbyć się 4 nawiasów (wokółz(&)
if g
).#
na pojedynczy znak (np.s
) I zamiast tego dopasować wzorzec na listachg
. (np.s[a,b]=[a,a+(b-a)/102..b];g m u i=unlines$v[m!y<$>s u|y<-s i]
)Matlab,
11410092 bajtówOdpowiednie narzędzie do pracy? Używam interesującego sposobu, w jaki Matlab
printf
generuje wielomian jako ciąg. Można podać ten wielomian, naezplot
którym drukuje się ukrytą krzywą w określonej domenie. Dla czytelności kod jest prezentowany z nowymi wierszami po; co nie jest potrzebne i nie jest wliczane do rozmiaru.Postęp w golfa jako fragment rozwijany.
Pokaż fragment kodu
Wyjście przypadków testowych (kliknij, aby zobaczyć pełny widok):
źródło
sprintf/ezplot
!fix
zamiast zamiastfloor
może pomóc w osiągnięciu dwucyfrowej liczby bajtów :-)[h,w]=size(A);t=0:h*w-1;
do zapisania kolejnych trzech bajtów!%.0f
. Oznacza to, że mogę całkowicie upuścić podłogę i pozwolić miprintf
to naprawić!Python 2, 261 bajtów
Format wejściowy:
matrix,xbounds,ybounds
(np[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
.). Format wyjściowy: zwykły PGM .Szacuje się odległość od każdego środka piksela do krzywej za pomocą aproksymacji pierwszego rzędu d ( x , y ) = | p ( x , y ) | / | ∇ p ( x , y ) |, gdzie ∇ p jest gradientem wielomianu p . (Jest to odległość od ( x , y ) do przecięcia płaszczyzny stycznej w ( x , y , p ( x , y )) z płaszczyzną xy .) Następnie piksele, w których d (x , y ) ma mniej niż jeden piksel szerokości krzywej proporcjonalnie do d ( x , y ), co daje ładne linie antyaliasingu (nawet jeśli nie jest to wymagane).
Oto te same wykresy z funkcją odległości podzieloną przez 16, aby była widoczna.
źródło
print
instrukcja dla nagłówka obrazu i jednaprint
instrukcja wwhile
pętli dla wartości każdego piksela.Python 3.5 + MatPlotLib + Numpy, 352 bajty:
Nazwana funkcja. Dość długo, ale hej, po prostu cieszę się, że udało mi się wykonać to zadanie. Pobiera 3 dane wejściowe, czyli
m by n
macierz, thex
-range iy
-range, które powinny znajdować się w tablicach (na przykład[[-1,0,1],[0,0,0],[1,0,0]],[-2,2],[-2,2]
). Wysyła ukończony wykres w nowym graficznym, interaktywnym oknie. Będę grał w golfa więcej czasu, kiedy będę mógł, ale na razie jestem z tego zadowolony.Końcowe wyniki dla przypadków testowych:
źródło
MATL ,
6761 bajtówTen kod działa w wersji 18.5.0 języka, który poprzedza wyzwanie. Wejście używa Opcjonalnie
m
,n
parametry. Matryca ma średniki jako separatory wierszy. Dokładny format wejściowy (na przykładzie paraboli) toKod tworzy obraz o rozmiarze 255 × 255. To mogą być testowane za pomocą @Suever „s Mátl online kompilator, który, między innymi bardzo interesujących cech, zawiera wyjście graficznego. Zobacz na przykład
Ten kompilator jest wciąż w fazie eksperymentalnej. Proszę zgłaszać wszelkie problemy do @Suever na czacie MATL . Jeśli przycisk „Uruchom” nie działa, spróbuj odświeżyć stronę i kliknąć ponownie.
Jeśli wolisz wyjście ASCII , kod należy nieco zmodyfikować (zmiany dotyczą tylko pierwszych dwóch i czterech ostatnich znaków powyższego kodu):
W ten sposób powstaje siatka ASCII 100 × 100, która używa znaku
*
do reprezentowania krzywej. Możesz to również przetestować za pomocą @Dennis ' Wypróbuj online! Platforma:Zauważ, że współczynnik kształtu wyjścia ASCII jest zmieniony, ponieważ znaki są nieco wyższe niż szerokie.
Wyjaśnienie
Kod najpierw oblicza wielomian dwóch zmiennych na siatce x - y . To często wykorzystuje transmisję , obliczając pośrednią macierz 4D, gdzie każdy wymiar reprezentuje odpowiednio x wartości, y wartości, x wykładników, y wykładników.
Na podstawie tej funkcji obliczana jest linia poziomu zerowego. Ponieważ w wyzwaniu określono, że należy wykryć tylko zmiany w znakach, kod stosuje splot 2D z blokiem 2 × 2 jedynek i oznacza piksel jako należący do linii, jeśli nie cztery wartości bloku mają ten sam znak.
Wszystkie przypadki testowe
Oto wszystkie dane wejściowe w odpowiednim formacie, na wypadek gdybyś chciał spróbować:
źródło