Beni Bir OOP Golf!


26

Beni Bir OOP Golf!

Nesneye yönelik programlamanın iki önemli bileşeni kalıtım ve kompozisyondur. Birlikte, sorunları çözmek için basit ama güçlü bir sınıf hiyerarşisi oluşturmaya izin veriyorlar. Göreviniz, sınıf hiyerarşisine ilişkin bir dizi ifadeyi ayrıştırmak ve hiyerarşi ile ilgili soruları cevaplamaktır.

Giriş

Bir sınıf hiyerarşisine ilişkin, bir dizinden veya standart bir girişten okunan ve hangisi dilinize uygunsa, bir dizi ifade ve soru. Dosya seçeneğini kullanırsanız, dosya adı kodunuza ilk argüman olarak geçecektir (işlev argümanı veya komut satırı argümanı, hangisini seçerseniz). Format aşağıdaki gibidir:

<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

Girdi her zaman ifadeler, sonra sorular olacaktır. Tüm sınıf isimleri büyük harfle yazılmış bir İngilizce harfle ( A-Z) başlayacak ve tüm üye isimleri küçük harfle yazılmış bir İngilizce harfle ( a-z) başlayacaktır . Tüm adlar büyük / küçük harfe duyarlıdır - ABC123ile aynı sınıf değildir Abc123.

Herhangi bir konjonktürel miras olmayacak - eğer Bmiras kalırsa A, herhangi bir çocuğundan Amiras kalmayacak .BB

Yalnızca sınıf adları, hiyerarşinin bir parçası olacaktır - gibi foo is a bar.veya document has a name.gerçekleşmeyen ifadeler .

Çıktı

Sorgulara cevap olarak, standart çıktıya yazılan veya fonksiyonunuzun geri dönüş değeri olarak verilen bir sıra dışı veya falsey değerleri. Bir soruyu cevaplamak için yeterli bilginiz yoksa (örneğin ifadelerde görmediğiniz isimleri içeren sorular), yanlış bir değerle cevaplayın.

Test Kılıfları

Dava 1:

Giriş:

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?

Çıktı:

True
True
False

Durum 2:

Giriş:

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?

Çıktı:

True
True
False
False
True

kurallar

  • Bir işlev veya programla cevap verebilirsiniz.
  • Standart boşluklar yasaktır
  • Bu , bayt cinsinden en kısa sürede doğru cevap kazanır.
  • Kazanan cevap bir hafta içinde seçilecek

İyi şanslar ve OOP seninle olsun!

Liderler Sıralaması

Bu yazının altındaki Yığın Parçacığı, a) dilindeki en kısa çözümlerin bir listesi olarak ve b) genel bir lider tablosu olarak cevaplardan lider tablosu oluşturur.

Cevabınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak cevabınızı bir başlık ile başlatın:

## Language Name, N bytes

Gönderinizin Nbüyüklüğü nerede ? Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğundan veya tercüman bayrağı cezalarını ayrı ayrı listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

## Perl, 43 + 2 (-p flag) = 45 bytes

Dil adını, daha sonra pasajda görünecek bir bağlantı da yapabilirsiniz:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Nasıl Does Criminal have a name?eşittir True? Tüm nesnelerin bir adı var mı?
J Atkin

4
@ Jakin Criminal is a Person. Person has a name.
Reto Koradi

Ahh ... Bunu özlemiştim.
J Atkin

Tüm girişi bir kerede almam gerekir mi yoksa etkileşimli bir konsol gibi satır satır alabilir miyim? # 2 ise, giriş bir statü olsa bile bir truthy \ falsey yazabilir miyim?
J Atkin

@ Jakin Bir kerede veya satır satır, seçiminizi yapın. Bu bir ifade ise, herhangi bir çıktı olmamalıdır. Sadece sorular cevap alır.
Mego

Yanıtlar:


13

CJam, 59 bayt

q_'.e=\N/{)'?=\S/>_,(%}%/(__,*{(2$z~@f=.*\m*|}/ff{1$e=>:=N}

Bu, her iki test durumu için de anında biter.

Sorunun ikinci adını ya da 1(her ikisi de) veya 0(sahte) ikinci adı yazdırır .

CJam tercümanında çevrimiçi olarak deneyin .

Fikir

Sınıflar ve üyeler arasındaki ayrım nedeniyle, zorluk , girdinin kısmi bir tanım sağladığı bir ön sipariş oluşturmaya kadar azalmaktadır .

Biz tanımlayan xy ancak ve ancak X a, y veya X bir sahiptir y .

İlk test durumu için giriş BA , CB ve Afoo olduğunu belirtir . Çünkü geçişlilik, biz de var Bfoo , CA ve Afoo . Ayrıca, yansıma nedeniyle, xx her zaman doğrudur.

Verilen bir girdi için, ≺ 'in kısmi tanımını ifadelerden çıkarabilir, ivity tanımını tamamlamak için nihayetinde transit geçişi uygulayabilir ve sonunda soruları cevaplayabiliriz.

kod

q_     e# Push all input from STDIN and a copy.
'.e=   e# Count the number of dots/statements (C).
\N/    e# Split the original input at linefeeds.
{      e# For each line:
  )'?= e#   Pop the last character and check if it is a question mark.
       e#   Pushes 1 for '?', 0 for '.'.
  \S/  e#   Split the modified line at spaces.
  >    e#   Remove the first chunk ("Does" or "Is") for questions.
  _,(% e#   Keep the first and last element of the resulting array.
}%/    e# Split the line array into chunks of length C.
(_     e# Extract the first chunk (statements) and push a copy.
       e# The original becomes an accumulator for ≺.
_,*    e# Repeat the statements C times.
{      e# For each of the repeated statements:
  (    e#   Shift out the first name.
       e#     ["w" "x"] -> ["x"] "w"
  2$z~ e#   Copy the accumulator, zip it and dump.
       e#     [["x" "y"] ["z" "w"]] -> ["x" "z"] ["y" "w"]
  @f=  e#   Rotate the shifted out name on top and check for equality.
       e#     ["y" "w"] "w" -> [0 1]
  .*   e#   Vectorized string repetition.
       e#     ["x" "z"] [0 1] -> ["" "z"]
  \m*  e#   Swap the result with the shifted array and apply Cartesian product.
       e#     ["" "z"] ["x"] -> [["" "x"] ["z" "x"]]
       e#   This accounts for transitivity; we had ["w" "x"] and ["z" "w"],
       e#   so now we have ["z" "x"].
  |    e#   Perform set union with the accumulator to add the new pairs.
}/     e#
ff{    e# For each of the questions on the bottom of the stack.
  1$e= e#   Count the occurrences of the question pair in the accumulator.
  >    e#   Remove 0 or 1 elements from the question pair.
  :=   e#   Check for equality.
       e#   If the question pair occurs in the accumulator, this pushes the
       e#   second name of the question pair. Otherwise, it pushes 1 if the
       e#   names are equal (to account for reflexivity) and 0 otherwise.
  N    e#   Push a linefeed.
}      e#

2
CJam'ın sınıfları olmadığı düşünüldüğünde bu etkileyici: D
Beta Decay

Bu güzel.
Mego

@ BetaDecay Sınıfları aslında yuvalanmış kümelerdir; sınıflar her dilde uygulanır. İlk örnekte söyle. C:{B:{A:{foo:{}}}}
Bir

8

Python 3, 431 331 308 bayt

o={}
f={}
def h(z,f):
 if z not in o:f[z]=[z];o[z]=[]
while 1:
 g=input().split(' ');r=2;l=g[-1][:-1]
 if'.'in g[3]:
  if'i'in g[1]:h(g[0],f);h(l,f);f[g[0]]+=f[l]
  if'h'in g[1]:o[g[0]]+=l,
 else:
  if'I'in g[0]:r=any(l in z for z in f[g[1]])
  if'D'in g[0]:r=any(l in o[z] for z in f[g[1]])
 if r<2:print(r)

Bu yorumların tam sürümüdür

objects = {}
synonyms = {}

def createObject(name):
    """
    Create a object with `name` if is does not yet exist and start a synonym tree.
    """
    if name not in objects:
        synonyms[name] = [name]
        objects[name] = []

# use this to read from a file
# with open("questions.txt") as file: 
#     for l in file:
        # print(">>> " + l, end='')
        # inArg = l.replace("\n","").split(" ")


while True: # to read from a file comment this
        inArg = input(">>> ").split(" ") # and this out

        out = -1

        if '.' in inArg[3]: # statement
            last = inArg[3].replace('.','')

            if 'i' in inArg[1]: # is a
                createObject(inArg[0])
                createObject(last)
                synonyms[inArg[0]] += synonyms[last]

            if 'h' in inArg[1]: # has a
                objects[inArg[0]] += [last]

        else:# question
            last = inArg[-1].replace('?','')

            createObject(inArg[1])
            if 'I'in inArg[0]: # Is a
                out = any([last in syn for syn in synonyms[inArg[1]]])

            if 'D'in inArg[0]: # Does have a
                out = any(last in objects[syn] for syn in synonyms[inArg[1]])

        if out != -1:
            print(out)

Test durumu # 1 için çıktı:

True
True
False

Dava # 2:

True
True
False
False
True

Ana programdaki netlik için hata ayıklama komutlarını kaldırdım, ancak onları görmek isterseniz sadece tarihe bakmak


Bunun yerine kullanmanın global fiçinde h(z)kullanımı def h(z,f)ve küresel geçmesi fonu çağrılırken içinde. Aslında, hiç ihtiyacınız yok h(z)- sadece vücudu istediğiniz yere koyun. İhtiyacınız yok r=2ve bunu print(r)yapmadan yapabilirsiniz ifçünkü yanlış sorgular için bir falsey değeri vermeniz gerekir. Sen yeniden adlandırabilir syniçin zve tıraş orada birkaç bayt kapatır. []İlk önce listenin kavranmasına ihtiyacın olduğunu sanmıyorum any.
Mego

Ayrıca bir ekez kullanırsınız , böylece tanımlamayı ortadan kaldırabilir ve sadece kullanabilirsiniz [a,b,c,d]. Yerine if s(i,g) is not None, do if s(i,g)- re.Matchnesneleri her zaman değerlendirilir Truebir eşleşme bulunursa. Ayrıca 2 bayt ile bırakabilirsiniz f[x]+=f[y].
Mego

@Mego Wow, tüm ipuçları için teşekkürler. Onları daha sonra koymam gerekecek.
J Atkin

Bu mesaj muhtemelen size çok yardımcı olacaktır
Mego

@Mego Big, 396'ya düştü. Kısa bir süre sonra göndereceğim.
J Atkin

4

Haskell, 157 bayt

o s=v(x 0#k)#(x 1#q)where(k,q)=break((=='?').l.l)(words#lines s)
x n w=(w!!n,init$l w)
v k(a,c)=a==c||or[v k(b,c)|b<-snd#(filter((==a).fst)k)]
(#)=map
l=last

İpi ver o. Değil emin eğer xve v( 'özü' ve 'doğrulamak') ekleri içermemelidir kesimler fazla yapım maphem mümkün olup olmadığını bir infix veya.

EDIT: Açıklama

Yani, (#)bir infix işlecini nasıl tanımladığınızdır, onu maplistenin her bir elemanına bir fonksiyon uygulamak için kısaca kullanırım . Bunu ve diğer takma ladımı çözerek, 'direct-function-application' işlecinden kaçınarak $ve daha fazla parantez ve aralık ekleyerek ve gerçek işlev adları ile varıyoruz:

oop string = map (verify (map (extract 0) knowledge)) (map (extract 1) questions)
 where (knowledge,questions) = break ((=='?').last.last) (map words (lines string))

extract n wordlist = (wordlist!!n,init (last wordlist))

verify knowledge (a,c) = (a==c)
               || or [verify knowledge (b,c) | b <- map snd (filter ((==a).fst) knowledge)]

map words (lines string) Giriş dizesindeki her satırın sözcük listelerinin listesidir.

(=='?').last.last Satır son sözcüğündeki son harf bir soru işareti olup olmadığını, yani satırın bir soru olup olmadığını belirten bir göstergedir.

break Listeyi soru olmadan ilk bölümden (tüm ifadelerden) ve ilk sorudan (tüm sorulardan) bölümler.

mapextract nBunlara ping yapmak , her kelimenin listesinden gerçekten istediğimiz unsurları çıkarır, nth kelimesi (ifadelerde ilk kelimedir - yani n == 0, sorularda ikinci kelimedir - so n == 1) !!operatör ve sonuncuyu kullanarak kullanarak son harfi kesmek (ya '.'da '?') gerekir init.

(Büyük harfleri tamamen görmezden geldiğime dikkat edin, çünkü sınıflar ve üyeler arasındaki ayrımı tamamen görmezden geldiğim için, üyeler sadece bilgi tabanı tarafından oluşturulan bir ağacın yapraklarıdır (ancak tüm yapraklar üyeleri temsil etmez, aynı zamanda ne alt sınıflara ne de üyelere sahip olan sınıflar da olamaz) (her alt düğümün üst düğümünün temsil ettiği şeyin bir alt sınıfını veya üyesini temsil ettiği) .BU'NUN GERÇEKLEŞTİRDİĞİMİZ OP tarafından kapsanmayan durumlarda yapılması gereken bir yanlış.) Yakında çözümü düzenleyecektir.)

Şimdi map (extract 0) knowledgeve map (extract 1) questionsbirinci ile ikinci arasındaki bir alt sınıfı ya da üye ilişkisini temsil eden ad tuplelerinin listesi.

Tuplelerin map (extract 0) knowledgehepsi gerçek ilişkilerdir, map (extract 1) questionsburadakiler şimdi verifyilk argümanın ayarlandığı şekilde fonksiyonun üzerinde eşleştirilir map (extract 0) knowledge.

(Bundan sonra iç hakkında verify, knowledgebir parametre adı ve daha önce ifade eder extracted demet listesi).

(Ayrıca, okurken verify, ||(SE'de yatay kaydırmayı önlemek için inelegant linebreak işleminden sonra) normal bir boole bağlantısının "refleks" ile "özyinelemeli" durum arasında orolmasına rağmen, bir listenin üzerine katlandığını, yani varsa kontrol ettiğini unutmayın. liste öğesi doğrudur.)

Şimdi, eğer bir dönüşümsüz ise, bir ilişki açıkça doğrudur. Kesinlikle hayır, bir konuşma potatodeğil sahip bir potato(ve olduğu gibi burada bile kullanılan anlamda 'is' in biri değil 'Polis polis olduğunu'), ama bu sadece sonlandırma koşulu olduğunu kapakları tüm ilişkiler sonrasında ağaçtan yürümek (gerçek ağaçların aksine, 'yapraklara doğru' anlamına gelir).

Diğer tüm durumlarda, bir demet almaya çalışırız knowledge( filteryalnızca kontrol etmek istediğimizle aynı ilk elemente sahip çiftleri 'gördüğümüzden emin olduktan sonra ) ve işaret ettiği yerden devam eder. Liste anlama, devam etmek için muhtemel tüm bağlantıyı ele alır ve verifyher durumda tekrar arar . Çıkmaz sokak burada boş bir listeye sahip olacak ve falsegenel olarak geri dönecek ve bu nedenle verifyonun tarafından çağrılan örneği etkilemeyecek .


Haskell olmayan akıcı insanlar için kısa bir açıklama ekleyebilir misiniz?
J Atkin

Mutlu bir şekilde! İstenene kadar her yazı için yapmıyorum.
Leif Willerts,

Tamam teşekkürler! (dolgu maddesi)
J Atkin

Vay, bu bir açıklama.
J Atkin

2
Ben sadece ilk yarısını okumayı bitirdim Learn you a haskell for great good!ve şimdi bunu anlıyorum! (Bu cevap aslında beni haskell ve FP hakkında daha fazla şey öğrenmeye teşvik etti, ve sooooo harika!)
J Atkin

4

JavaScript, 265 263 bayt

for(o={};i=prompt().split(/\W/);)a=i[0],b=i[1],d=i[2],b=="is"?((o[a]=o[a]||{p:[],k:{}}).p.push(d),o[d]=o[d]||{p:[],k:{}}):b=="has"?o[a].k[d]=1:alert(o[b]&&(a>"E"?b==d|(c=n=>~(p=o[n].p).indexOf(d)|p.some(c))(b):(c=n=>o[n].k.hasOwnProperty(i[4])|o[n].p.some(c))(b)))

Çıkmak için boş bir dize girin.

açıklama

for(
  o={};                               // o = all objects
  i=prompt().split(/\W/);             // i = command as an array of words
)
  a=i[0],                             // a = first word
  b=i[1],                             // b = second word
  //c=i[2],                           // c = third word
  d=i[3],                             // b = fourth word
  //e=i[4],                           // e = fifth word

  // Case: <name> is a <name>.
  b=="is"?(
    (o[a]=o[a]||{p:[],k:{}})          // create the object if it does not exist
      .p.push(d),                     // add the parent to the object's list of parents
    o[d]=o[d]||{p:[],k:{}}            // create the parent if it does not exist
  ):

  // Case: <name> has a <name>.
  b=="has"?
    o[a].k[d]=1                       // set the specified property

  :
  alert(                              // display the responses to the questions
    o[b]                              // false if the queried object does not exist
    &&(

      // Case: Is <name> a <name>?
      a>"E"?                          // "Is" > "E" and "Does" < "E"
        b==d                          // check if it is itself
        |(c=n=>
          ~(p=o[n].p)                 // p = direct parents of current object
            .indexOf(d)               // check direct parents for the object
          |p.some(c)                  // check the grandparents
        )(b)

      // Case: Does <name> have a <name>?
      :
        (c=n=>
          o[n].k.hasOwnProperty(i[4]) // check if this object has the property
          |o[n].p.some(c)             // check it's parents for the property also
        )(b)
    )
  )

Kullanabilir string.split(" ");misin
J Atkin

@JAtkin .match(/\w+/g)Noktalama işaretlerini kelimelerden çıkarmak için kullanılır .
user81655

Bunu gördüm ama daha .split(" ")kısa olmaz mıyım yoksa bir şey mi özlüyorum? (Ben javascript bilmiyorum)
J Atkin

@JAtkin Kullansaydım (iki kere) .splitde kullanmak zorunda kalacağım .slice(0,-1)çünkü (ile ) miras B is a A.alacaktı . BA..
user81655 22:15

@JAtkin Aslında, split'in kullanabileceğim düzenli ifadeleri kabul ettiğini öğrendim .split(/\W/). Buna bakmama neden olduğun için teşekkürler!
user81655 22:15
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.