Mathematica, 100%, 141 байт
f@x_:=Count[1>0]@Table[ImageInstanceQ[x,"caprine animal",RecognitionThreshold->i/100],{i,0,50}];If[f@#>f@ImageReflect@#,"Up","Down"]<>"goat"&
Ну, это больше похоже на обман. Это также невероятно медленно и очень глупо. Функция f
примерно показывает, насколько высоко вы можете установить порог распознавания в одном из встроенных в компьютерное зрение Mathematica изображений, и при этом распознавать изображение как животное-каприн.
Затем мы видим, является ли изображение или перевернутое изображение более козлиным. Работает над изображением вашего профиля только потому, что галстук нарушен в пользу понижения. Вероятно, существует множество способов, которыми это можно улучшить, включая вопрос о том, представляет ли изображение Bovids или другие обобщения типа сущностей животных-капринов.
Ответьте в виде письменных оценок 100% для первого набора тестирования и 94% для второго набора тестирования, поскольку алгоритм дает неубедительный результат для козы 1. Это может быть повышено до 100% за счет еще более длительного вычислительного времени: тестирование больше значений RecognitionThreshold
. Повышение от 100
до 1000
достаточности; по какой-то причине Mathematica считает, что это очень плохой образ! Изменение объекта распознавания с животного-каприна на копытного млекопитающего также, кажется, работает.
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"
]
]
Альтернативное решение, 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"
]
]
Этот использует ту же стратегию, что и раньше, но с бинарным поиском через порог. Здесь задействованы две функции:
g[t]
возвращает, является ли его аргумент козлиным изображением с порогом t
.
f
принимает три параметра: изображение и верхнюю и нижнюю границу порога. Это рекурсивно; это работает, проверяя порог m
между верхним и нижним порогами (смещенный к нижнему). Если изображение и отраженное изображение являются козлиными или не козлиными, оно удаляет нижнюю или верхнюю часть диапазона в зависимости от ситуации и вызывает себя снова. В противном случае, если одно изображение является козлиным, а другое - не козлиным, оно возвращается, Upgoat
если первое изображение является козьим, а в Downgoat
противном случае (если второе, отраженное изображение является козлиным).
Определения функций заслуживают небольшого пояснения. Во-первых, применение функции левоассоциативно. Это означает, что нечто подобное g[x][y]
интерпретируется как (g[x])[y]
; «Результат g[x]
применения к y
.»
Во-вторых, назначение в Mathematica примерно эквивалентно определению правила замены. То есть, f[x_] := x^2
это не значит «объявить функцию с именем f
с параметром , x
который возвращает x^2
;» его значение ближе к: «всякий раз, когда вы видите что-то подобное f[ ... ]
, называйте вещь внутри x
и заменяйте все на x^2
».
Соединяя эти два значения вместе, мы можем видеть, что определение g
говорит Mathematica заменить любое выражение формы (g[ ... ])[ ... ]
правой частью присваивания.
Когда Mathematica встречает выражение g[m]
(во второй строке f
), оно видит, что выражение не соответствует ни одному из известных ему правил, и оставляет его без изменений. Затем он соответствует Map
оператору /@
, чьи аргументы g[m]
и список {i, ImageReflect@i}
. ( /@
это инфиксная запись; это выражение в точности эквивалентно Map[g[m], { ... }]
.) Map
Заменяется путем применения его первого аргумента к каждому элементу его второго аргумента, поэтому мы получаем {(g[m])[i], (g[m])[ ... ]}
. Теперь Mathematica видит, что каждый элемент соответствует определению g
и выполняет замену.
Таким образом, мы g
должны действовать как функция, которая возвращает другую функцию; то есть он действует примерно так, как мы написали:
g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]
(За исключением того, что в этом случае само g[t]
по себе оценивается как a Function
, тогда как раньше само g[t]
по себе не было преобразовано вообще.)
Последний трюк, который я использую - это необязательный шаблон. Шаблон l_ : 0
означает «сопоставить любое выражение и сделать его доступным как l
, или ничего не сопоставить и сделать 0
доступным как l
». Итак, если вы вызываете f[i]
с одним аргументом (проверяемое изображение), это как если бы вы звонили f[i, 0, 1]
.
Вот тестовый жгут, который я использовал:
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 *)