Jouez-moi au golf!
L'héritage et la composition sont deux composants importants de la programmation orientée objet. Ensemble, ils permettent de créer des hiérarchies de classes simples mais puissantes pour résoudre les problèmes. Votre tâche consiste à analyser une série d'instructions sur une hiérarchie de classes et à répondre à des questions sur la hiérarchie.
Contribution
Une série d'énoncés et de questions sur une hiérarchie de classes, lus à partir d'un fichier ou d'une entrée standard, selon ce qui convient le mieux à votre langue. Si vous utilisez l'option file, le nom de fichier sera transmis comme premier argument à votre code (argument de fonction ou argument de ligne de commande, selon votre choix). Le format est le suivant:
<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
L'entrée sera toujours des déclarations, puis des questions. Tous les noms de classe commenceront par une lettre anglaise majuscule ( A-Z
) et tous les noms de membres commenceront par une lettre anglaise minuscule ( a-z
). Tous les noms sont sensibles à la casse - ABC123
n'est pas la même classe que Abc123
.
Il n'y aura pas d'héritage cyclique - si B
hérite de A
, A
n'héritera pas de B
ou de l'un des B
enfants.
Seuls les noms de classe feront partie d'une hiérarchie - des instructions telles que foo is a bar.
ou document has a name.
ne se produiront pas.
Sortie
Une série de valeurs véridiques ou falsey, en tant que réponses aux requêtes, écrites sur la sortie standard ou en tant que valeur de retour de votre fonction. Si vous ne disposez pas de suffisamment d'informations pour répondre à une question (par exemple, des questions impliquant des noms que vous n'avez pas vus dans les déclarations), répondez par une valeur de falsey.
Cas de test
Cas 1:
Contribution:
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?
Sortie:
True
True
False
Cas 2:
Contribution:
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?
Sortie:
True
True
False
False
True
Règles
- Vous pouvez répondre avec une fonction ou un programme
- Les failles standard sont interdites
- Ceci est le code-golf , donc la réponse correcte la plus courte en octets gagne
- La réponse gagnante sera choisie dans une semaine
Bonne chance et que le POO soit avec vous!
Classement
L'extrait de pile au bas de cet article génère le classement à partir des réponses a) comme une liste des solutions les plus courtes par langue et b) comme un classement général.
Pour vous assurer que votre réponse apparaît, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:
## Language Name, N bytes
où N
est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou que vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:
## Perl, 43 + 2 (-p flag) = 45 bytes
Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de code:
## [><>](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?
égal àTrue
? Tous les objets ont-ils un nom?Criminal is a Person
.Person has a name
.Réponses:
CJam, 59 octets
Cela se termine instantanément pour les deux cas de test.
Il imprime soit le deuxième nom de la question, soit
1
(les deux sont véridiques), soit0
(la fausse).Essayez-le en ligne dans l' interpréteur CJam .
Idée
En raison de la distinction entre les classes et les membres, le défi se résume à créer une précommande pour laquelle l'entrée fournit une définition partielle.
Nous définissons que x ≺ y si x est un y ou x a un y .
Pour le premier cas de test, l'entrée indique que B ≺ A , C ≺ B et A ≺ foo . En raison de la transitivité, nous avons également B ≺ foo , C ≺ A et A ≺ foo . De plus, en raison de la réflexivité, x ≺ x est toujours vrai.
Pour une entrée donnée, nous pouvons donc extraire la définition partielle de ≺ des énoncés, appliquer la transitivité un nombre de fois suffisant pour compléter la définition de ≺ et enfin répondre aux questions.
Code
la source
C:{B:{A:{foo:{}}}}
Python 3,
431331308 octetsCeci est la version complète avec des commentaires
Sortie pour le cas de test n ° 1:
Cas n ° 2:
J'ai supprimé les commandes de débogage pour plus de clarté dans le programme principal, mais si vous souhaitez les voir, regardez simplement dans l'historique
la source
global f
inh(z)
, utilisezdef h(z,f)
et transmettez le globalf
in lors de l'appel. En fait, vous n'avez pas besoinh(z)
du tout - mettez simplement le corps où vous l'appelez. Vous n'en avez pas besoinr=2
et vous pouvez simplement vous enprint(r)
passerif
, car vous devez générer une valeur de falsey pour les fausses requêtes. Vous pouvez renommersyn
pourz
et raser il de plusieurs octets. Je ne pense pas que vous ayez besoin de la[]
compréhension de votre liste dans le premierany
.e
une fois, vous pouvez donc supprimer la définition et simplement l'utiliser[a,b,c,d]
. Au lieu deif s(i,g) is not None
, faireif s(i,g)
-re.Match
objets sont toujours évalués àTrue
si une correspondance est trouvée. Vous pouvez également supprimer 2 octets avecf[x]+=f[y]
.Haskell, 157 octets
Donnez la chaîne à
o
. Je ne sais pas si fairex
etv
('extraire' et 'vérifier') des infixes coupe plus que de fairemap
un infixe, ou si les deux sont possibles.EDIT: Explication
Donc,
(#)
comment vous définissez un opérateur infixe, je l'utilise simplement comme raccourci pourmap
appliquer une fonction à chaque élément d'une liste. En résolvant cela et l'autre aliasl
, en évitant l'opérateur d'application directe de fonction$
et en ajoutant encore plus de parenthèses et d'espacement, et avec de vrais noms de fonction, nous arrivons à:map words (lines string)
est une liste de listes de mots de chaque ligne de la chaîne d'entrée.(=='?').last.last
est un prédicat indiquant si la dernière lettre du dernier mot d'une ligne est un point d'interrogation, c'est-à-dire si la ligne est une question.break
casse la liste dans un tuple de la première partie sans questions (toutes les déclarations) et la partie de la première question sur (toutes les questions).map
pingextract n
sur ceux-ci enlève de chaque liste de mots les éléments que nous voulons vraiment, len
th (qui dans les déclarations est le premier mot - doncn == 0
, et dans les questions est le deuxième mot - doncn == 1
) en utilisant l'!!
opérateur et le dernier, à partir duquel nous doivent couper la dernière lettre (soit'.'
ou'?'
) en utilisantinit
.(Notez que j'ignore complètement la capitalisation, c'est parce que j'ignore complètement la distinction entre les classes et les membres, les membres ne sont que des feuilles d'un arbre construit par la base de connaissances (mais toutes les feuilles ne représentent pas des membres, elles peuvent également être des classes sans sous-classes ni membres) ), dans lequel chaque nœud enfant représente une sous-classe ou un membre de ce que représente son nœud parent. J'ai juste réalisé que c'était une mauvaise chose à faire dans les cas non couverts par OP. Éditera bientôt la solution.)
Maintenant,
map (extract 0) knowledge
etmap (extract 1) questions
sont des listes de tuples de noms représentant une relation de sous-classe ou de membre du premier au second.Les tuples dans
map (extract 0) knowledge
sont tous de vraies relations, ceux dansmap (extract 1) questions
sont maintenant mappés sur laverify
fonction, avec le premier argument défini surmap (extract 0) knowledge
.(Désormais, à l'intérieur
verify
,knowledge
est un nom de paramètre et fait référence à laextract
liste de tuple déjà éditée.)(En outre, lors de la lecture
verify
, notez que tandis que le||
(après le saut de ligne inélégant pour éviter le défilement horizontal sur SE) est une disjonction booléenne normale entre le cas `` réflexif '' et le `` récursif '', leor
replie sur une liste, c'est-à-dire vérifie s'il en existe l'élément de liste est vrai.)Or, une relation est évidemment correcte si elle est réflexive. A proprement parler, non, un
potato
n'a pas avoir unpotato
(et il est même pas un dans le sens « est » est utilisé ici, comme dans « Un flic est un flic »), mais qui est juste la condition de terminaison qui couvre toutes les relations après descendre l'arbre (ce qui, contrairement aux vrais arbres, signifie «vers les feuilles»).Dans tous les autres cas, nous essayons de prendre un tuple
knowledge
(après avoirfilter
édité pour nous assurer que nous ne 'voyons' que les paires avec le même premier élément que celui que nous voulons vérifier), et continuons d'où il pointe. La compréhension de la liste traite de tous les tuples possibles pour continuer et appelle àverify
nouveau dans chaque cas. Une impasse aura juste une liste vide ici et reviendrafalse
globalement, et n'influencera donc pas l'instance deverify
celle - ci qui a été appelée par.la source
Learn you a haskell for great good!
et maintenant je comprends ça! (Cette réponse est en fait ce qui m'a incité à en savoir plus sur haskell et FP, et c'est tellement cool!)JavaScript,
265263 octetsEntrez une chaîne vide pour quitter.
Explication
la source
string.split(" ");
?.match(/\w+/g)
pour supprimer la ponctuation des mots..split(" ")
plus court ou est-ce que je manque quelque chose? (Je ne connais pas javascript).split
je devrais aussi utiliser.slice(0,-1)
(deux fois) carB is a A.
cela feraitB
hériterA.
(avec le.
)..split(/\W/)
. Merci de m'avoir fait chercher ça!