Domuzlar uçabilir mi?


45

Görev

Göreviniz, seçtiğiniz ifadeleri kullanarak, birkaç ifadeyi analiz eden ve domuzların uçabileceği ifadelerden sonuçlanıp sonuçlanmayacağını belirleyen bir işlev veya program yazmaktır.

Giriş

Giriş, STDIN'den okunabilen, işlev bağımsız değişkeni olarak alınan veya hatta bir dosyaya kaydedilebilen bir Dizedir. Giriş, aşağıdaki EBNF kullanılarak tanımlanabilir:

input = statement , {statement};
statement = (("Pigs are ", attribute) | ("Everything that is ", attribute, "is also ", attribute)), ". ";
attribute = [not], ("able to fly" | singleAttribute);
singleAttribute = letter, {letter};
letter = "a" | "b" | "c" | "d" | "e" | "f" | "g"
       | "h" | "i" | "j" | "k" | "l" | "m" | "n"
       | "o" | "p" | "q" | "r" | "s" | "t" | "u"
       | "v" | "w" | "x" | "y" | "z" ;

Örnek giriş (aşağıdaki daha fazla örneğe bakın):

Pigs are green. Everything that is green is also intelligent. Everything that is able to fly is also not intelligent. Pigs are sweet. 

Çıktı

Çıktı, işleviniz tarafından döndürülebilir, bir dosyaya yazılabilir veya STDOUT'a yazdırılabilir. Ele alınması gereken 5 farklı durum vardır:

  1. Verilen açıklamalar geçerlidir, tutarlıdır ve domuzların uçabileceği gibi mantıklı bir sonuçtur. Bu durumda çıkış yapmanız gerekir Yes.
  2. Verilen açıklamalar geçerlidir, tutarlı ve domuzların uçamayacağı kadar mantıklı bir sonuçtur. Bu durumda çıkış yapmanız gerekir No.
  3. Domuzların uçup uçamayacağı, verilen geçerli ve tutarlı ifadelerden çıkarılamaz. Bu durumda çıkış yapmanız gerekir Maybe.
  4. Verilen ifadeler geçerlidir ancak tutarlı değildir (örneğin, verilen ifadelerde bir çelişki vardır). Eski falso quodlibet'ten beri Yes, bu durumda çıktı almaya karar veriyoruz .
  5. Verilen ifadeler geçerli değildir, yani verilen EBNF'ye göre formatlanmamıştır. Bu durumda ne istersen yapabilirsin.

ayrıntılar

  • Verilen niteliklerin birbirinden bağımsız olduğunu varsayabilirsiniz. Bu nedenle, örneğin bir domuz aynı anda herhangi bir tutarsızlığa neden olmadan genç ve yaşlı, yeşil, kırmızı ve mavi olabilir. Bununla birlikte, bir domuz aynı anda 'yeşil' ve 'yeşil' olmayabilir, bu bir çelişkidir ve (4) de açıklandığı gibi kullanılmalıdır.
  • Her özellik için, evrende verilen özelliğe sahip en az bir nesne (zorunlu olarak domuz değil) olduğunu ve buna sahip olmayan bir nesne olduğunu varsayalım.

Örnek Girişler ve Çıkışlar

Giriş:

Pigs are green. Everything that is green is also intelligent. Everything that is able to fly is also not intelligent. 

Çıktı: Domuzlar yeşil ve dolayısıyla zeki olduklarından ve uçabilecek her şey akıllı olmadığından domuzlar uçamaz. Çıktı olduğunu No.

Giriş:

Pigs are old. Everything that is not able to fly is also not old. 

Çıktı: Domuzlar uçamazsa, yaşlı değillerdi. Ancak eski oldukları için çıktı almalısınız Yes.

Giriş:

Everything that is sweet is also not old. Everything that is intelligent is also blue. 

Çıktı: Maybe .

Giriş:

Pigs are not able to fly. Everything that is red is also sweet. Everything that is sweet is also not red. 

Çıktı: İlk ifade domuzların uçamayacağını ima etmesine rağmen, aşağıdaki ifadeler birbiriyle çelişmektedir ve bu nedenle çıktı olması gerekir Yes.

Giriş:

Pigs are very smart. Pigs are able to fly. 

Çıktı: İstediğiniz ne olursa olsun, Dize yukarıda belirtilen kriterlere uymadığından.

kazanan

Bu , bu yüzden en kısa sürede cevap (bayt cinsinden) kazanır. Kazanan, ilk doğru cevap gönderildikten bir hafta sonra seçilecektir.

Uçan bir domuz


üçüncü örnek neden evet döndürüyor?
xem

10
Girişi Prolog koduna çeviren bir cevap yazmayı düşünüyorum.
Tal

1
Kırmızı olan hiçbir şeyin olmadığı sonucuna varabilirsiniz. Tatlı, kırmızı olmayan şeyler iyi.
user2357112

1
Daha fazla örnek umuyordum, sadece onları kendim yapabildim.
cjfaure

1
@xem: ex falso quodlibet, patlama prensibi olarak wikipedia 'dan bakın. Bir çelişki varsa, her şey kanıtlanabilir. Yani eğer 'tanrı var' doğru ise ve 'tanrı yok' doğru ise, her şeyin doğru olduğu gösterilebilir, bu yüzden domuzların uçabileceği doğrulanabilir.
fightermahethief

Yanıtlar:


10

Perl, 363 353 350 347 343 297 266 264

$_=<>;s/able to fly/X/g;$m=' ?(not )?\b(P|\w+)';$h{$1?N.$2:$2}{$3?N.$4:$4}=$h{$3?$4:N.$4}{$1?$2:N.$2}=1while s/$m.{8}$m\.//;map{%x=0,r($_,$_)}%h;sub r{($a,$b)=@_;$e+=$h{$a}{N.$b};$x{$b}++or$h{$a}{$b}=1,map{r($a,$_)}%{$h{$b}}}print$e|$h{P}{X}?Yes:$h{P}{NX}?No:Maybe

Ungolfed / Açıklama:

# Read one line from STDIN
$_=<>;
# Replaces special attribute with X
s/able to fly/X/g;
# Prepare attribute match
$m=' ?(not )?\b(P|\w+)';
# Match "Everything that is A is also B. "
#                        "\bA........ \bB\."
# Match "Pigs are B. "
#     "\bP........\bB\."
while(s/$m.{8}$m\.//)
{
  # Add facts for A => B and !B => !A, where A may equal "P" for "Pigs are"
  # Facts are stored as a hash of hashes %h; keys%h are the source attributes;
  # keys%{$h{$a}} are the attributes that follow from attribute $a
  # A "not attribute" is stored as "Nattribute", while a "attribute" is just stored as "attribute"
  $h{$1?N.$2:$2}{$3?N.$4:$4}=$h{$3?$4:N.$4}{$1?$2:N.$2}=1
}
# For all known source attributes ... (this should really be keys%h but we dont mind the extra hashrefs)
map{%x=0,r($_,$_)}%h;
sub r
{
  ($a,$b)=@_;
  # ... remember that we hit a negation and therefor an inconsistency ...
  # If we check/add $b and find an existing "N$b" that means that attribute $b is supposed to be true and not true at the same time
  # It is cheaper bytewise to just add up all consistency errors (remember each fact has a hard value of 1) than to exit right here
  $e+=$h{$a}{N.$b};
  # ... remember that we processed this attribute for the current source attribute so we prevent loops ...
  $x{$b}++or
  # ... add a new fact and then follow the chains (again omitting keys).
  $h{$a}{$b}=1,map{r($a,$_)}%{$h{$b}}
}
# Did we happen on an inconsistency? Do pigs fly? Dont pigs fly? Maybe (Bitwise or is okay too)
print$e|$h{P}{X}?Yes:$h{P}{NX}?No:Maybe

4
Bize nasıl çalıştığını söylerseniz / yorum yazsanız harika olurdu!
kusur

Ve başka yorumlar daha fazla yorum için ... özellikle herhangi bir şeyin daha fazla açıklamaya ihtiyacı var mı?
Thaylon

Daha da fazla yorum eklendi ...
Thaylon

@AlanBerndt ise bir postfix önerdi. Yorum yapamadığından ve onaylayamadığımdan beri. Teşekkür etmek istiyorum! İşte.
Thaylon

10

Haskell, 586 566 547 bayt

Her özellik için varsayımına yazdım P bazı bulunmalıdır x ve y böyle P (x) doğrudur ve P (y) yanlıştır; Bu varsayım olmadan, dördüncü örnek girdiyle çelişki olmaz ve "Hayır" cevabı verilir.

#define X p s q m
#define W where
t=0<1;f=0>1;y="Yes"
l=length;r=filter;h=head;(#)=(,)
u 0=[[]];u n=[x:y|x<-[t,f],y<-u$n-1]
c l=all(==h l)l#and l
X[]|or[fst$c$map(!!(n-1))e|n<-[1..l$h e]]=y|z t=y|z f="No"|t="Maybe"W e=m$u$l s;z m=t#m==(c$map h$q e)
X("Pigs":_:y)=p v((r$(==a).(!!k)).q)m z W((k,v),z,a)=s%y
X(_:_:_:y)=p w q((r(\x->(x!!j/=a)||(x!!k==b))).m)v W((j,u),_:_:z,a)=s%y;((k,w),v,b)=u%z
s%("not":w)=(i,u,not p)W(i,u,p)=s%w
s%(_:"to":_:w)=(0#s,w,t)
s%(w:z)=(maybe(l s,s++[w#l s])(#s)$lookup w s,z,t)
main=interact$p[""#0]id id.words.r(/='.')

Bu, "-cpp" ghc komut satırı seçeneğiyle derlenmelidir. Giriş, EOF (^ D) ile sonlandırılmalıdır. Çevrimiçi olarak http://melpon.org/wandbox/ adresinden deneyebilirsiniz , ancak komut satırı seçeneklerini ayarlayamazsınız. Bunun yerine, programı dil seçeneğiyle önekleyebilirsiniz.

{-# LANGUAGE CPP #-}

Özellik kümesini toplayarak çalışır, sonra girdideki sonuçları kullanarak özellik -> doğruluk değer kümesini filtreler. Sonuç, her özelliğin hem Doğru hem de Yanlış olarak geçerli bir şekilde atanabilmesini sağlamak için test edilir (buradaki başarısızlık, eski falso quodlibet vakasıdır ). Son olarak, her bir değerlemede "uçabilme" değerini kontrol ederek domuz gerçekleriyle eşleşen değerleri arar.

Oldukça az sayıda bayt etrafındaki diş açma durumuna kaybedildi: şu ana kadar görülen özellikler kümesi, domuz-gerçek-seçici işlevi ve imalarla belirlenen filtreleme işlevi. Muhtemelen aynı fikir, saf bir dilde çok daha kısa olacaktır.

Düzenleme: Birkaç baytın gurur duyduğu haskeller'in önerisi ile kaydedilmiş, sonra z ve "u% u 2 z" nin bağlanması yerine "_: _: z" ile "u% z" ye bağlayarak 3 tane tasarruf ettirerek bir kaç ekstra değer kazandı.

Düzenleme 2: Biraz daha kaydetti. 2 bayt kurtarmak için (#) = (,) numarası kullanıldı ve kalıp kelimelerinin eş anlamlılarını öğrendi ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms ), Bu programdaki çiftlerin geri kalanını ortadan kaldırarak. Ayrıştırıcının aradığı kalıpları değiştirerek daha fazla tasarruf elde ettim. Örneğin: bir cümle Pigs ile başlamazsa ve ayrıştırıcı durumunda kalan bir şey varsa, "Her şey .." cümlesini ayrıştırırız. Bu, X ve% için kalıplarda çok sayıda karakter kaydetti.


Varsayımınız doğru, en başından bahsetmeyi unuttum ama şimdi ayrıntılar bölümüne ekledim!
saat

2
Bayt sayınıza bayrakları dahil etmelisiniz ( code-golf için wiki etiketine bakınız ). Bu nedenle, 607 bayttır.
nyuszika7h

Bu gerçekten doğru mu? Bağlantı sadece unicode kodlamalarla ilgili bayraklardan bahseder; meta, C ++ işaretleriyle ilgili benzer bir meseleden bahseder. IMO, kullanılan bayraklar, Haskell98'in oldukça yaygın bir GHC uzantısına izin vermek içindir, dolayısıyla -std = c ++ 11'e benzer. Ref: meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan

u ile ilgili ikinci tanımınızı değiştirebilirsiniz u n=(:)<$>[t,f]<*>u(n-1)(her ne kadar bu Control.Applicative'in içe
aktarılmasını

1
c ile tanımını değiştirebilirsinc l=(all(==l!!0)l,and l)
proud haskeller

6

Python, 547 536 525 521 513 509 497 503 501

m=map
o='not ';R={'':{''}}
S=lambda x,y:filter(len,m(str.strip,x.split(y)))
N=lambda a:[o+a,a[4:]][a[:4]==o]
def C(s):a,c=S(s[19:],'is also');return[(a,c),(N(c),N(a))]
X=lambda A:A&set(m(N,A))and 1/0 or A
for a,c in sum(m(lambda x:[('',x[9:])]if'P'==x[0]else C(x),S(raw_input(),'.')),[]):R.setdefault(a,{a}).add(c)
def F(s):
 i,n={s},{s}
 while 1:
  for r in i:n|=R.get(r,n)
  if X(i)>=n:return i
  i|=n
try:a='able to fly';n=N(a);c={n:'No','':'Maybe'}[''.join({a,n}&m(F,R)[0])]
except:c='Yes'
print c

Girdideki her a -> bbiri için, verilen maddeyi ve olumsuzluğunu not b -> not a , cümlelerin setine ->ekleriz ve daha sonra bir sabit nokta döngü kullanarak herhangi bir tekliften erişilebilen teklifler setini hesaplarız. Ne zaman bir çelişkiyle karşılaştığımız zaman a (ve daha sonra yakalar) a basar ZeroDivisionErrorve basarız Yes.

Son olarak, 'uçabiliyor' (ve / veya olumsuzluğunun) 'domuz' önermesinden ulaşılabilir olup olmadığını kontrol ediyoruz ''ve uygun yanıtı yazdırıyoruz.

EDIT : Bu adamcağız, tamir ediyor. Sabit.


1
trybloğu aynı satır üzerine yerleştirerek 2 byte tasarruf edebilmelisiniztry:
undergroundmonorail

@ undergroundmonorail: Bunu gördüğünüz için teşekkürler! değiştirdi.
user2361830

5

Yakut 1.9.3 ( 365 364 362)

h='able to fly'
i="(not )?(#{h}|\\w+)"
o=->s{n=Regexp.new(i+" (is also|are) "+i).match s
[[n[2],!n[1]],[n[5],!n[4]]]}
c=e=!z=[]
w=->r{z.member?(r)||(z<<(a,b=r)
c|=a[0]==b[0]&&a[1]!=b[1]
w[[[b[0],!b[1]],[a[0],!a[1]]]]
z.map{|q|q[1]==r[0]&&w[[q[0],r[1]]]})}
y=->x{z.member?([[p='Pigs',!e],[h,x]])}
f=->x{x.split(?.).map{|s|w[o[s]]}
c|y[!e]?'Yes':y[e]?'No':'Maybe'}

kullanım

Tanımlayıp üzerinde kod, bir işlev fmetin girdi ve döner temsil eden bir parametre alır Yes, Noya da Maybe.

Örneğin:

f['Pigs are old. Everything that is not able to fly is also not old.']
=> "Yes"

Çevrimiçi test: http://ideone.com/fxLemg

Ungolfed kodu (birim testleri dahil) burada mevcuttur .


* mevcuttur ("çevrimiçi test" başlığı altında). Çoğul, iyi arkadaşım.
Stan Strum

@StanStrum Teşekkürler! Ben metni değiştirilmiş - Ben kodu demek olduğunu kullanılabilir ve aynı zamanda birim testleri içerir.
Cristian Lupascu
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.