Joe wąż jest głodny.
On je zdjęcia, jeden piksel na raz.
On naprawdę lubi jasne piksele.
Wyzwanie
Zaprogramuj Joe, aby zjadał najjaśniejsze piksele, jakie może znaleźć, biorąc pod uwagę, że może poruszać się tylko w górę, w dół, w lewo lub w prawo.
Dane techniczne
- Joe musi zacząć od lewego górnego piksela obrazu.
- Joe może poruszać się tylko w poziomie lub w pionie o 1 każdy ruch
- Joe ma tylko wystarczająco dużo czasu, aby przenieść 1/3 liczby pikseli na zdjęciu (1/3 tyle ruchów co pikseli). Jeśli liczba pikseli nie jest wielokrotnością 3, zaokrąglij w dół do najbliższej liczby całkowitej.
- Joe może przekroczyć swoją ścieżkę, ale liczy się to jako 0 jasność
- Jasność opiera się na sumie r, gib, więc rgb (0,0,0) ma jasność 0, a rgb (255,255,255) ma maksymalną jasność.
Wkład
Możesz wprowadzić obraz, jak chcesz.
Wydajność
- obraz przedstawiający wynik końcowy twojego zdjęcia (z czarnymi pikselami zjadanymi).
- Ilość zjedzonej jasności (proszę podać zakres w odpowiedzi)
Punktacja
Twój program będzie oceniany na:
- Średnia jasność pikseli Joe je / Średnia jasność pikseli na obrazie *
* możesz to zakodować na stałe w swoim programie
Twój całkowity wynik będzie średnią wyników dla następujących zdjęć:
Testuj obrazy:
http://upload.wikimedia.org/wikipedia/en/thumb/f/f4/The_Scream.jpg/800px-The_Scream.jpg
code-challenge
image-processing
Stretch Maniac
źródło
źródło
[![image description](SE URL for downsized image)](URL for original image)
.Odpowiedzi:
C ++, wynik:
1.420421,46766Jest to zasadniczo nieco bardziej wyrafinowana wersja dwóch istniejących rozwiązań: spośród czterech możliwych ruchów wybiera ten, który maksymalizuje jasność. Jednak zamiast patrzeć tylko na jasność piksela docelowego, patrzy na ważoną sumę jasności pikseli w sąsiedztwie piksela docelowego, gdzie piksele bliżej celu mają większą wagę.
EDYCJA: Zastosowanie nieliniowej jasności w obliczeniach sąsiedztwa poprawia nieznacznie wynik.
Kompiluj z
g++ joe.cpp -ojoe -std=c++11 -O3 -lcairo
. Wymaga Cairo.Uruchom z
joe <image-file> [<radius>]
.<image-file>
to wejściowy obraz PNG.<radius>
(opcjonalny argument) to promień zsumowanego sąsiedztwa, w pikselach (mniejszy jest szybszy, większy jest (z grubsza) lepszy.) Wyprowadza wynik i nazwany obrazout.<image-file>
.Wyniki
Więcej słodyczy
źródło
if (o_neighborhood > o_max_neighborhood) o_max = *o, o_max_neighborhood = o_neighborhood;
tylko ten kod go ustawia. jednak ze względu na zaangażowane nan porównanie jest zawsze fałszywe, dlatego o_max nigdy nie jest ustawiane i używane w sposób niezainicjowany.Python 3, wynik = 1,57
Najpierw nasz wąż podróżuje po obrazie, tworząc pionowe linie w równej odległości od siebie.
Możemy rozszerzyć tego węża, biorąc dwa punkty obok siebie w linii pionowej i tworząc pętlę, której punktami końcowymi są one.
Organizujemy punkty w pary i dla każdej pary przechowujemy rozmiar i średnią wartość jasności pętli, która daje największą średnią jasność.
Na każdym kroku wybieramy parę z najwyższą wartością przedłużenia pętli, aby osiągnąć maksymalną średnią jasność na przedłużeniu i obliczamy nowy optymalny rozmiar pętli i wartość jasności dla pary.
Przechowujemy trojaczki (wartość, rozmiar, para_punkt) w strukturze sterty posortowanej według wartości, dzięki czemu możemy usunąć największy element (w O (1)) i wydajnie dodać nowy zmodyfikowany (w O (log n)).
Zatrzymujemy się, gdy osiągniemy limit liczby pikseli, a ten wąż będzie ostatnim wężem.
Odległość między pionowymi liniami ma bardzo niewielki wpływ na wyniki, dlatego wybrano stałą 40 pikseli.
Wyniki
Uwaga: oryginalne zdjęcie „Krzyk” nie było dostępne, więc użyłem innego obrazu „Krzyk” o podobnej rozdzielczości.
Gif przedstawiający proces rozciągania węża na obrazie „wirowania”:
Kod pobiera jedną (lub więcej oddzielonych spacjami) nazwę pliku ze standardowego wejścia i zapisuje powstałe obrazy węża do plików png i drukuje wyniki na standardowe wyjście.
źródło
Python 2 (wynik: 0,0797116)
Po prostu bardzo prosty i naiwny chciwy algorytm, aby uruchomić piłkę.
Wydajność:
źródło
sum of brightnesses of eaten pixels / amount of eaten pixels
czy właściwa formuła, prawda? Może to po prostu straszny algorytm;)The average brightness of pixels Joe eats / The average brightness of the pixels in the picture*
Java (wynik: 0,6949)
Prosty algorytm, który zjada najjaśniejszy piksel z czterech pikseli otaczających aktualny piksel. W przypadku remisu zjedzony piksel jest losowy, co prowadzi do różnych wyników i obrazów wynikowych przy każdym wykonaniu. Jako takie, poniższe wyniki są średnimi z ponad 50 wykonań na każdym obrazie.
Aby go uruchomić, albo edytuj trzy argumenty (istniejące jako stałe klasy) w źródle lub przekaż je za pomocą wiersza poleceń w postaci, w
java HungryImageSnake <source> <iterations> <printScores>
której<source>
znajduje się plik źródłowy obrazu do zjedzenia,<iterations>
czyli ile razy zjesz obraz (biorąc średni wynik i zapisanie najlepszego wyniku ze wszystkich iteracji), i<printScores>
prawdą jest wydrukowanie wyniku każdej iteracji lub fałsz, aby nie.Średnie wyniki, według obrazu, z ponad pięćdziesięciu iteracji:
Najlepsze wyniki, według obrazu, z tych samych pięćdziesięciu iteracji:
Obrazy z najwyższą liczbą punktów:
Jak widać na zdjęciach, w rzeczywistości zjadana jest znacznie mniej niż jedna trzecia pikseli, ponieważ wąż czasami utknął wśród pikseli, które już zjadł, w których utknął w martwym obszarze, dopóki losowość jego ruchów nie doprowadzi do jadalna część obrazu.
Również w wyniku ponownego zjadania pikseli przez węża wyniki są tendencyjne w dół, ponieważ zerowa jasność martwych pikseli jest ponownie uwzględniana w średniej. Oczekiwałbym, że zobaczę znacznie wyższe wyniki, gdyby zmodyfikowano algorytm oceniania, aby podzielić tylko liczbę ruchów, które doprowadziły do zjedzenia nowych pikseli, a nie wszystkie ruchy (w tym te, w których wąż zjada martwy piksel, który zjadł wcześniej ).
Oczywiście lepszym rozwiązaniem byłoby stworzenie heurystycznego poziomu jasności dla każdego piksela i znalezienie ścieżki
width * height / 3
pikseli o najwyższej średniej jasności, ale wątpię, aby to podejście było optymalne w czasie wykonywania, szczególnie na większych obrazach, ponieważ liczba możliwych permutacji byłby bardzo duży. Mogę później wypróbować jakąś formę tego podejścia i opublikować ją w osobnej odpowiedzi, jeśli tak.źródło
Python 2, wynik: 1,205
Jakiś czas temu przygotowałem szybkie rozwiązanie Python, ale zapomniałem je opublikować. Oto jest Znajduje najbogatsze bloki na obrazie, a następnie podróżuje do każdego bloku, zjadając wszystkie najlepsze bloki, do których dochodzi.
Wyniki
Przykładowe zdjęcie
Kod Python 2.7
źródło