W bardzo niedocenianej powieści Steampunk The Difference Engine odpowiednik domów kinowych zapewniał pikselowany ruchomy obraz wyświetlany za pomocą płytek, które można było odwracać mechanicznie. Silnikiem sterującym ruchem tych płytek była duża, hałaśliwa maszyna kontrolowana przez talię perforowanych kart.
Twoim zadaniem jest emulowanie takiego silnika i wyświetlanie animacji pikselowej określonej przez plik wejściowy. Dane wejściowe składają się z linii w formacie o stałej szerokości, ale można założyć, co jest wygodne dla wskazania końca linii. Format to:
SSSSYYxxXXOA
SSSS: 4 digit sequence no. may be padded by blanks or all blank
YY: the y coordinate affected by this line (descending, top is 0, bottom is m-1)
xx: the starting x coordinate
XX: the ending x coordinate
O: hexadecimal opcode
A: argument (0 or 1)
Dane wejściowe są wyraźnie uporządkowane (jeśli kiedykolwiek upuścisz swoją talię kart na podłogę, podziękujesz mi za tę część). Oznacza to, że program musi wykonać stabilny rodzaj linii wejściowych, używając pola sekwencji jako klucza sortowania. Linie o tym samym numerze sekwencji muszą zachować swoje pierwotne względne uporządkowanie. (Powinno to działać z niestabilnym sortowaniem, jeśli do klawisza zostanie dołączony rzeczywisty numer linii.) Puste pole sekwencji powinno być interpretowane jako niższe niż dowolna liczba (sekwencja sortowania ascii).
Pojedyncza linia instrukcji może wpływać tylko na jedną współrzędną y, ale może określać ciągły zakres wartości x. Końcowa wartość x może pozostać pusta lub może być identyczna z wartością początkową, aby wpłynąć na pojedynczy piksel.
Kod op jest cyfrą szesnastkową, która określa uniwersalny binarny kod funkcji, który jest używany jako rasterop. Argument wynosi 0 lub 1. Wykonywana operacja rastrowa to
pixel = pixel OP argument infix expression
--or--
OP(pixel, argument) function call expression
Tak więc oryginalna wartość piksela jest wprowadzana jako X w tabeli UBF, a wartość argumentu z instrukcji jest wprowadzana jako Y. Wynikiem tej funkcji jest nowa wartość piksela. Ta operacja jest wykonywana na każdej parze x, y od xx, YY do XX, YY określonej w instrukcji. Zakres określony przez xx i XX obejmuje oba punkty końcowe. Więc
0000 0 010F1
powinien ustawić piksele 0,1,2,3,4,5,6,7,8,9,10 w rzędzie 0.
Wymiary wyjściowe ( m x n ) powinny wynosić co najmniej 20 x 20, ale w razie potrzeby mogą być większe. Ale ziarno powinno pokazać, wiesz? Ma być pikselowany . Dopuszczalne są zarówno wyjścia graficzne, jak i ASCII-art.
Jeśli na przykład chcieliśmy stworzyć obraz pikselowanej figury:
# #
###
##
####
#
#### ####
# #
###
# #
# #
Jeśli narysujemy go za pomocą operacji odwracania, takiej jak XOR, można go narysować i usunąć bez względu na to, czy ekran jest czarny, czy biały.
00020261
0 6 661
1 3 561
2 3 461
3 3 661
4 4 461
5 0 361
5 5 861
6 3 361
6 5 561
8 3 561
9 3 361
9 5 561
10 3 361
10 5 561
Powielenie tej sekwencji spowoduje, że postać pojawi się i zniknie.
Większą animację można komponować poza kolejnością, określając różne „strzały” w polu sekwencji.
100 016F0
101 016F0
102 016F0
103 016F0
104 016F0
105 016F0
106 016F0
107 016F0
108 016F0
109 016F0
110 016F0
111 016F0
112 016F0
113 016F0
114 016F0
115 016F0
200020261
2 0 6 661
2 1 3 561
2 2 3 461
2 3 3 661
2 4 4 461
2 5 0 361
2 5 5 861
2 6 3 361
2 6 5 561
2 8 3 561
2 9 3 361
2 9 5 561
210 3 361
210 5 561
00020261
0 6 661
1 3 561
2 3 461
3 3 661
4 4 461
5 0 361
5 5 861
6 3 361
6 5 561
8 3 561
9 3 361
9 5 561
10 3 361
10 5 561
300020261
3 0 6 661
3 1 3 561
3 2 3 461
3 3 3 661
3 4 4 461
3 5 0 361
3 5 5 861
3 6 3 361
3 6 5 561
3 8 3 561
3 9 3 361
3 9 5 561
310 3 361
310 5 561
00020261
0 6 661
1 3 561
2 3 461
3 3 661
4 4 461
5 0 361
5 5 861
6 3 361
6 5 561
8 3 561
9 3 361
9 5 561
10 3 361
10 5 561
Produkcja:
To jest golf golfowy, więc wygrywa najkrótszy program (według liczby bajtów). Premia (-50), jeśli silnik wydaje odgłosy kliknięcia.
źródło
x
koordynacja końcowa jest zawsze włączająca?Odpowiedzi:
Mathematica,
306281 bajtówTo oczekuje, że ciąg wejściowy zostanie zapisany w zmiennej
i
A tutaj z pewnymi odstępami:
To cholernie długo trwało. Wyzwanie to zawierało wiele dziwacznych szczegółów, a zwłaszcza parsowanie danych wejściowych zajmuje dużo kodu w Mathematica (prawie połowa z nich, 137 bajtów, po prostu analizuje dane wejściowe). Skończyłem zmieniać język dwa razy, zanim zdecydowałem się na Mathematica (myślałem, że mogę zaoszczędzić na analizie danych wejściowych za pomocą Ruby, ale potem zdałem sobie sprawę, że wynik musi być animowany , więc wróciłem do Mathematica).
źródło
Przykład Postscript Ungolfed
Jest to program w stylu „protokołu-prologu”, więc dane natychmiast znajdują się w tym samym pliku źródłowym. Animowanych plików GIF mogą być produkowane z ImageMagick za
convert
użytkowego (używa Ghostscript)convert clack.ps clack.gif
.źródło
gs -sDEVICE=bbox clack.ps
.