I maiali sono in grado di volare?


45

Compito

Il tuo compito è scrivere una funzione o un programma in una lingua a tua scelta che analizzi un paio di affermazioni e determini se da quelle affermazioni si può concludere che i maiali sono in grado di volare.

Ingresso

L'input è una stringa che può essere letta da STDIN, presa come argomento di funzione o addirittura memorizzata in un file. L'ingresso può essere descritto usando il seguente EBNF:

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

Esempio di input (vedere altri esempi di seguito):

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

Produzione

L'output può essere restituito dalla funzione, essere scritto in un file o stampato su STDOUT. Esistono 5 casi diversi da gestire:

  1. Le dichiarazioni fornite sono valide, coerenti e hanno come conseguenza logica che i maiali possono volare. In tal caso, è necessario eseguire l'output Yes.
  2. Le dichiarazioni fornite sono valide, coerenti e hanno come conseguenza logica che i maiali non possono volare. In tal caso, è necessario eseguire l'output No.
  3. Non si può concludere dalle affermazioni fornite, valide e coerenti se i suini possano volare o meno. In tal caso, è necessario eseguire l'output Maybe.
  4. Le dichiarazioni fornite sono valide, ma non coerenti (ovvero c'è una contraddizione nelle dichiarazioni fornite). Poiché ex falso quodlibet , decidiamo di produrre Yesin quel caso.
  5. Le istruzioni fornite non sono valide, ovvero non sono formattate in base al dato EBNF. In tal caso, puoi fare quello che vuoi.

Dettagli

  • Si può presumere che gli attributi dati siano indipendenti l'uno dall'altro. Quindi, ad esempio, un maiale può essere giovane e vecchio, verde, rosso e blu allo stesso tempo senza causare incoerenze. Tuttavia, un maiale potrebbe non essere "verde" e "non verde" allo stesso tempo, è una contraddizione e dovrebbe essere gestito come descritto in (4).
  • Per ogni attributo, supponi che ci sia almeno un oggetto (non necessariamente un maiale) nell'universo che ha l'attributo dato e un oggetto che non lo possiede.

Ingressi e uscite di esempio

Ingresso:

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

Risultato: poiché i maiali sono verdi e quindi intelligenti e tutto ciò che è in grado di volare non è intelligente, i maiali non possono volare. L'output è No.

Ingresso:

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

Risultato: se i maiali non erano in grado di volare, non erano nemmeno vecchi. Ma poiché sono vecchi, è necessario produrre Yes.

Ingresso:

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

Uscita: Maybe .

Ingresso:

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

Output: Sebbene la prima affermazione implichi che i maiali non possono volare, le seguenti affermazioni si contraddicono a vicenda e quindi l'output deve essere Yes.

Ingresso:

Pigs are very smart. Pigs are able to fly. 

Output: Qualunque cosa tu voglia, poiché la stringa non corrisponde ai criteri sopra menzionati.

Vincitore

Questo è , quindi vince la risposta corretta più breve (in byte). Il vincitore verrà scelto una settimana dopo la pubblicazione della prima risposta corretta.

Un maiale volante


perché il terzo esempio restituisce sì?
xem,

10
Sto pensando di scrivere una risposta che traduca l'input nel codice Prolog.
Tal

1
Puoi solo concludere che non esiste nulla di rosso. Le cose dolci e non rosse vanno bene.
user2357112

1
Speravo in più esempi, solo per poterli fare da solo.
cjfaure,

1
@xem: ex falso quodlibet, cercalo su wikipedia come principio di esplosione. Se esiste una contraddizione, allora tutto può essere provato. Quindi se "dio esiste" è vero e "dio non esiste" è vero, qualsiasi cosa può essere dimostrata vera, quindi i maiali possono volare possono essere dimostrati veri.
fightermagethief,

Risposte:


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 / Spiegazione:

# 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
Sarebbe bello se tu potessi dirci come funziona / scrivere alcuni commenti!
Flawr

E un altro voto per ulteriori commenti ... qualcosa in particolare ha bisogno di più spiegazioni?
Thaylon

Aggiunti ancora più commenti ...
Thaylon

@AlanBerndt ha suggerito un postfix mentre. Dal momento che non può commentare e non posso approvare. Vorrei dire grazie! Qui.
Thaylon,

10

Haskell, 586 566 547 byte

Ho scritto questo presupponendo che per ogni proprietà P debbano esistere alcuni x e y tali che P (x) è vero e P (y) è falso; senza questa ipotesi, il quarto esempio di input non avrebbe contraddizioni e risponderebbe "No".

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

Questo dovrebbe essere compilato con l'opzione della riga di comando ghc "-cpp". L'ingresso deve essere terminato da EOF (^ D). Puoi provarlo online su http://melpon.org/wandbox/ , ma non puoi impostare le opzioni della riga di comando. Invece, puoi aggiungere il prefisso al programma con l'opzione lingua

{-# LANGUAGE CPP #-}

Funziona raccogliendo l'insieme di tratti, quindi filtrando l'insieme di tratti -> valutazioni di verità usando le implicazioni nell'input. Il risultato viene quindi testato per garantire che ogni caratteristica possa essere validamente assegnata a Vero e Falso (il fallimento qui è il caso del quodlibet ex falso ). Infine, cerca le valutazioni che corrispondono ai fatti del maiale, controllando il valore di "in grado di volare" in ogni valutazione.

Parecchi byte sono andati persi nello stato di threading: l'insieme di tratti visti finora, la funzione selettore fatto suino e la funzione di filtro determinata dalle implicazioni. Probabilmente la stessa identica idea sarebbe molto più breve in un linguaggio impuro.

Modifica: salvati diversi byte con il suggerimento di haskeller orgoglioso, quindi un paio extra sostituendo il legame di z e "u% drop 2 z" con un legame a "_: _: z" e "u% z", salvando 3.

Modifica 2: salvato ancora. Ho usato il trucco (#) = (,) per salvare 2 byte e ho imparato i sinonimi dei pattern ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonym ), ma la notazione era troppo dettagliata per ottenere un risparmio da eliminando il resto delle coppie in questo programma. Spremuto un po 'di più risparmiando modificando i modelli che il parser cerca. Ad esempio: se una frase non inizia con Maiali e rimane qualcosa nello stato di analisi, analizziamo una frase "Tutto ciò che è ..". Ciò ha salvato un sacco di caratteri nei motivi per X e%.


Il tuo presupposto è corretto, ho dimenticato di menzionarlo in primo luogo, ma ora l'ho aggiunto alla sezione dei dettagli!
vauge

2
Dovresti includere i flag nel conteggio dei byte (vedi il tag wiki per code-golf ). Pertanto, è 607 byte.
nyuszika7h,

È davvero corretto? Il collegamento menziona solo flag relativi alle codifiche Unicode; meta menziona un problema simile per quanto riguarda i flag C ++ -D (un evidente trucco) vs -std = c ++ 11 (selezionando una specifica variazione di lingua, quindi probabilmente ok). IMO i flag utilizzati servono per abilitare un'estensione GHC piuttosto comune di Haskell98, quindi analoga a -std = c ++ 11. Rif: meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan

puoi sostituire la tua seconda definizione di u con u n=(:)<$>[t,f]<*>u(n-1)(anche se ciò richiederebbe l'importazione di Control.Applicative, quindi in secondo luogo è peggio)
orgoglioso haskeller il

1
puoi sostituire la definizione di c conc l=(all(==l!!0)l,and l)
haskeller orgoglioso

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

Per ognuno a -> bnell'input, aggiungiamo la clausola data e la sua negazione not b -> not a all'insieme di clausole e quindi calcoliamo l'insieme di proposizioni che sono ->raggiungibili da qualsiasi proposizione usando un ciclo di fixpoint. Ogni volta che incontriamo una contraddizione, lanciamo (e successivamente catturiamo) un ZeroDivisionErrore stampiamo Yes.

Infine, controlliamo se "in grado di volare" (e / o la sua negazione) è raggiungibile dalla proposizione "is pig" ''e stampiamo la risposta appropriata.

EDIT : Questo è un bug, risolvendolo. Fisso.


1
dovresti essere in grado di salvare 2 byte posizionando il tryblocco sulla stessa linea ditry:
undergroundmonorail

@undergroundmonorail: grazie per averlo individuato! l'ha cambiato.
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'}

uso

Il codice sopra definisce una funzione fche accetta un parametro che rappresenta l'input testuale e ritorna Yes, Noo Maybe.

Per esempio:

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

Test online: http://ideone.com/fxLemg

Il codice non golfato (inclusi i test unitari) è disponibile qui .


* sono disponibili (sotto l'intestazione "test online"). Plurali, mio ​​buon amico.
Stan Strum,

@StanStrum Grazie! Ho modificato il testo - intendo che il codice è disponibile e include anche test unitari.
Cristian Lupascu,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.