Zadanie polega na znalezieniu sposobu na narysowanie linii poziomej w szeregu 16-bitowych liczb całkowitych.
Przyjmujemy tablicę 256 x 192 pikseli z 16 pikselami na słowo. Linia to ciągły ciąg setów (1) bitów. Linie mogą rozpoczynać się w środku dowolnego słowa, nakładać się na inne słowa i kończyć się dowolnym słowem; mogą również zaczynać się i kończyć tym samym słowem. Nie mogą się zawijać do następnej linii. Wskazówka: środkowe słowa są łatwe - po prostu napisz 0xffff, ale krawędzie będą trudne, podobnie jak obsługa przypadku na początku i na końcu tego samego słowa. Funkcja / procedura / procedura musi przyjmować współrzędne x0 i x1 wskazujące poziome punkty początkowe i końcowe, a także współrzędne y.
Wykluczam się z tego, ponieważ sam zaprojektowałem prawie identyczny algorytm dla wbudowanego procesora, ale jestem ciekawy, jak inni by to zrobili. Punkty bonusowe za użycie stosunkowo szybkich operacji (na przykład 64-bitowa operacja zwielokrotnienia lub operacja zmiennoprzecinkowa nie byłaby szybka na wbudowanej maszynie, ale wystarczyłaby zwykła zmiana bitów.)
źródło
Odpowiedzi:
Ten kod zakłada, że zarówno x0, jak i x1 są włączającymi punktami końcowymi i że słowa są małymi endianami (tzn. Piksel (0,0) można ustawić za pomocą
array[0][0]|=1
).źródło
Pyton
Główną sztuczką jest tutaj użycie tabeli odnośników do przechowywania masek bitowych pikseli. Oszczędza to kilka operacji. Tabela 1kB nie jest obecnie tak duża nawet dla wbudowanej platformy
Jeśli przestrzeń jest naprawdę ograniczona, za cenę kilku & 0xf tabelę wyszukiwania można zmniejszyć do zaledwie 64B
Ten kod jest w języku Python, ale można go łatwo przenieść na dowolny język obsługujący operacje bitowe.
W przypadku korzystania z C, można rozważyć odwijania pętlę używając
switch
z urządzeniem Duffa . Ponieważ linia ma maksymalnie 16 słów, przedłużyłbymswitch
do 14 linii i zrezygnowałbym zwhile
całości.źródło
Oto wersja C mojej odpowiedzi w języku Python przy użyciu instrukcji switch zamiast pętli while i zmniejszonego indeksowania poprzez zwiększenie wskaźnika zamiast indeksu tablicy
Rozmiar tabeli odnośników można znacznie zmniejszyć, używając T [x1 i 0xf] i U [x2 i 0xf] dla kilku dodatkowych instrukcji
źródło
Scala,
linie 7s / 1M linie4,1s / 1Mpierwsze wdrożenie:
Po wyeliminowaniu wewnętrznego wywołania metody i zamianie for na pętlę while, na moim 2Ghz Single Core Scala 2.8 zwalnia 1 Mio. Linie w 4.1 sek. zamiast początkowych 7.
Kod testowy i wywołanie:
Test wydajności:
Testowany przy użyciu czasu narzędzia uniksowego, porównując czas użytkownika, w tym czas uruchomienia, skompilowany kod, brak fazy rozruchu JVM.
Zwiększenie liczby wierszy pokazuje, że na każdy nowy milion potrzeba dodatkowych 3.3s.
źródło