Математика, 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, і все ще розпізнавати зображення як тварина Каприна.
Потім ми бачимо, чи зображення чи перевернуте зображення є більш козистим. Працює над вашим зображенням профілю лише тому, що краватка порушена на користь пуховика. Ймовірно, існує безліч способів, як це можна було б покращити, включаючи запитання, чи зображено зображення Бовіда чи інші узагальнення типу сутності тварини Каприна.
Відповідайте як письмові бали 100% для першого тестового набору і 94% для другого тестового набору, оскільки алгоритм дає непереконливий результат для кози 1. Це можна збільшити до 100% за рахунок ще більшого часу обчислення за рахунок тестування більше значень RecognitionThreshold. Підвищення від 100до 1000sufficies; чомусь Mathematica вважає, що це дуже непоказний образ! Здається, що зміна об'єкта розпізнавання з козелячої тварини на ссавця-копитця також працює.
Безголовки:
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 *)