Mathematica, 100%, 141 bajtów
f@x_:=Count[1>0]@Table[ImageInstanceQ[x,"caprine animal",RecognitionThreshold->i/100],{i,0,50}];If[f@#>f@ImageReflect@#,"Up","Down"]<>"goat"&
Cóż, to coś więcej niż oszustwo. Jest również niezwykle powolny, a także bardzo głupi. Funkcja z f
grubsza widzi, jak wysoko można ustawić próg rozpoznawania w jednym z wbudowanych komputerowych systemów wizyjnych Mathematiki, i nadal rozpoznaje obraz jako kozę.
Następnie sprawdzamy, czy obraz lub odwrócony obraz jest bardziej kozi. Działa tylko na Twoim zdjęciu profilowym, ponieważ remis jest zerwany na korzyść downgoat. Prawdopodobnie istnieje wiele sposobów, które można by ulepszyć, w tym pytanie, czy obraz przedstawia Bovids lub inne uogólnienia rodzaju bydła koziego.
Odpowiedz jako pisemne wyniki 100% dla pierwszego zestawu testowego i 94% dla drugiego zestawu testowego, ponieważ algorytm daje niejednoznaczny wynik dla kozy 1. Można to zwiększyć do 100% kosztem jeszcze dłuższego czasu obliczeniowego o testowanie większej liczby wartości RecognitionThreshold
. Podnoszenie z 100
do 1000
sufficies; z jakiegoś powodu Mathematica uważa, że to bardzo nieprzyjemny obraz! Wydaje się, że zmiana jednostki rozpoznającej z kozy na Kopytny Ssak również działa.
Nie golfowany:
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"
]
]
Alternatywne rozwiązanie, 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"
]
]
Ten wykorzystuje tę samą strategię jak poprzednio, ale z wyszukiwaniem binarnym powyżej progu. W grę wchodzą dwie funkcje:
g[t]
zwraca, czy jego argumentem jest obraz kozi z progiem t
.
f
przyjmuje trzy parametry: obraz oraz górną i dolną granicę progu. Jest rekurencyjny; działa poprzez testowanie progu m
między górnym a dolnym progiem (odchylonym w kierunku dolnego). Jeśli obraz i obraz odbity są zarówno kozie, jak i nie-kozie, eliminuje odpowiednio dolną lub górną część zakresu i wywołuje się ponownie. W przeciwnym razie, jeśli jeden obraz jest kozi, a drugi nie jest kozi, zwraca, Upgoat
jeśli pierwszy obraz jest kozi, a w Downgoat
przeciwnym razie (jeśli drugi obraz odbity jest kozi).
Definicje funkcji zasługują na małe wyjaśnienie. Po pierwsze, aplikacja funkcji jest lewostronna. Oznacza to, że coś podobnego g[x][y]
jest interpretowane jako (g[x])[y]
; „wynik g[x]
zastosowania do y
”.
Po drugie, przypisanie w Mathematica jest w przybliżeniu równoznaczne ze zdefiniowaniem reguły zastępowania. Oznacza to, f[x_] := x^2
że nie oznacza „zadeklaruj funkcję o nazwie f
z parametrem, x
który zwraca x^2
;” jego znaczenie jest bliższe: „za każdym razem, gdy zobaczysz coś takiego f[ ... ]
, zadzwoń do środka x
i zastąp to x^2
”.
Zestawiając te dwa elementy, widzimy, że definicja g
mówi Mathematica, aby zastąpić dowolne wyrażenie formularza (g[ ... ])[ ... ]
prawą stroną zadania.
Kiedy Mathematica napotka wyrażenie g[m]
(w drugim wierszu f
), zobaczy, że wyrażenie nie pasuje do żadnych znanych reguł i pozostawia je bez zmian. Następnie dopasowuje Map
operator /@
, którego argumentami są, g[m]
i listę {i, ImageReflect@i}
. ( /@
to notacja infiksowa; to wyrażenie jest dokładnie równoważne z Map[g[m], { ... }]
.) Map
Zastępuje się przez zastosowanie pierwszego argumentu do każdego elementu jego drugiego argumentu, więc otrzymujemy {(g[m])[i], (g[m])[ ... ]}
. Teraz Mathematica widzi, że każdy element pasuje do definicji g
i zastępuje.
W ten sposób musimy g
zachowywać się jak funkcja, która zwraca inną funkcję; to znaczy działa mniej więcej tak, jak napisaliśmy:
g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]
(Z wyjątkiem tego przypadku g[t]
samo ocenia na a Function
, podczas gdy wcześniej g[t]
samo w ogóle nie zostało przekształcone).
Ostatnią sztuczką, której używam, jest opcjonalny wzór. Wzorzec l_ : 0
oznacza „dopasuj dowolne wyrażenie i udostępnij je jako l
, lub nie dopasowuj niczego i 0
udostępnij jako l
”. Tak więc, jeśli wywołujesz f[i]
z jednym argumentem (obrazem do przetestowania), to tak jakbyś zadzwonił f[i, 0, 1]
.
Oto uprząż testowa, której użyłem:
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 *)