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"&
Bueno, esto se siente más que un poco como hacer trampa. También es increíblemente lento, además de ser muy tonto. La función fve aproximadamente qué tan alto puede establecer el umbral de Reconocimiento en una de las funciones de visión por computadora de Mathematica, y aún así reconocer la imagen como un animal Caprino.
Luego vemos si la imagen o la imagen volteada es más caprichosa. Funciona en su imagen de perfil solo porque el empate está roto a favor de downgoat. Probablemente hay muchas formas en que esto podría mejorarse, incluida la pregunta si la imagen representa Bovids u otras generalizaciones del tipo de entidad animal Caprino.
Responda como puntajes escritos 100% para el primer conjunto de pruebas y 94% para el segundo conjunto de pruebas, ya que el algoritmo arroja un resultado no concluyente para la cabra 1. Esto puede elevarse hasta el 100% a expensas de un tiempo de cálculo aún más largo probando más valores de RecognitionThreshold. Subiendo de 100a 1000suficientes; ¡Por alguna razón, Mathematica piensa que es una imagen muy desagradable! Cambiar la entidad de reconocimiento de Caprine animal a Hoofed Mammal también parece funcionar.
Sin golf:
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"
]
]
Solución alternativa, 100% + bonificación
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"
]
]
Éste usa la misma estrategia que antes, pero con una búsqueda binaria por encima del umbral. Aquí hay dos funciones involucradas:
g[t]devuelve si su argumento es o no una imagen caprichosa con umbral t.
ftoma tres parámetros: una imagen y un límite superior e inferior en el umbral. Es recursivo; funciona probando un umbral mentre los umbrales superior e inferior (sesgado hacia el inferior). Si la imagen y la imagen reflejada son caprichosas o no caprichosas, elimina la parte inferior o superior del rango según corresponda y se llama a sí misma nuevamente. De lo contrario, si una imagen es caprichosa y la otra no es caprichosa, regresa Upgoatsi la primera imagen es caprichosa y de lo Downgoatcontrario (si la segunda imagen reflejada es caprichosa).
Las definiciones de funciones merecen una pequeña explicación. Primero, la aplicación de la función es asociativa a la izquierda. Esto significa que algo así g[x][y]se interpreta como (g[x])[y]; "el resultado de g[x]aplicado a y".
Segundo, la asignación en Mathematica es más o menos equivalente a definir una regla de reemplazo. Es decir, f[x_] := x^2no , no significa "declarar una función llamada fcon el parámetro xque devuelve x^2;" su significado está más cerca de "cuando veas algo así f[ ... ], llama a la cosa que está adentro xy reemplaza todo con x^2".
Al poner estos dos juntos, podemos ver que la definición de ges decirle a Mathematica que reemplace cualquier expresión de la forma (g[ ... ])[ ... ]con el lado derecho de la tarea.
Cuando Mathematica encuentra la expresión g[m](en la segunda línea de f), ve que la expresión no coincide con ninguna regla que conozca y la deja sin cambios. Luego coincide con el Mapoperador /@, cuyos argumentos son g[m]y la lista {i, ImageReflect@i}. ( /@es notación infija; esta expresión es exactamente equivalente a Map[g[m], { ... }]). El Mapse reemplaza aplicando su primer argumento a cada elemento de su segundo argumento, por lo que obtenemos {(g[m])[i], (g[m])[ ... ]}. Ahora Mathematica ve que cada elemento coincide con la definición de gy hace el reemplazo.
De esta manera, tenemos gque actuar como una función que devuelve otra función; es decir, actúa más o menos como escribimos:
g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]
(Excepto en este caso g[t]por sí solo se evalúa como a Function, mientras que antes g[t]solo no se transformó en absoluto).
El truco final que uso es un patrón opcional. El patrón l_ : 0significa "hacer coincidir cualquier expresión y hacer que esté disponible como l, o no hacer coincidir nada y hacer que 0esté disponible como l". Entonces, si llamas f[i]con un argumento (la imagen a probar) es como si hubieras llamado f[i, 0, 1].
Aquí está el arnés de prueba que utilicé:
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 *)