Mathematica, 100%, 141 byte
f@x_:=Count[1>0]@Table[ImageInstanceQ[x,"caprine animal",RecognitionThreshold->i/100],{i,0,50}];If[f@#>f@ImageReflect@#,"Up","Down"]<>"goat"&
Bene, questo sembra più che un po 'barare. È anche incredibilmente lento oltre ad essere molto sciocco. La funzione f
vede all'incirca quanto in alto è possibile impostare la soglia di riconoscimento in uno dei builtin di visione artificiale di Mathematica, e ancora riconoscere l'immagine come un animale Caprino.
Vedremo quindi se l'immagine o l'immagine capovolta è più goaty. Funziona sull'immagine del tuo profilo solo perché la cravatta è rotta a favore di downgoat. Probabilmente ci sono molti modi in cui questo potrebbe essere migliorato, incluso chiedendogli se l'immagine rappresenti Bovidi o altre generalizzazioni del tipo di entità animale Caprina.
Rispondi come punteggio scritto 100% per il primo set di test e 94% per il secondo set di test, poiché l'algoritmo produce un risultato inconcludente per la capra 1. Questo può essere riportato al 100% a spese di un tempo di calcolo ancora più lungo di testare più valori di RecognitionThreshold
. Innalzamento da 100
a 1000
sufficienti; per qualche motivo Mathematica pensa che sia un'immagine molto poco seria! Anche la modifica dell'entità del riconoscimento dall'animale Caprino a Mammifero zoppicato sembra funzionare.
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"
]
]
Soluzione alternativa, bonus del 100% +
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"
]
]
Questo utilizza la stessa strategia di prima, ma con una ricerca binaria oltre la soglia. Ci sono due funzioni coinvolte qui:
g[t]
restituisce o meno il suo argomento è un'immagine goaty con soglia t
.
f
accetta tre parametri: un'immagine e un limite superiore e inferiore sulla soglia. È ricorsivo; funziona testando una soglia m
tra la soglia superiore e quella inferiore (polarizzata verso la parte inferiore). Se l'immagine e l'immagine riflessa sono sia goaty che non-goaty, elimina la parte inferiore o superiore dell'intervallo nel modo appropriato e si chiama di nuovo. Altrimenti, se un'immagine è goaty e l'altra non è goaty, viene restituita Upgoat
se la prima immagine è goaty e Downgoat
altrimenti (se la seconda immagine riflessa è goaty).
Le definizioni delle funzioni meritano una piccola spiegazione. Innanzitutto, l'applicazione delle funzioni è di associazione associativa. Ciò significa che qualcosa di simile g[x][y]
viene interpretato come (g[x])[y]
; "il risultato di g[x]
applicato a y
."
In secondo luogo, l'incarico in Mathematica equivale all'incirca alla definizione di una regola sostitutiva. Cioè, f[x_] := x^2
non non significa "dichiarare una funzione chiamata f
con il parametro x
che restituisce x^2
;" il suo significato è più vicino a "ogni volta che vedi qualcosa di simile f[ ... ]
, chiama la cosa dentro x
e sostituisci l'intera cosa con x^2
".
Mettendo insieme questi due, possiamo vedere che la definizione di g
sta dicendo a Mathematica di sostituire qualsiasi espressione del modulo (g[ ... ])[ ... ]
con il lato destro dell'incarico.
Quando Mathematica incontra l'espressione g[m]
(nella seconda riga di f
), vede che l'espressione non corrisponde a nessuna delle regole che conosce e la lascia invariata. Quindi corrisponde Map
all'operatore /@
, i cui argomenti sono g[m]
e l'elenco {i, ImageReflect@i}
. ( /@
è notazione infissa; questa espressione è esattamente equivalente a Map[g[m], { ... }]
.) Map
Viene sostituita applicando il suo primo argomento a ciascun elemento del suo secondo argomento, quindi otteniamo {(g[m])[i], (g[m])[ ... ]}
. Ora Mathematica vede che ogni elemento corrisponde alla definizione di g
e fa la sostituzione.
In questo modo dobbiamo g
agire come una funzione che restituisce un'altra funzione; cioè, agisce più o meno come abbiamo scritto:
g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]
(Tranne che in questo caso g[t]
da solo valuta a Function
, mentre prima g[t]
da solo non è stato affatto trasformato.)
L'ultimo trucco che uso è un modello opzionale. Il modello l_ : 0
significa "abbina qualsiasi espressione e rendila disponibile come l
, oppure non corrisponde a nulla e rendi 0
disponibile come l
". Quindi, se chiami f[i]
con un argomento (l'immagine da testare) è come se avessi chiamato f[i, 0, 1]
.
Ecco il cablaggio di prova che ho usato:
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 *)