Vorwort
Als ich heute 900 Runden im Bogenschießen geschossen habe (10 endeten bei 6 Pfeilen pro Ende und 10 endeten bei 3 Pfeilen pro Ende, was insgesamt 90 Pfeilen und einer maximalen Punktzahl von 900 entspricht), habe ich an diese Herausforderung gedacht.
Beim Bogenschießen (vorausgesetzt, Sie schießen auf eine von FITA bereitgestellte Zielfläche [das Stück Papier, auf das Sie schießen]) können Sie für jeden Pfeil eine maximale Punktzahl von 10 angeben. Die Zielfläche enthält 10 oder 11 Ringe mit abnehmendem Durchmesser. ineinander verschachtelt. Vom inneren Ring nach außen werden diese von 10 Punkten bis zu einem Punkt gezählt (und im Fall von 11 Ringen gibt es einen sekundären innersten Ring, der als 'X' zählt, der mit 10 bewertet wird, in Fällen, in denen das Binden unterbrochen wird, jedoch als der höhere Wert). Beobachten:
Natürlich beziehe ich mich auf die FITA Metric-Wertung, wie in der obigen Abbildung gezeigt. Wenn Sie genau hinsehen, können Sie den innersten Ring beobachten, bei dem es sich um eine verblasste gepunktete Linie handelt, deren Punktzahl nicht markiert ist. Das ist das 'X', auf das ich mich bezog, aber Sie müssen nicht darauf achten, es sei denn, Sie konkurrieren um den Bonus.
Herausforderung
Erstellen Sie eine Funktion (oder ein vollständiges Programm, wenn die Sprache keine Funktionen unterstützt), die ein perfekt quadratisches Bild als Eingabe (oder ggf. einen Bilddateinamen) mit einer bestimmten Anzahl von Grün (HEX # 00FF00, RGB (0, 255, 0)) Punkte von einiger Größe und gibt die Punktzahl zurück. Das Bild enthält möglicherweise andere Daten als die grünen Punkte , aber das Grün hat immer den exakt gleichen Farbton.
Sie können sich vorstellen, dass das quadratische Bild die Zielfläche darstellt, wobei sich der äußerste Ring an 4 Punkten (oben in der Mitte, unten in der Mitte, rechts in der Mitte, links in der Mitte) berührt. Die dargestellte Zielfläche hat immer das gleiche Verhältnis, wobei alle Ringe eine Breite von genau 1/20 der Breite des eingegebenen Zielbilds haben. Bei einem Eingabebild mit den Eingabeabmessungen 400 x 400 Pixel können Sie beispielsweise davon ausgehen, dass jeder Ring eine innere Breite von 20 Pixel hat, wie im Folgenden dargestellt:
Klarstellungen
- Wenn Sie zwei Ringe berühren, wird der höhere der beiden Ringe gezählt
- Sie müssen nicht automatisch Misses oder den 'x'-Fall berücksichtigen, es sei denn, Sie versuchen, den Bonus zu erhalten
- Sie können davon ausgehen, dass sich keine grünen Kreise überlappen
- Sie können auch davon ausgehen, dass sich keine anderen Pixel dieses Grüntons im Bild befinden
- Das Bild ist entweder im PNG-, JPEG- oder PPM-Format (nach Wahl).
- Externe Bildbearbeitungsbibliotheken sind zulässig, wenn sie vor dem Absenden dieser Frage erstellt wurden
- Sie können davon ausgehen, dass alle grünen Kreise auf einem Ziel den gleichen Durchmesser haben
- Wenn Sie für den Bonus für überlappende Kreise schießen (hah), können Sie davon ausgehen, dass mindestens ein Kreis im Bild keine weitere Überlappung aufweist
- Standardlücken sind nicht zulässig
Testfälle
In den folgenden beiden Fällen sollten jeweils 52 Punkte erzielt werden (oder bei Boni 52 mit 1 "x" und 1 "verfehlt"):
Und dieser letzte Testfall sollte 25 Punkte bringen :
Bonus
- -25 Bytes, wenn Sie auch die Anzahl der Fehler (außerhalb eines der Ringe) zurückgeben
- -30 Bytes, wenn Sie auch die Menge der Xs zurückgeben (angenommen, dass das innerste x 3 / 100stel der Breite des Bildes und 10 dann 2 / 100stel der Breite des Bildes beträgt. Die Proportionen 1-9 bleiben unverändert)
- -35% Byteanzahl, wenn Sie überlappende Kreise berücksichtigen
Dies ist Codegolf, also gewinnt das kleinste Byte. Habe Spaß!
quelle
Antworten:
Verarbeitung 2, 448-25 = 423 Bytes
Liest eine Bilddatei ein f durchläuft die Pixel, bis sie grün sind, und füllt dann den Kreis, um den Punkt zu bestimmen, der der Mitte am nächsten liegt. Addiert dann diese Punktzahl zu einer Gesamtsumme. Wenn die Punktzahl negativ ist, wird sie einem Fehlerzähler hinzugefügt.
Das Programm gibt 2 Zahlen aus, wobei die erste die Punktzahl und die zweite die Anzahl der Fehler ist.
Sie können erhalten die Verarbeitung hier
quelle
Perl 5 + GD: 225 - 25 = 200
Bearbeiten: Ermittelte den Grund für das fehlerhafte Lesen von Pixeln in indizierten PNGs und führte eine Problemumgehung durch.
Aus irgendeinem Grund werden bei der GD-Bibliothek die grünen Pixelwerte als (4.254,4) gelesen. Ich bin nicht sicher, ob dies spezifisch für die in der Frage enthaltenen PNG-Dateien ist.Zeilenumbrüche können im folgenden Code entfernt werden.Nimmt ein PNG-Bild in die Eingabe auf und druckt 2 Werte: Anzahl der Punkte und Fehler. Beispielsweise:
Last Minute Änderung:
Im Echtfarben-Modus brauchte ich sowieso die von
getPixel
und verwendeten Farbindizesfill
sind einfach ganzzahlig codierte RGB-Werte, so dass es nicht erforderlich ist, diese Indizes zu verwendenrgb
undcolorAllocate
zu diesen zu konvertieren.Erläuterung:
sub v
Parameter$_
anstelle von Standardparametern, da sie kürzer sind).quelle
Haskell -
579-25 = 554603-25-30576-25-30 = 521 BytesStrategie:
Die Ausgabe ist ein Triple (Score, Misses, Xs), z
(52,1,1)
für das Testbild.Das Programm schlägt möglicherweise fehl, wenn sich das Pixel eines Kreises, der dem Zentrum am nächsten liegt, innerhalb von 3 Pixeln eines anderen Kreises befindet.
quelle
all id
ist das gleiche wieand
.auchj
mit Pattern Guardsj n m|PixelRGBA8 0 255 0 _<-getColor n m v=0<1|0<1=0>1
Mathematica -
371386 - 25 = 361Eine optimalere Lösung. Berechnet die Antwort viel schneller als meine Python-Lösung.
Python mit PIL - Eine triviale und nicht optimale Lösung, 961 Bytes
Dies ist einfach zu versuchen, einen dummen Ansatz bei der Lösung des Problems zu demonstrieren. Es dauert ca. 2 Minuten, um die ersten beiden Testfälle auszuführen, und ca. 20 Minuten, um den dritten Testfall auf meinem System auszuführen, da der Kreisdetektor schnell aufgebaut, schrecklich ressourcenintensiv und abstoßend algorithmisch komplex ist. Trotzdem erfüllt es die Anforderungen, obwohl es sicherlich nicht optimal golfen kann. Je grüner das Bild ist, desto länger dauert die Ausführung.
Nimmt ein PIL-Bildobjekt und gibt die Punktzahl zurück.
Schritte, die es braucht:
n
. Falls es sich um grüne Pixel handelt, fügen Sie diese dem Kreis hinzuquelle
a
kann geschrieben werdena=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]