Mathematica, 100%, 141 Bytes
f@x_:=Count[1>0]@Table[ImageInstanceQ[x,"caprine animal",RecognitionThreshold->i/100],{i,0,50}];If[f@#>f@ImageReflect@#,"Up","Down"]<>"goat"&
Nun, das fühlt sich mehr als ein bisschen nach Schummeln an. Es ist auch unglaublich langsam und sehr albern. Die Funktion ermittelt f
ungefähr, wie hoch Sie den Erkennungsschwellenwert in einer der in Mathematica integrierten Funktionen für die Computervision einstellen können, und erkennt das Bild dennoch als Ziegentier.
Wir sehen dann, ob das Bild oder das gespiegelte Bild zickiger ist. Funktioniert nur mit Ihrem Profilbild, da die Krawatte zugunsten von Downgoat unterbrochen ist. Es gibt wahrscheinlich eine Menge Möglichkeiten, wie dies verbessert werden könnte, einschließlich der Frage, ob das Bild Bovids oder andere Verallgemeinerungen des Entitätstyps Caprine darstellt.
Die schriftliche Beantwortung ergibt 100% für den ersten Testsatz und 94% für den zweiten Testsatz, da der Algorithmus für Ziege 1 ein nicht schlüssiges Ergebnis liefert. Dies kann auf Kosten einer noch längeren Rechenzeit von auf 100% zurückgesetzt werden Testen Sie mehr Werte von RecognitionThreshold
. Auferwecken von 100
zu 1000
genügen; Aus irgendeinem Grund glaubt Mathematica, dass dies ein sehr schlechtes Bild ist! Es scheint auch zu funktionieren, die Erkennungsentität von Ziegen- zu Hufsäugetier zu ändern.
Ungolfed:
goatness[image_] := Count[
Table[
ImageInstanceQ[
image, Entity["Concept", "CaprineAnimal::4p79r"],
RecognitionThreshold -> threshold
],
{threshold, 0, 0.5, 0.01}
],
True
]
Function[{image},
StringJoin[
If[goatness[image] > goatness[ImageReflect[image]],
"Up",
"Down"
],
"goat"
]
]
Alternative Lösung, 100% + Bonus
g[t_][i_] := ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]
f[i_, l_: 0, u_: 1] := Module[{m = (2 l + u)/3, r},
r = g[m] /@ {i, ImageReflect@i};
If[Equal @@ r,
If[First@r, f[i, m, u], f[i, l, m]],
If[First@r, "Up", "Down"] <> "goat"
]
]
Dieser verwendet die gleiche Strategie wie zuvor, jedoch mit einer binären Suche über dem Schwellenwert. Hierbei handelt es sich um zwei Funktionen:
g[t]
Gibt zurück, ob es sich bei dem Argument um ein Ziegenbild mit Schwellenwert handelt t
.
f
Es werden drei Parameter verwendet: ein Bild und eine obere und untere Grenze für den Schwellenwert. Es ist rekursiv; Dies funktioniert durch Testen eines Schwellenwerts m
zwischen dem oberen und dem unteren Schwellenwert (nach unten gerichtet). Wenn das Bild und das reflektierte Bild sowohl ziegenartig als auch nicht ziegenartig sind, wird der untere oder obere Teil des Bereichs entsprechend entfernt und erneut aufgerufen. Wenn andernfalls ein Bild ziegenartig und das andere nicht ziegenartig ist, wird es zurückgegeben, Upgoat
wenn das erste Bild ziegenartig ist, und Downgoat
ansonsten (wenn das zweite, reflektierte Bild ziegenartig ist).
Die Funktionsdefinitionen verdienen eine kleine Erklärung. Erstens ist die Funktionsanwendung linksassoziativ. Dies bedeutet, dass so etwas g[x][y]
interpretiert wird als (g[x])[y]
; "das Ergebnis g[x]
angewendet auf y
."
Zweitens entspricht die Zuweisung in Mathematica in etwa der Definition einer Ersetzungsregel. Dies f[x_] := x^2
bedeutet nicht , dass eine Funktion f
mit dem Parameter deklariert wird x
, der zurückgibt x^2
. Seine Bedeutung ist näher dran: "Wenn du etwas siehst f[ ... ]
, rufe das Ding in dir auf x
und ersetze das Ganze durch x^2
."
Wenn wir diese beiden zusammenfassen, sehen wir, dass die Definition von g
Mathematica anweist, jeden Ausdruck des Formulars (g[ ... ])[ ... ]
durch die rechte Seite der Zuweisung zu ersetzen .
Wenn Mathematica auf den Ausdruck g[m]
(in der zweiten Zeile von f
) stößt , stellt es fest, dass der Ausdruck keinen bekannten Regeln entspricht, und lässt ihn unverändert. Dann entspricht es dem Map
Operator /@
, dessen Argumente g[m]
und die Liste sind {i, ImageReflect@i}
. ( /@
Ist eine Infixnotation; dieser Ausdruck ist genau gleichbedeutend mit Map[g[m], { ... }]
.) Das Map
wird ersetzt, indem das erste Argument auf jedes Element des zweiten Arguments angewendet wird {(g[m])[i], (g[m])[ ... ]}
. Jetzt sieht Mathematica, dass jedes Element der Definition von entspricht g
und ersetzt.
Auf diese Weise müssen wir uns g
wie eine Funktion verhalten, die eine andere Funktion zurückgibt. Das heißt, es verhält sich ungefähr so, wie wir es geschrieben haben:
g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]
(Ausgenommen in diesem Fall g[t]
ergibt sich für sich alleine eine Function
, während zuvor g[t]
für sich alleine überhaupt keine Transformation erfolgte.)
Der letzte Trick, den ich benutze, ist ein optionales Muster. Das Muster l_ : 0
bedeutet "Jedem Ausdruck l
zuordnen und 0
als verfügbar machen oder nichts zuordnen und als verfügbar machen l
". Wenn Sie also f[i]
mit einem Argument (dem zu testenden Bild) aufrufen , ist dies so, als hätten Sie angerufen f[i, 0, 1]
.
Hier ist das Testgeschirr, das ich verwendet habe:
gist = Import["https://api.github.com/gists/3fb94bfaa7364ccdd8e2", "JSON"];
{names, urls} = Transpose[{"filename", "raw_url"} /. Last /@ ("files" /. gist)];
images = Import /@ urls;
result = f /@ images
Tally@MapThread[StringContainsQ[##, IgnoreCase -> True] &, {names, result}]
(* {{True, 18}} *)
user = "items" /.
Import["https://api.stackexchange.com/2.2/users/40695?site=codegolf", "JSON"];
pic = Import[First["profile_image" /. user]];
name = First["display_name" /. user];
name == f@pic
(* True *)