Golf Me An OOP!
Dos componentes importantes de la programación orientada a objetos son la herencia y la composición. Juntos, permiten crear jerarquías de clase simples pero poderosas para resolver problemas. Su tarea es analizar una serie de declaraciones sobre una jerarquía de clases y responder preguntas sobre la jerarquía.
Entrada
Una serie de declaraciones y preguntas sobre una jerarquía de clases, leídas de un archivo o entrada estándar, lo que sea mejor para su idioma. Si usa la opción de archivo, el nombre de archivo se pasará como primer argumento a su código (argumento de función o argumento de línea de comando, lo que elija). El formato es el siguiente:
<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
La entrada siempre será declaraciones, luego preguntas. Todos los nombres de clase comenzarán con una letra mayúscula en inglés ( A-Z
), y todos los nombres de miembros comenzarán con una letra minúscula en inglés ( a-z
). Todos los nombres distinguen entre mayúsculas y minúsculas, ABC123
no es la misma clase que Abc123
.
No habrá ninguna herencia cíclica; si B
hereda de A
, A
no heredará de B
ninguno de B
los hijos de ninguno .
Solo los nombres de clase formarán parte de una jerarquía: declaraciones como foo is a bar.
odocument has a name.
no ocurrirán.
Salida
Una serie de valores verdaderos o falsos, como respuestas a las consultas, escritos en la salida estándar o como el valor de retorno de su función. Si no tiene suficiente información para responder una pregunta (por ejemplo, preguntas que involucran nombres que no ha visto en las declaraciones), responda con un valor falso.
Casos de prueba
Caso 1:
Entrada:
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?
Salida:
True
True
False
Caso 2:
Entrada:
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?
Salida:
True
True
False
False
True
Reglas
- Puedes responder con una función o un programa
- Las lagunas estándar están prohibidas
- Este es el código de golf , por lo que la respuesta correcta más corta en bytes gana
- La respuesta ganadora se elegirá en una semana.
¡Buena suerte, y que la OOP esté contigo!
Tabla de clasificación
El Fragmento de pila al final de esta publicación genera la tabla de clasificación a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.
Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:
## Language Name, N bytes
¿Dónde N
está el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:
## Perl, 43 + 2 (-p flag) = 45 bytes
También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:
## [><>](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?
igual aTrue
? ¿Todos los objetos tienen un nombre?Criminal is a Person
.Person has a name
.Respuestas:
CJam, 59 bytes
Esto termina instantáneamente para ambos casos de prueba.
Imprime el segundo nombre de la pregunta o
1
(ambos de verdad), o0
(falso).Pruébelo en línea en el intérprete de CJam .
Idea
Debido a la distinción entre clases y miembros, el desafío se reduce a crear un preorden para el cual la entrada proporciona una definición parcial.
Definimos que x ≺ y iff x es una Y o X tiene una Y .
Para el primer caso de prueba, la entrada indica que B ≺ A , C ≺ B y A ≺ foo . Debido a la transitividad, también tenemos B ≺ foo , C ≺ A y A ≺ foo . Además, debido a la reflexividad, x ≺ x siempre es cierto.
Para una entrada dada, podemos extraer la definición parcial de ≺ de las declaraciones, aplicar la transitividad una cantidad suficiente de veces para completar la definición de ≺ y finalmente responder las preguntas.
Código
fuente
C:{B:{A:{foo:{}}}}
Python 3,
431331308 bytesEsta es la versión completa con comentarios.
Salida para el caso de prueba # 1:
Caso # 2:
Eliminé los comandos de depuración para mayor claridad en el programa principal, pero si desea verlos solo mire el historial
fuente
global f
inh(z)
, usedef h(z,f)
y pase el globalf
in cuando lo llame. De hecho, no necesitash(z)
nada, solo coloca el cuerpo donde lo llamas. No necesitar=2
, y puedeprint(r)
prescindir de élif
, ya que debe generar un valor falso para consultas falsas. Puede cambiar el nombresyn
az
afeitará varios bytes allí. No creo que necesites la[]
comprensión de tu lista en el primeroany
.e
una vez, por lo que puede eliminar la definición y simplemente usarla[a,b,c,d]
. En lugar deif s(i,g) is not None
hacerif s(i,g)
, losre.Match
objetos siempre se evalúanTrue
si se encuentra una coincidencia. También puede soltar 2 bytes conf[x]+=f[y]
.Haskell, 157 bytes
Dale la cuerda a
o
. No estoy seguro si hacerx
e infijarv
('extraer' y 'verificar') corta más que hacermap
un infijo, o si ambos son posibles.EDITAR: Explicación
Entonces, así
(#)
es como define un operador infijo, lo uso solo como una abreviatura paramap
aplicar una función a cada elemento de una lista. Resolviendo este y el otro aliasl
, evitando el operador 'aplicación de función directa'$
y agregando aún más paréntesis y espaciando cosas, y con nombres de funciones reales llegamos a:map words (lines string)
es una lista de listas de palabras de cada línea en la cadena de entrada.(=='?').last.last
es un predicado que indica si la última letra en la última palabra de una línea es un signo de interrogación, es decir, si la línea es una pregunta.break
rompe la lista en una tupla de la primera parte sin preguntas (todas las declaraciones) y la parte de la primera pregunta (todas las preguntas).map
hacer pingextract n
en estos saca de cada lista de palabras los elementos que realmente queremos, eln
th (que en las declaraciones es la primera palabra - entoncesn == 0
, y en las preguntas es la segunda palabra - son == 1
) usando el!!
operador y el último, del cual tiene que cortar la última letra (ya sea'.'
o'?'
) usandoinit
.(Tenga en cuenta que ignoro por completo las mayúsculas, eso se debe a que ignoro completamente la distinción entre clases y miembros, los miembros son solo hojas de un árbol construido por la base de conocimiento (pero no todas las hojas representan miembros, también pueden ser clases sin subclases ni miembros) ), en el que cada nodo secundario representa una subclase o un miembro de lo que representa su nodo primario. Me acabo de dar cuenta de que ESTO ES UNA COSA INCORRECTA EN CASOS no cubiertos por OP. Editaré la solución pronto).
Ahora
map (extract 0) knowledge
ymap (extract 1) questions
son listas de tuplas de nombres que representan una relación de subclase o miembro de la primera a la segunda.Las tuplas
map (extract 0) knowledge
son todas relaciones verdaderas, las demap (extract 1) questions
ahora están asignadas a laverify
función, con el primer argumento establecido enmap (extract 0) knowledge
.(De ahora en adelante, dentro
verify
,knowledge
hay un nombre de parámetro y se refiere a laextract
lista de tuplas ya editada).(Además, al leer
verify
, tenga en cuenta que si bien||
(después del salto de línea poco elegante para evitar el desplazamiento horizontal en SE) es una disyunción booleana normal entre el caso 'reflexivo' y el 'recursivo', loor
pliega sobre una lista, es decir, verifica si existe el elemento de la lista es verdadero)Ahora, una relación es obviamente correcta si es reflexiva. Estrictamente hablando, no, a
potato
no tiene unpotato
(y ni siquiera es uno en el sentido de que 'es' se usa aquí, como en 'Un policía es un policía'), pero esa es solo la condición de terminación que cubre todas las relaciones después de caminando por el árbol (que a diferencia de los árboles reales significa 'hacia las hojas').En todos los demás casos, tratamos de tomar una tupla de
knowledge
(después defilter
editar para asegurarnos de que 'vemos' solo pares con el mismo primer elemento que queremos verificar), y continuar desde donde apunta. La comprensión de la lista trata con todas las tuplas posibles para continuar yverify
vuelve a llamar en cada caso. Un callejón sin salida solo tendrá una lista vacía aquí y volverá enfalse
general, y no influirá en la instancia por laverify
que fue llamado.fuente
Learn you a haskell for great good!
y ¡ahora entiendo esto! (Esta respuesta es en realidad lo que me impulsó a aprender más sobre haskell y FP, ¡y es tan genial!)JavaScript,
265263 bytesIngrese una cadena en blanco para salir.
Explicación
fuente
string.split(" ");
?.match(/\w+/g)
eliminar la puntuación de las palabras..split(" ")
sería más corto o me estoy perdiendo algo. (No sé javascript).split
, también tendría que usarlo.slice(0,-1)
(dos veces) porqueB is a A.
haríaB
heredarA.
(con el.
)..split(/\W/)
. ¡Gracias por hacerme buscar eso!