Apakah Babi bisa terbang?

45

Tugas

Tugas Anda adalah menulis fungsi atau program dalam bahasa pilihan Anda yang menganalisis beberapa pernyataan dan menentukan apakah dapat disimpulkan dari pernyataan-pernyataan yang dapat diterbangkan babi.

Memasukkan

Input adalah sebuah String yang dapat dibaca dari STDIN, diambil sebagai argumen fungsi atau bahkan disimpan dalam file. Input dapat dijelaskan menggunakan EBNF berikut:

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

Input contoh (lihat lebih banyak contoh di bawah):

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

Keluaran

Output dapat dikembalikan oleh fungsi Anda, ditulis ke file atau dicetak ke STDOUT. Ada 5 kasus berbeda yang harus ditangani:

  1. Pernyataan yang diberikan valid, konsisten dan memiliki konsekuensi logis bahwa babi dapat terbang. Dalam hal ini, Anda harus menampilkan Yes.
  2. Pernyataan yang diberikan valid, konsisten dan memiliki konsekuensi logis bahwa babi tidak bisa terbang. Dalam hal ini, Anda harus menampilkan No.
  3. Tidak dapat disimpulkan dari pernyataan yang diberikan, valid dan konsisten apakah babi bisa terbang atau tidak. Dalam hal ini, Anda harus menampilkan Maybe.
  4. Pernyataan yang diberikan valid, tetapi tidak konsisten (yaitu ada kontradiksi dalam pernyataan yang diberikan). Sejak ex falso quodlibet , kami memutuskan untuk menampilkan Yesdalam hal ini.
  5. Pernyataan yang diberikan tidak valid, yaitu tidak diformat sesuai dengan EBNF yang diberikan. Dalam hal ini, Anda dapat melakukan apa pun yang Anda inginkan.

Detail

  • Anda dapat mengasumsikan bahwa atribut yang diberikan independen satu sama lain. Jadi, misalnya, babi mungkin muda dan tua, hijau, merah dan biru pada saat yang sama tanpa menyebabkan ketidakkonsistenan. Namun, babi mungkin tidak 'hijau' dan 'tidak hijau' pada saat yang sama, itu kontradiksi dan harus ditangani sebagaimana dijelaskan dalam (4).
  • Untuk setiap atribut, asumsikan bahwa setidaknya ada satu objek (tidak harus seekor babi) di alam semesta yang memiliki atribut yang diberikan, dan satu objek yang tidak memilikinya.

Contoh Input & Output

Memasukkan:

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

Keluaran: Karena Babi berwarna hijau dan karena itu cerdas, dan segala sesuatu yang dapat terbang tidak cerdas, babi tidak bisa terbang. Output adalah No.

Memasukkan:

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

Keluaran: Jika babi tidak bisa terbang, mereka juga tidak tua. Tetapi karena mereka sudah tua, Anda harus keluar Yes.

Memasukkan:

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

Output: Maybe .

Memasukkan:

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

Keluaran: Walaupun pernyataan pertama menyiratkan bahwa babi tidak dapat terbang, pernyataan berikut ini saling bertentangan dan oleh karena itu hasilnya haruslah Yes.

Memasukkan:

Pigs are very smart. Pigs are able to fly. 

Output: Apa pun yang Anda inginkan, karena String tidak cocok dengan kriteria yang disebutkan di atas.

Pemenang

Ini adalah , jadi jawaban terpendek yang benar (dalam byte) menang. Pemenang akan dipilih satu minggu setelah jawaban pertama yang benar diposting.

Seekor Babi terbang

sangat besar
sumber
mengapa contoh ketiga kembali ya?
xem
10
Saya sedang mempertimbangkan untuk menulis jawaban yang menerjemahkan input ke dalam kode Prolog.
Tal
1
Anda hanya dapat menyimpulkan bahwa tidak ada merah. Manis, hal-hal yang bukan merah baik-baik saja.
user2357112
1
Saya berharap lebih banyak contoh, supaya saya bisa melakukannya sendiri.
cjfaure
1
@xem: ex falso quodlibet, cari di wikipedia sebagai prinsip ledakan. Jika ada kontradiksi, maka apa pun bisa dibuktikan. Jadi jika 'tuhan ada' adalah benar dan 'tuhan tidak ada' adalah benar, apa pun dapat terbukti benar, oleh karena itu babi dapat terbang dapat dibuktikan benar.
fightermagethief

Jawaban:

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

Tidak Disatukan / Penjelasan:

# 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
Thaylon
sumber
4
Akan lebih bagus jika Anda bisa memberi tahu kami cara kerjanya / menulis beberapa komentar!
flawr
Dan upvote lain untuk lebih banyak komentar ... sesuatu yang khusus perlu penjelasan lebih lanjut?
Thaylon
Menambahkan lebih banyak komentar ...
Thaylon
@AlanBerndt menyarankan postfix sementara. Karena dia tidak bisa berkomentar dan saya tidak bisa menyetujui. Saya ingin mengucapkan terima kasih! sini.
Thaylon
10

Haskell, 586 566 547 bytes

Saya menulis ini dengan asumsi bahwa untuk setiap properti P pasti ada beberapa x dan y sedemikian sehingga P (x) benar dan P (y) salah; tanpa asumsi ini, contoh input keempat tidak akan memiliki kontradiksi dan akan menjawab "Tidak".

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

Ini harus dikompilasi dengan opsi baris perintah ghc "-cpp". Input harus diakhiri oleh EOF (^ D). Anda dapat mencobanya online di http://melpon.org/wandbox/ , tetapi Anda tidak dapat mengatur opsi baris perintah. Sebagai gantinya, Anda dapat mengawali program dengan opsi bahasa

{-# LANGUAGE CPP #-}

Ia bekerja dengan mengumpulkan seperangkat sifat, kemudian menyaring set penilaian sifat -> kebenaran menggunakan implikasi dalam input. Hasilnya kemudian diuji untuk memastikan bahwa setiap sifat dapat secara benar ditugaskan untuk Benar dan Salah (kegagalan di sini adalah kasus ex falso quodlibet ). Akhirnya, ia mencari penilaian yang sesuai dengan fakta babi, memeriksa nilai "mampu terbang" di setiap penilaian.

Cukup beberapa byte yang hilang ke keadaan threading sekitar: seperangkat sifat yang terlihat sejauh ini, fungsi pemilih-fakta-babi, dan fungsi penyaringan ditentukan oleh implikasinya. Mungkin ide yang persis sama akan jauh lebih pendek dalam bahasa yang tidak murni.

Sunting: Disimpan beberapa byte oleh saran haskeller bangga, lalu beberapa tambahan dengan mengganti pengikatan z dan "u% drop 2 z" dengan mengikat ke "_: _: z" dan "u% z", menghemat 3.

Sunting 2: Disimpan lagi. Menggunakan trik (#) = (,) untuk menyimpan 2 byte dan belajar tentang sinonim pola ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonymous ), tetapi notasinya terlalu bertele-tele untuk mendapatkan penghematan dari menghilangkan sisa pasangan dalam program ini. Peras lebih banyak penghematan dengan mengubah pola yang dicari parser. Misalnya: jika sebuah kalimat tidak dimulai dengan Babi dan kami memiliki sesuatu yang tersisa dalam status pengurai, kami menguraikan kalimat "Segala sesuatu yang ..". Ini menyimpan banyak karakter dalam pola untuk X dan%.

Matt Noonan
sumber
Asumsi Anda benar, saya lupa menyebutkannya di tempat pertama tetapi saya sekarang telah menambahkannya ke bagian detail!
vauge
2
Anda harus menyertakan flag dalam jumlah byte Anda (lihat tag wiki untuk kode-golf ). Oleh karena itu, 607 byte.
nyuszika7h
Apakah itu benar? Tautan hanya menyebutkan flag yang terkait dengan pengkodean unicode; meta menyebutkan masalah serupa mengenai flag C ++ -D (cheat yang jelas) vs -std = c ++ 11 (memilih variasi bahasa tertentu, jadi mungkin ok). IMO flag yang digunakan adalah untuk mengaktifkan ekstensi GHC yang agak umum dari Haskell98, karenanya analog dengan -std = c ++ 11. Ref: meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan
Anda dapat mengganti definisi kedua Anda dengan u n=(:)<$>[t,f]<*>u(n-1)(meskipun ini akan membutuhkan pengimporan Control.Applicative, jadi menurut Anda itu lebih buruk)
haskeller bangga
1
Anda dapat mengganti definisi c denganc l=(all(==l!!0)l,and l)
haskeller bangga
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

Untuk masing-masing a -> binput, kami menambahkan klausa yang diberikan dan negasinya not b -> not a ke himpunan klausa dan kemudian menghitung set proposisi yang dapat ->dijangkau dari proposisi apa pun menggunakan loop fixpoint. Setiap kali kita menemukan kontradiksi, kita melempar (dan kemudian menangkap) a ZeroDivisionErrordan mencetak Yes.

Akhirnya, kami memeriksa apakah 'mampu terbang' (dan / atau negasinya) dapat dijangkau dari proposisi 'is pig' ''dan mencetak respons yang sesuai.

EDIT : Ini buggy, memperbaikinya. Tetap.

pengguna2361830
sumber
1
Anda harus dapat menghemat 2 byte dengan meletakkan tryblok pada baris yang sama dengantry:
undergroundmonorail
@undergroundmonorail: terima kasih telah melihatnya! mengubahnya.
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'}

Pemakaian

Kode di atas mendefinisikan fungsi f, yang mengambil satu parameter yang mewakili masukan tekstual dan kembali Yes, Noatau Maybe.

Sebagai contoh:

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

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

Kode ungolfed (termasuk tes unit) tersedia di sini .

Cristian Lupascu
sumber
* tersedia (di bawah tajuk "tes online"). Bentuk jamak, teman baik saya.
Stan Strum
@StanStrum Terima kasih! Aku diubah teks - maksud saya kode yang tersedia dan juga termasuk tes unit.
Cristian Lupascu