Golf Me A ООП!
Двумя важными компонентами объектно-ориентированного программирования являются наследование и компоновка. Вместе они позволяют создавать простые, но мощные иерархии классов для решения проблем. Ваша задача - проанализировать ряд утверждений об иерархии классов и ответить на вопросы об иерархии.
вход
Серия утверждений и вопросов об иерархии классов, прочитанных из файла или стандартного ввода, в зависимости от того, что лучше для вашего языка. Если вы используете опцию file, имя файла будет передано в качестве первого аргумента в ваш код (аргумент функции или аргумент командной строки, в зависимости от того, что вы выберете). Формат выглядит следующим образом:
<statement> : <name> is a <name>. | <name> has a <name>.
<question> : Is <name> a <name>? | Does <name> have a <name>?
<name> : a-z | A-Z | sequence of alphanumerics or underscores, starting with a letter
На входе всегда будут заявления, а затем вопросы. Все имена классов начинаются с заглавной английской буквы ( A-Z
), а все имена членов начинаются со строчной английской буквы ( a-z
). Все имена чувствительны к регистру - ABC123
это не тот же класс, что и Abc123
.
Не будет никакого циклического наследования - если B
наследует от A
, A
не наследует от B
кого-либо из B
детей.
Только имена классов будут частью иерархии - такие операторы, как foo is a bar.
или document has a name.
не будут встречаться.
Выход
Ряд истинных или ложных значений, как ответы на запросы, записанные в стандартный вывод или как возвращаемое значение вашей функции. Если у вас недостаточно информации для ответа на вопрос (например, вопросы с именами, которых вы не видели в утверждениях), ответьте с ошибочным значением.
Тестовые случаи
Случай 1:
Входные данные:
B is a A.
C is a B.
A has a foo.
Does B have a foo?
Is C a A?
Is D a A?
Выход:
True
True
False
Случай 2:
Входные данные:
Cop is a Person.
Criminal is a Person.
Sheriff is a Cop.
Crooked_Cop is a Cop.
Crooked_Cop is a Criminal.
BankRobber is a Criminal.
Cop has a badge.
Criminal has a criminal_record.
Person has a name.
Is Crooked_Cop a Person?
Does Criminal have a name?
Is Crooked_Cop a BankRobber?
Does Person have a potato?
Is Cop a Cop?
Выход:
True
True
False
False
True
правила
- Вы можете ответить с помощью функции или программы
- Стандартные лазейки запрещены
- Это код-гольф , поэтому выигрывает кратчайший правильный ответ в байтах
- Победивший ответ будет выбран через неделю
Удачи, и да будет с вами ООП!
Leaderboard
Фрагмент стека в нижней части этого поста создает таблицу лидеров из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.
Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:
## Language Name, N bytes
где N
размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Если вы хотите включить в заголовок несколько чисел (например, потому что ваш результат равен сумме двух файлов или вы хотите перечислить штрафы за флаг интерпретатора отдельно), убедитесь, что фактический результат является последним числом в заголовке:
## Perl, 43 + 2 (-p flag) = 45 bytes
Вы также можете сделать имя языка ссылкой, которая будет отображаться во фрагменте кода:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 61097; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 45941; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
Does Criminal have a name?
равняетсяTrue
? У всех объектов есть имя?Criminal is a Person
.Person has a name
,Ответы:
CJam, 59 байт
Это завершается мгновенно для обоих тестовых случаев.
Он либо печатает второе имя имени вопроса либо
1
(оба правдиво), либо0
(ложно).Попробуйте онлайн в интерпретаторе CJam .
идея
Из-за различий между классами и членами задача сводится к созданию предварительного заказа, для которого входные данные предоставляют частичное определение.
Мы определим, что x ≺ y, если x является y или x имеет y .
Для первого контрольного примера вход указывает, что B ≺ A , C ≺ B и A ≺ foo . Из-за транзитивности у нас также есть B ≺ foo , C ≺ A и A ≺ foo . Кроме того, из-за рефлексивности, x ≺ x всегда верно.
Таким образом, для данного ввода мы можем извлечь частичное определение ≺ из утверждений, применить транзитивность достаточное количество раз, чтобы завершить определение ≺ и, наконец, ответить на вопросы.
Код
источник
C:{B:{A:{foo:{}}}}
Python 3,
431331308 байтЭто полная версия с комментариями
Выход для теста № 1:
Дело № 2:
Я удалил команды отладки для ясности в основной программе, но если вы хотите увидеть их, просто посмотрите в историю
источник
global f
inh(z)
, используйтеdef h(z,f)
и передавайте глобальныйf
in при вызове. На самом деле, вам совсем не нужноh(z)
- просто поместите тело туда, где вы его называете. Вам не нужноr=2
, и вы можете просто обойтисьprint(r)
безif
, так как вам нужно вывести значение Falsey для ложных запросов. Вы можете переименоватьsyn
вz
и сбрить несколько байт там. Я не думаю, что вам нужно во[]
всем вашем понимании списка в первую очередьany
.e
один раз, так что вы можете покончить с определением и просто использовать[a,b,c,d]
. Вместоif s(i,g) is not None
doif s(i,g)
-re.Match
объекты всегда оцениваются,True
если найдено совпадение. Вы также можете сбросить 2 байта с помощьюf[x]+=f[y]
.Haskell, 157 байт
Дайте строку для
o
. Не уверен, что создание инфиксовx
иv
('extract' и 'verify') режет больше, чем созданиеmap
инфикса, или оба варианта возможны.РЕДАКТИРОВАТЬ: объяснение
Итак,
(#)
как вы определяете инфиксный оператор, я использую его просто как сокращение дляmap
применения функции к каждому элементу списка. Устраняя этот и другой псевдонимl
, избегая оператора 'direct-function-application'$
и добавляя еще больше скобок и пробелов, и с реальными именами функций мы получаем:map words (lines string)
список списков слов каждой строки входной строки(=='?').last.last
является предикатом, указывающим, является ли последняя буква в последнем слове строки знаком вопроса, т.е. является ли строка вопросом.break
разбивает список в кортеже первой части без вопросов (все утверждения) и части из первого вопроса о (все вопросы).map
pingextract n
для этих элементов вынимает из каждого списка слов те элементы, которые нам действительно нужны, элементn
th (который в утверждениях является первым словом - такn == 0
, а в вопросах - второе слово - такn == 1
) с использованием!!
оператора и последнего, из которого мы должны вырезать последнюю букву (или'.'
или'?'
), используяinit
.(Обратите внимание, что я полностью игнорирую капитализацию, потому что я полностью игнорирую различие между классами и членами, члены - это просто листья дерева, построенного базой знаний (но не все листья представляют члены, они также могут быть классами без подклассов и членов ), в котором каждый дочерний узел представляет подкласс или член того, что представляет его родительский узел. Я ТОЛЬКО ПРИЗНАЛ, ЧТО ЭТО НЕПРАВИЛЬНО, ЧТО ДЕЛАТЬ В СЛУЧАЯХ, НЕ УКАЗАННЫХ OP. Скоро отредактирую решение.)
Теперь,
map (extract 0) knowledge
иmap (extract 1) questions
это списки кортежей имен, представляющих подкласс или членское отношение первого ко второму.Все кортежи in
map (extract 0) knowledge
являются истинными отношениями,map (extract 1) questions
теперь они отображаются наverify
функцию с первым аргументом, установленным вmap (extract 0) knowledge
.(Отныне, внутри
verify
,knowledge
это имя параметра и относится к ужеextract
отредактированному списку кортежей.)(Кроме того, при чтении
verify
обратите внимание, что хотя||
(после не элегантного разрыва строки, чтобы избежать горизонтальной прокрутки на SE) это нормальное логическое дизъюнкция между регистром «возвратный» и «рекурсивный»,or
сворачивает его в список, то есть проверяет, есть ли Элемент списка имеет значение true.)Теперь отношения, очевидно, правильные, если они рефлексивные. Строго говоря, нет,
potato
не имеетpotato
(и это даже не в том смысле , «есть» используется здесь, как и в «A Cop является Cop»), но это только условие завершения , которое охватывает все отношения после ходить по дереву (что в отличие от настоящих деревьев означает «к листьям»).Во всех других случаях мы пытаемся взять кортеж из
knowledge
(после того, как мыfilter
выполнили его, чтобы убедиться, что мы «видим» только пары с тем же первым элементом, который мы хотим проверить), и продолжаем с того места, на которое он указывает. Понимание списка имеет дело со всеми возможными кортежами для продолжения и вызываетverify
снова в каждом случае. У тупика просто будет здесь пустой список, и он будет возвращен вfalse
целом, и, следовательно, не повлияет на экземпляр,verify
который был вызван.источник
Learn you a haskell for great good!
и теперь я это понимаю! (Этот ответ на самом деле побудил меня узнать больше о haskell и FP, и это оооочень круто!)JavaScript,
265263 байтаВведите пустую строку, чтобы выйти.
объяснение
источник
string.split(" ");
?.match(/\w+/g)
чтобы убрать пунктуацию со слов..split(" ")
будет короче, или я что-то упустил? (Я не знаю javascript).split
я также должен был бы использовать.slice(0,-1)
(дважды), потомуB is a A.
что сделал быB
наследованиеA.
(с.
)..split(/\W/)
. Спасибо, что заставил меня посмотреть это!