Mit Algodoo und Paint habe ich diese sechs monochromen 300 × 300-Bilder in vier praktischen Formen erstellt:
Diese Bildklasse weist die folgenden Eigenschaften auf:
- Sie sind immer 300 × 300 Pixel, einfarbig (nur Schwarzweiß) und haben genau vier weiße Bereiche, die einem Quadrat, einem Kreis, einem Dreieck und einem Zahnrad entsprechen.
- Die Formen überlappen sich nie und berühren sich auch nicht. Sie berühren auch nicht den Bildrand oder überschreiten Grenzen.
- Die Formen haben immer die gleiche Größe, können jedoch gedreht und beliebig positioniert werden.
(Die Formen haben auch gleiche Flächen, wenn sie jedoch so gerastert werden, ist es unwahrscheinlich, dass ihre Pixelanzahl genau gleich ist.)
Herausforderung
Schreiben Sie das kürzeste Programm oder die kürzeste Funktion, die den Dateinamen eines solchen Bildes aufnimmt und alle weißen Pixel umdreht ...
- rot,
(255, 0, 0)
wenn sie auf dem Platz sind. - blau,
(0, 0, 255)
wenn sie im Kreis sind. - grün,
(0, 255, 0)
wenn sie im Dreieck sind. - gelb,
(255, 255, 0)
wenn sie im Gang sind.
z.B
Einzelheiten
Ihr Programm sollte für alle möglichen Eingabebilder effektiv funktionieren. (Es werden nur gültige einfarbige 300 × 300-Bilder eingegeben.) Die sechs von mir bereitgestellten Bilder sind lediglich Beispiele. Sie können die Ausgabe möglicherweise nicht fest in Ihr Programm einprogrammieren.
Sie dürfen keine integrierten oder externen Computer Vision-Bibliotheken oder -Funktionen verwenden. Der Punkt ist, dies unter Verwendung Ihrer eigenen Operationen auf Pixelebene zu tun. Sie können Bildbibliotheken verwenden, mit denen Sie einfach Bilder öffnen und ändern können (z. B. PIL für Python).
Sie können alle gängigen verlustfreien Bilddateiformate für die Eingabe und Ausgabe verwenden, solange Sie sich an das Farbschema halten.
Sie können den Bilddateinamen als Funktionsargument von stdin oder über die Befehlszeile eingeben. Das Ausgabebild kann in einer neuen Datei oder derselben Datei gespeichert oder einfach angezeigt werden.
Wertung
Die Einsendung mit den wenigsten Bytes gewinnt. Ich kann Einsendungen mit zusätzlichen Bildern testen, um ihre Gültigkeit zu bestimmen.
quelle
Antworten:
J -
246,224185 BytesDas war ein Spaß!
Ich habe den Teil für verbundene Komponenten, den ich für die Herausforderung "Bin ich im größten Raum" verwendet habe , erneut verwendet und das Verhältnis zwischen durchschnittlichem und maximalem Abstand aller Punkte zum Mittelpunkt jeder Komponente verwendet. Ich habe mich damit abgefunden, da es sowohl skalierungs- als auch rotationsunabhängig ist und anscheinend gut genug ist, um zwischen den angegebenen Formen zu unterscheiden. Wenn ich diesen Wert von niedrig nach hoch ordne, erhalte ich den Ordnungskreis, das Zahnrad, das Quadrat und das Dreieck, mit denen die Farbkarte permutiert wird.
Zeigt das Ergebnis mit dem viewmap-Addon an. Keine Toolboxen außer zum Lesen und Ausgeben von Dateien.
Robustheit scheint keine Voraussetzung zu sein, dafür werden 18 Bytes benötigt. 2 weitere unnötige Bereiche sind, ersetzt
&.>
durch&>
inratio
und&.:
durch&:
in dcent für weitere 2 Byte.Enormer Gewinn an Kürze und Leistung bei der
comp
Verwendung von Shifting anstelle voncut
(;.
). Auf diese Weise wird das Bild repliziert und in alle 8 Richtungen verschoben, anstatt es mit einem 3x3-Fenster zu scannen.Die
id
Funktion war für das, was sie tun musste, lächerlich komplex. Jetzt werden den Pixeln in Objekten IDs zugewiesen, indem das Bild mit einer Reihe eindeutiger Zahlen multipliziert wird, wodurch der Hintergrund auf Null gesetzt wird.Code etwas genauer erklärt:
Dieser ist ein bisschen lang, um im Detail zu erklären, wird aber tun, wenn es Interesse gibt.
quelle
Mathematica,
459392 BytesUngolfed:
Ich konnte 6 weiteres Bytes speichern , indem
m=1.Mean@a;m=#-m&/@a;
inm=#-Mean@a&/@a;
, aber das sprengt deutlich Ausführungszeit auf, die für die Prüfung ärgerlich. (Beachten Sie, dass dies zwei Optimierungen sind: Herausziehen der BerechnungMean@a
aus der Schleife und Verwenden exakter Symboltypen anstelle von Gleitkommazahlen. Interessanterweise ist die Verwendung exakter Typen viel wichtiger als die Berechnung des Mittelwerts in jeder Iteration.)Das ist also Ansatz Nummer drei:
Zeichnen wir nun für alle Pixel in der Form den Abstand von vs Winkel zu diesem Mittelpunkt:
Das Dreieck hat 3 klare Maxima, das Quadrat 4, das Zahnrad 16 und der Kreis hat Tonnen aufgrund von Aliasing-Schwankungen um den konstanten Radius.
150
das Maximum ist.Nur zur Veranschaulichung, wenn ich Ell's Idee verwende und die Regionen einfach nach dem größten Abstand zwischen einem Pixel und der Mitte sortiere, kann ich dies in 342 Bytes tun:
Aber ich habe nicht vor, damit zu konkurrieren, solange alle anderen ihre eigenen Originalalgorithmen verwenden, anstatt die der anderen herunterzuspielen.
quelle
Java,
1204113210871076Nur um mir selbst zu beweisen, dass ich das kann.
Ich habe Importe direkt neben den Funktionsdeklarationen eingefügt. Diese müssten außerhalb der Klasse sein, damit dies funktioniert:
Ungolfed (und runnable; dh Boilerplate hinzugefügt):
Dies funktioniert, indem jedes Pixel des Bildes durchlaufen wird und jedes Mal, wenn wir ein "Loch" erreichen, eine Überflutung erfolgt. Wir addieren jedes Füllergebnis als a
Set<Point>
zu aSet
. Dann bestimmen wir, welche Form welche ist. Dies erfolgt durch Betrachten der Anzahl der Grenzpixel der Form. Ich definierte die Grenze als eine Bewegung eines Ritters weg von einem schwarzen Plättchen, da dies zwischen Rotationen und dergleichen konstanter bleiben würde. Wenn wir dies tun, wird klar, dass die Formen nach diesem Wert sortiert werden können: Kreis, Quadrat, Dreieck, Zahnrad. Also sortiere und setze ich alle Pixel dieser Form auf die richtige Farbe.Beachten Sie, dass das Bild, auf das ich schreibe, nicht direkt aus der Datei stammt. In diesem Fall würde Java das Bild als schwarzweiß behandeln und das Füllen mit Farben würde nicht funktionieren. Also muss ich mit
TYPE_INT_RGB
(was ist1
) mein eigenes Image erstellen . Beachten Sie auch, dass das Bild, an dem ich arbeite,302
von stammt302
. Auf diese Weise muss sich der Abstandsalgorithmus des Ritters keine Gedanken darüber machen, ob das Bild außerhalb der Grenzen gelesen werden soll. Diese Größenabweichung behebe ich durch einen Anrufi.getSubImage(1,1,300,300)
. Hinweis: Ich habe möglicherweise vergessen, dies zu beheben, als ich die Bilder hochgeladen habe. In diesem Fall sind die Bilder 2 Pixel zu breit, aber bis auf diese Tatsache sollten sie korrekt seinDie Funktion überschreibt die Datei, deren Pfad übergeben wird.
quelle
Python,
571 567528 BytesÄhnlich wie bei der Lösung von Quincunx wird zunächst jede Form mit einem Index von 1 bis 4 gefüllt. Anschließend wird die Identität der Formen anhand des Radius ihres Begrenzungskreises bestimmt. Entsprechend wird eine Farbpalette erstellt und das Bild als indiziertes Farbbild gespeichert.
BEARBEITEN: Die Tatsache, dass die Formen den Bildrand garantiert nicht berühren, wurde übersehen. Kürzer ist es dann!
Nimmt einen Eingabedateinamen in die Befehlszeile und schreibt die Ausgabe in
o.png
.quelle
Mathematica 225
Update :
Das OP entschied, dass dieser Ansatz Computer-Vision-Funktionen verwendet, sodass er nicht mehr läuft. Ich lasse es aber gepostet. Vielleicht findet es jemand von Interesse.
ImageData
Gibt das Bild als Matrix aus Nullen und Einsen zurück.Flatten
wandelt diese Matrix in eine Liste um.Morphological Components
Findet die 4 Cluster von Pixeln und weist jedem Pixel je nach Cluster eine bestimmte Ganzzahl, 1, 2, 3, 4, zu. 0 ist für den (schwarzen) Hintergrund reserviert.ComponentMeasurements
testet die Zirkularität der Cluster.Am wenigsten kreisförmig wird es immer sein: der Kreis, das Quadrat, das Dreieck und das Zahnrad.
ReplacePart
Ersetzt jede ganzzahlige Komponente durch die jeweilige RGB-Farbe unter Verwendung der Zirkularitätssortierung.Partition...Dimensions[m][[2]]
Nimmt die Liste der Pixelfarben und gibt eine Matrix mit den gleichen Abmessungen wie das Eingabebild zurück.Image
wandelt die Matrix der Pixelfarben in ein Farbbild um.quelle
f@i_:=Image[#/.Append[Thread[Ordering[Last/@ComponentMeasurements[#,"Circularity"]]->{Yellow,Green,Red,Blue}],0->Black]]&@MorphologicalComponents@i
{RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1], RGBColor[1, 1, 0]}
:, wobei 1 255 entspricht. Es wurden keine Bibliotheken verwendet.MorphologicalComponents
Ihre Regeln erfüllt oder verletzt. Sobald man weiß, zu welchem Cluster jedes Pixel gehört, gibt es viele Möglichkeiten, einschließlich einer unformatierten Anzahl von Pixeln, um zu bestimmen, welche Figur welche ist.(255,0,22)
wenn ich Paint einchecke). Ich habe kein Mathematica, kann also nicht rennen, um sicherzugehen.Mathematica,
354345314291288Noch Golfspielen, könnte durch ein paar Zeichen mehr verkürzt werden, aber die Leistung wird unerträglich. Verwendet die Varianz, um Formen zu identifizieren:
Mit Abstand:
Testen:
Hier ist es völlig ungolfed. Füge später Erklärungen hinzu:
quelle
Python,
579577554514502501 BytesFüllen Sie jede Form mit einer Überflutung und berechnen Sie dann den Abstand zwischen dem Schwerpunkt und dem entferntesten Punkt.
dann wird die reale Oberfläche der Form mit der Oberfläche eines Dreiecks, Quadrats, einer Scheibe oder eines Rads verglichen, die die gleiche Größe haben würden.
quelle
C # 1086 Bytes
Noch eine Floodfill-Lösung, nur zur Veranschaulichung, da es hier keine C # -Version gibt. Wie Quincunx wollte ich mich beweisen, dass ich es kann und es gibt keinen großen Unterschied zu seiner Vorgehensweise in Java.
Es akzeptiert jedes Bildformat.
Es kann wahrscheinlich ein paar Zeichen entfernt werden, indem das gesamte statische Material entfernt und eine Instanz von Program erstellt wird.
Lesbare Version:
Golf gespielt:
quelle