Können Schweine fliegen?


45

Aufgabe

Ihre Aufgabe ist es, eine Funktion oder ein Programm in einer Sprache Ihrer Wahl zu schreiben, die einige Aussagen analysiert und feststellt, ob aus diesen Aussagen geschlossen werden kann, dass Schweine fliegen können.

Eingang

Die Eingabe ist eine Zeichenfolge, die aus STDIN gelesen, als Funktionsargument verwendet oder sogar in einer Datei gespeichert werden kann. Die Eingabe kann mit folgendem EBNF beschrieben werden:

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" ;

Beispieleingabe (siehe weitere Beispiele unten):

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

Ausgabe

Die Ausgabe kann von Ihrer Funktion zurückgegeben, in eine Datei geschrieben oder an STDOUT gedruckt werden. Es sind 5 verschiedene Fälle zu behandeln:

  1. Die angegebenen Aussagen sind gültig, konsistent und haben logischerweise zur Folge, dass Schweine fliegen können. In diesem Fall müssen Sie ausgeben Yes.
  2. Die angegebenen Aussagen sind gültig, konsistent und haben als logische Konsequenz, dass Schweine nicht fliegen können. In diesem Fall müssen Sie ausgeben No.
  3. Aus den gegebenen, gültigen und übereinstimmenden Aussagen kann nicht geschlossen werden, ob Schweine fliegen können oder nicht. In diesem Fall müssen Sie ausgeben Maybe.
  4. Die angegebenen Aussagen sind gültig, aber nicht konsistent (dh es gibt einen Widerspruch in den angegebenen Aussagen). Da ex falso quodlibet , entscheiden wir uns Yesin diesem Fall für die Ausgabe .
  5. Die angegebenen Aussagen sind ungültig, dh sie sind nicht gemäß der angegebenen EBNF formatiert. In diesem Fall können Sie tun, was Sie wollen.

Einzelheiten

  • Sie können davon ausgehen, dass die angegebenen Attribute unabhängig voneinander sind. So kann beispielsweise ein Schwein jung und alt, grün, rot und blau gleichzeitig sein, ohne dass es zu Inkonsistenzen kommt. Ein Schwein darf jedoch nicht gleichzeitig 'grün' und 'nicht grün' sein, das ist ein Widerspruch und sollte wie in (4) beschrieben behandelt werden.
  • Nehmen Sie für jedes Attribut an, dass es mindestens ein Objekt (nicht unbedingt ein Schwein) im Universum gibt, das das angegebene Attribut hat, und ein Objekt, das es nicht hat.

Beispiel Ein- und Ausgänge

Eingang:

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

Output: Da Schweine grün und daher intelligent sind und alles, was fliegen kann, nicht intelligent ist, können Schweine nicht fliegen. Ausgabe ist No.

Eingang:

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

Output: Wenn Schweine nicht fliegen konnten, waren sie auch nicht alt. Aber wie sie alt sind, müssen Sie ausgeben Yes.

Eingang:

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

Ausgang: Maybe .

Eingang:

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

Ausgabe: Obwohl die erste Aussage impliziert, dass Schweine nicht fliegen können, widersprechen sich die folgenden Aussagen und daher muss die Ausgabe sein Yes.

Eingang:

Pigs are very smart. Pigs are able to fly. 

Ausgabe: Was auch immer Sie möchten, da der String nicht den oben genannten Kriterien entspricht.

Gewinner

Das ist , also gewinnt die kürzeste richtige Antwort (in Bytes). Der Gewinner wird eine Woche nach dem Absenden der ersten richtigen Antwort ermittelt.

Ein fliegendes Schwein


Warum gibt das dritte Beispiel yes zurück?
Xem

10
Ich überlege, eine Antwort zu schreiben, die die Eingabe in Prolog-Code übersetzt.
Tal

1
Sie können nur den Schluss ziehen, dass nichts Rotes existiert. Süße, nicht rote Dinge sind in Ordnung.
user2357112

1
Ich habe auf weitere Beispiele gehofft, nur damit ich sie selbst machen kann.
cjfaure

1
@xem: ex falso quodlibet, schau es auf Wikipedia als das Prinzip der Explosion nach. Wenn ein Widerspruch besteht, kann alles bewiesen werden. Also, wenn 'Gott existiert' wahr ist und 'Gott existiert nicht' wahr ist, kann alles als wahr gezeigt werden, daher können Schweine fliegen als wahr nachgewiesen werden.
Fightermagethief

Antworten:


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 / Erklärung:

# 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
Wäre toll, wenn ihr uns erzählen könntet, wie es funktioniert / schreibt ein paar Kommentare!
Fehler

Und noch eine Gegenstimme für mehr Kommentare ... braucht etwas mehr Erklärung?
Thaylon

Noch mehr Kommentare
hinzugefügt

@AlanBerndt hat währenddessen einen Postfix vorgeschlagen. Da er nicht kommentieren kann und ich nicht zustimmen kann. Ich möchte mich bedanken! Hier.
Thaylon

10

Haskell, 586 566 547 Bytes

Ich schrieb dies unter der Annahme, dass für jede Eigenschaft P einige x und y existieren müssen, so dass P (x) wahr und P (y) falsch ist; Ohne diese Annahme hätte die vierte Beispieleingabe keinen Widerspruch und würde mit "Nein" antworten.

#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(/='.')

Dies sollte mit der ghc-Kommandozeilenoption "-cpp" kompiliert werden. Die Eingabe muss mit EOF (^ D) abgeschlossen werden. Sie können es online unter http://melpon.org/wandbox/ versuchen , aber Sie können keine Befehlszeilenoptionen festlegen. Stattdessen können Sie dem Programm die Sprachoption voranstellen

{-# LANGUAGE CPP #-}

Es funktioniert, indem die Gruppe von Merkmalen gesammelt und dann die Gruppe von Merkmalen -> Wahrheitsbewertungen unter Verwendung der Auswirkungen in der Eingabe gefiltert wird. Das Ergebnis wird dann getestet, um sicherzustellen, dass jedes Merkmal sowohl mit Richtig als auch mit Falsch belegt werden kann (Fehler ist hier der Ex-Falso-Quodlibet- Fall). Schließlich wird nach Bewertungen gesucht, die mit den Schweinefakten übereinstimmen, und der Wert für "flugfähig" in jeder Bewertung überprüft.

Nicht wenige Bytes gingen verloren, um den Status zu ändern: die Menge der bisher beobachteten Merkmale, die Pig-Fact-Selector-Funktion und die durch die Implikationen bestimmte Filterfunktion. Wahrscheinlich wäre die exakt gleiche Idee in einer unreinen Sprache viel kürzer.

Bearbeiten: Mehrere Bytes durch den Vorschlag von stolzem Haskeller gespeichert, dann ein paar zusätzliche Bytes, indem die Bindung von z und "u% drop 2 z" durch eine Bindung an "_: _: z" und "u% z" ersetzt und 3 gespeichert werden.

Bearbeiten 2: Mehr gespeichert. Verwendete den (#) = (,) Trick, um 2 Bytes zu sparen und lernte mehr über Mustersynonyme ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms ), aber die Notation war zu ausführlich, um Einsparungen zu erzielen Eliminieren Sie den Rest der Paare in diesem Programm. Sie haben weitere Einsparungen erzielt, indem Sie die Muster geändert haben, nach denen der Parser sucht. Beispiel: Wenn ein Satz nicht mit Pigs beginnt und im Parser-Status noch etwas übrig ist, wird der Satz "Everything that is .." analysiert. Dadurch wurden viele Zeichen in den Mustern für X und% gespeichert.


Ihre Vermutung ist richtig, ich habe vergessen, sie an erster Stelle zu erwähnen, aber ich habe sie jetzt in den Detailbereich aufgenommen!
Vauge

2
Sie sollten die Flags in Ihre Byteanzahl aufnehmen (siehe das Tag-Wiki für Code-Golf ). Daher sind es 607 Bytes.
Nyuszika7h

Ist das wirklich richtig? Der Link erwähnt nur Flags, die sich auf Unicode-Codierungen beziehen. Meta erwähnt ein ähnliches Problem in Bezug auf C ++ - Flags -D (ein offensichtlicher Betrüger) vs -std = c ++ 11 (Auswahl einer bestimmten Sprachvariante, also wahrscheinlich in Ordnung). IMO dienen die verwendeten Flags dazu, eine recht häufige GHC-Erweiterung von Haskell98 zu ermöglichen, daher analog zu -std = c ++ 11. Ref: meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan

Sie können Ihre zweite Definition von u mit ersetzen u n=(:)<$>[t,f]<*>u(n-1)(obwohl dies den Import von Control.Applicative erfordern würde, so ist es in zweiter
Linie

1
Sie können die Definition von c durchc 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

Für jedes Element a -> bin der Eingabe fügen wir die angegebene Klausel und ihre Negation not b -> not a zur Menge der Klauseln hinzu und berechnen dann die Menge der Sätze, die ->von jedem Satz aus mit einer Fixpunktschleife erreichbar sind. Immer wenn wir auf einen Widerspruch stoßen, werfen (und fangen) wir ein ZeroDivisionErrorund drucken Yes.

Schließlich prüfen wir, ob die Fähigkeit zum Fliegen (und / oder deren Negation) über den Vorschlag "Ist Schwein" erreichbar ist, ''und drucken die entsprechende Antwort aus.

EDIT : Dies ist fehlerhaft, es zu beheben. Fest.


1
Sie sollten in der Lage sein, 2 Bytes zu sparen, indem Sie den tryBlock in dieselbe Zeile stellen wietry:
undergroundmonorail

@undergroundmonorail: danke, dass du das gesehen hast! änderte es.
user2361830

5

Ruby 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'}

Verwendungszweck

Der obige Code definiert eine Funktion f, die einen Parameter , die die Texteingabe und kehrt nimmt Yes, Nooder Maybe.

Zum Beispiel:

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

Online-Test: http://ideone.com/fxLemg

Der Code ohne Golf (einschließlich Unit-Tests) ist hier verfügbar .


* sind verfügbar (unter Überschrift "Online-Test"). Plural, mein guter Freund.
Stan Strum

@StanStrum Danke! Ich habe den Text geändert - ich meine, der Code ist verfügbar und enthält auch Unit-Tests.
Cristian Lupascu
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.