Przedmowa
Kiedy strzelałem dziś z łucznictwa 900 rundę wcześniej (10 kończy się na 6 strzałach na końcu i 10 kończy się na 3 strzałach na końcu, w sumie 90 strzał i maksymalny wynik 900), pomyślałem o tym wyzwaniu.
W strzelaniu z łuku (zakładając, że strzelasz do tarczy dostarczonej przez FITA [kawałek papieru, do którego strzelasz]), za każdą strzałę możesz zdobyć maksymalną liczbę punktów 10. Tarcza docelowa zawiera 10 lub 11 pierścieni o malejącej średnicy, zagnieżdżone w sobie. Od wewnętrznego pierścienia na zewnątrz są one liczone od 10 punktów do jednego punktu (aw przypadku 11 pierścieni istnieje drugi pierścień wewnętrzny, który liczy się jako „X”, który otrzymuje wynik 10, ale jest stosowany w przypadkach zerwania remisu jako wyższa wartość). Przestrzegać:
Oczywiście mam na myśli punktację FITA Metric, jak widać na powyższej ilustracji. Jeśli przyjrzysz się uważnie, możesz zaobserwować najbardziej wewnętrzny pierścień, który jest wyblakłą przerywaną linią, którego wynik nie jest zaznaczony. To jest „X”, o którym mówiłem, ale nie będziesz musiał tego słuchać, chyba że będziesz walczył o bonus.
Wyzwanie
Utwórz funkcję (lub pełny program, jeśli język nie obsługuje funkcji), który otrzymuje idealnie kwadratowy obraz jako dane wejściowe (lub nazwę pliku obrazu, jeśli to konieczne), zawierający pewną liczbę zieleni (HEX # 00FF00, RGB (0, 255, 0)) kropek o pewnym rozmiarze i zwraca wynik. Obraz może zawierać dane inne niż zielone kropki , ale zielony zawsze będzie miał dokładnie ten sam odcień.
Możesz sobie wyobrazić, że kwadratowy obraz przedstawia twarz docelową, z zewnętrznym pierścieniem dotykającym 4 punktów (górny środek, dolny środek, prawy środek, lewy środek). Reprezentowana powierzchnia docelowa zawsze będzie miała tę samą proporcję, przy czym wszystkie pierścienie będą miały szerokość dokładnie 1/20 szerokości wejściowego obrazu docelowego. Jako przykład, biorąc pod uwagę obraz wejściowy o wymiarach wejściowych 400px na 400px, możesz założyć, że każdy pierścień ma wewnętrzną szerokość 20px, jak pokazano poniżej:
Wyjaśnienia
- Po dotknięciu dwóch oddzielnych pierścieni liczony jest wyższy z dwóch pierścieni
- Nie musisz automatycznie rozliczać się z braków lub przypadku „x”, chyba że próbujesz uzyskać bonus
- Możesz założyć, że żadne zielone kółka się nie pokrywają
- Możesz również założyć, że na obrazie nie ma innych pikseli tego odcienia zieleni
- Obraz będzie w formacie PNG, JPEG lub PPM (do wyboru)
- Zewnętrzne biblioteki przetwarzania obrazu są dozwolone, jeśli zostały utworzone przed opublikowaniem tego pytania
- Możesz założyć, że wszystkie zielone kółka na jednym celu będą miały tę samą średnicę
- Jeśli strzelasz (hah) w celu uzyskania premii za nakładające się koła, możesz założyć, że co najmniej jedno koło na obrazie nie ma innego nakładającego się koła
- Standardowe luki są niedozwolone
Przypadki testowe
Poniższe dwa przypadki powinny uzyskać 52 (lub w przypadku bonusów 52 z 1 'x' i 1 chybcem):
Ten ostatni przypadek testowy powinien uzyskać 25 :
Premia
- -25 bajtów, jeśli również zwrócisz liczbę braków (poza dowolnym pierścieniem)
- -30 bajtów, jeśli zwrócisz również liczbę Xs (załóż, że najbardziej wewnętrzny x to 3/100 szerokości obrazu, a 10 to 2/100 szerokości obrazu. Proporcje 1-9 pozostają niezmienione)
- -35% liczby bajtów, jeśli uwzględnisz nakładające się kręgi
To jest kod golfowy, więc wygrywa najmniej bajtów. Baw się dobrze!
źródło
Odpowiedzi:
Przetwarzanie 2, 448–25 = 423 bajtów
Wczytuje plik obrazu f, który przechodzi przez piksele, aż znajdzie zielony kolor, a następnie zalanie wypełnia okrąg określający punkt, który jest najbliżej środka. Następnie dodaje ten wynik do sumy. jeśli wynik jest ujemny, jest dodawany do licznika braków.
Program wyświetli 2 liczby, pierwsza to wynik, a druga liczba braków.
możesz uzyskać przetwarzanie tutaj
źródło
Perl 5 + GD: 225-25 = 200
Edycja: Znalazłem przyczynę nieprawidłowego odczytu pikseli w zindeksowanych plikach PNG i zastosowałem obejście.
Z jakiegoś powodu w bibliotece GD wartości zielonych pikseli są odczytywane jako (4,254,4). Nie jestem pewien, czy dotyczy to plików PNG zawartych w pytaniu.Podziały linii można usunąć w poniższym kodzie.Pobiera obraz PNG na wejściu i drukuje 2 wartości: Liczba punktów i braków. Na przykład:
Zmiana w ostatniej chwili:
W prawdziwym trybie kolorów, którego i tak potrzebowałem, indeksy kolorów używane
getPixel
ifill
są po prostu liczbami RGB zakodowanymi liczbami całkowitymi, więc nie trzeba używaćrgb
icolorAllocate
konwertować na te indeksy i z nich.Wyjaśnienie:
sub v
którego przeprowadzany jest parametr$_
zamiast parametrów standardowych, ponieważ jest on krótszy).źródło
Haskell -
579-25 = 554603-25-30576-25-30 = 521 bajtówStrategia:
Wyjście jest potrójne (wynik, chybienie, Xs), np
(52,1,1)
Dla obrazu testowego.Program może zawieść, jeśli piksel koła najbliższego środka znajduje się w odległości 3 pikseli od innego koła.
źródło
all id
jest taka sama jak.and
, A także można wdrożyć zaj
pomocą strażników wzorówj n m|PixelRGBA8 0 255 0 _<-getColor n m v=0<1|0<1=0>1
Mathematica -
371386 - 25 = 361Bardziej optymalne rozwiązanie. Oblicza odpowiedź znacznie szybciej niż moje rozwiązanie Python.
Python z PIL - trywialne i nieoptymalne rozwiązanie, 961 bajtów
Jest to po prostu próba wykazania głupiego podejścia do rozwiązania problemu. Uruchomienie dwóch pierwszych przypadków testowych zajmuje ~ 2 minuty, a uruchomienie trzeciego w moim systemie zajmuje ~ 20 minut z powodu szybko wykonanego, strasznie wymagającego zasobów i odpychająco złożonego algorytmicznie detektora okręgu. Mimo to spełnia wymagania, choć z pewnością nie jest optymalnie golfowy. Im więcej zieleni na obrazie, tym dłużej trwa.
Pobiera obiekt obrazu PIL i zwraca wynik.
Kroki, które trzeba podjąć:
n
, jeśli są to zielone piksele, następnie dodaj je do okręguźródło
a
może być zapisana jakoa=lambda x,y,w,h:[(X,Y)for X in(x-1,x,x+1)for Y in(y-1,y,y+1)if w>X>-1<Y<h]