Математика, 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
до 1000
sufficies; чомусь 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 *)