Чи здатні Свині літати?


45

Завдання

Ваше завдання полягає в тому, щоб написати функцію або програму мовою на ваш вибір, яка аналізує пару тверджень і визначає, чи можна зробити висновок із тих тверджень, що свині здатні літати.

Вхідні дані

Вхід - це рядок, яку можна прочитати з STDIN, взяти її як аргумент функції або навіть зберегти у файлі. Вхід може бути описаний за допомогою наступного 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" ;

Приклад введення (див. Більше прикладів нижче):

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

Вихід

Вихід може бути повернутий вашою функцією, записати у файл або роздрукувати в STDOUT. Є 5 різних випадків, які потрібно вирішити:

  1. Наведені твердження є дійсними, послідовними та мають логічний наслідок того, що свині можуть літати. У такому випадку потрібно вивести результат Yes.
  2. Наведені твердження справедливі, послідовні і мають як логічний наслідок, що свині не можуть літати. У такому випадку потрібно вивести результат No.
  3. З наведених, дійсних та послідовних тверджень не можна зробити висновок, чи можуть свині літати чи ні. У такому випадку потрібно вивести результат Maybe.
  4. Наведені висловлювання є дійсними, але не є послідовними (тобто є суперечність у даних твердженнях). Оскільки ex falso quodlibet , ми вирішуємо вивести Yesу цьому випадку.
  5. Наведені заяви не є дійсними, тобто вони не форматовані відповідно до даного EBNF. У такому випадку ви можете робити все, що завгодно.

Деталі

  • Можна припустити, що дані атрибути не залежать один від одного. Так, наприклад, свиня може бути одночасно молодою та старшою, зеленою, червоною та синьою, не викликаючи жодної непослідовності. Однак свиня може бути не "зеленою" і "не зеленою" одночасно, це суперечність і з нею слід поводитися, як описано в (4).
  • Для кожного атрибуту припустіть, що у Всесвіті є принаймні один об'єкт (не обов'язково свиня), який має даний атрибут, і один об'єкт, який його не має.

Приклади входів та виходів

Вхід:

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

Вихід: Оскільки свині зелені і, отже, розумні, і все, що вміє літати, не є розумним, свині не можуть літати. Вихід є No.

Вхід:

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

Вихід: Якщо свині не змогли літати, вони також не були старими. Але як вони старі, ви повинні вивести Yes.

Вхід:

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

Вихід: Maybe .

Вхід:

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

Результат: Хоча з першого твердження випливає, що свині не можуть літати, наступні твердження суперечать одне одному, і тому вихід повинен бути Yes.

Вхід:

Pigs are very smart. Pigs are able to fly. 

Вихід: Що б ви не хотіли, так як String не відповідає зазначеним вище критеріям.

Переможець

Це , тому найкоротша правильна відповідь (у байтах) виграє. Переможець буде обраний через тиждень після опублікування першої правильної відповіді.

Літаюча Свиня


чому третій приклад повертає так?
xem

10
Я розглядаю можливість відповіді, яка переводить вхід у код Prolog.
Тал

1
Можна лише зробити висновок, що нічого червоного не існує. Солодкі, не червоні речі - це добре.
користувач2357112

1
Я сподівався на більше прикладів, просто щоб я міг їх зробити сам.
cjfaure

1
@xem: ex falso quodlibet, розгляньте це на wikipedia як принцип вибуху. Якщо існує суперечність, то можна довести що завгодно. Отже, якщо «бог існує» є істинним, а «бога не існує» є істинним, все може бути показано правдою, тому свині можуть літати, може бути доведено правдою.
винищувач, головний керівник

Відповіді:


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

Недоліковані / Пояснення:

# 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
Було б чудово, якби ви могли сказати нам, як це працює / написати кілька коментарів!
недолік

І ще одна пропозиція для отримання додаткових коментарів ... щось зокрема потребує більше пояснень?
Тайлон

Додано ще більше коментарів ...
Thaylon

@AlanBerndt запропонував постфікс на той час. Оскільки він не може коментувати, і я не можу схвалити. Я хотів би сказати спасибі! тут.
Тайлон

10

Haskell, 586 566 547 байт

Я написав це, припускаючи, що для кожної властивості P повинно існувати деяка x і y така, що P (x) є істинним, а P (y) - хибним; без цього припущення, четвертий приклад прикладу не мав би суперечності і відповів би "Ні".

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

Це слід скласти за допомогою параметра командного рядка ghc "-cpp". Введення має бути закінчене EOF (^ D). Ви можете спробувати його в Інтернеті за адресою http://melpon.org/wandbox/ , але ви не можете встановити параметри командного рядка. Натомість ви можете встановити префікс програми за допомогою мови

{-# LANGUAGE CPP #-}

Він працює, збираючи набір ознак, потім фільтруючи набір ознак -> оцінки істини, використовуючи наслідки вхідних даних. Потім результат перевіряється, щоб гарантувати, що кожна ознака може бути присвоєна істинному, і хибному (тут відмова є випадком колишнього кводлібету ). Нарешті, він шукає оцінки, які відповідають фактам свиней, перевіряючи значення "здатного літати" у кожній оцінці.

До стану потоків навколо було втрачено досить багато байтів: набір дотепер ознак, функція селектора фактів свиней та функція фільтрації, що визначається наслідками. Можливо, саме така ідея була б набагато коротшою в нечистій мові.

Редагувати: збережено кілька байтів за пропозицією гордого haskeller, потім ще кілька додаткових, замінивши прив’язку z та "u% drop 2 z" на прив'язку до "_: _: z" та "u% z", заощаджуючи 3.

Редагувати 2: збережено ще кілька. Використовували трюк (#) = (,), щоб зберегти 2 байти та дізналися про синоніми шаблону ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms ), але позначення були надто багатослівними, щоб отримати заощадження усунення решти пар у цій програмі. Знищив ще трохи економії, змінивши шаблони, за якими шукає аналізатор. Наприклад: якщо речення не починається з Pigs, і у нас є щось, що залишилося в синтаксичному синтаксичному аналізі, ми розбираємо пропозицію "Все, що є .." Це зберегло багато символів у шаблонах для X та%.


Ваше припущення правильне, я забув згадати це в першу чергу, але тепер додав його до розділу деталей!
vauge

2
Ви повинні включити прапори до числа байтів (див. Тег wiki для коду-гольфу ). Тому це 607 байт.
nyuszika7h

Це дійсно правильно? У посиланні згадуються лише прапори, пов'язані з кодуванням unicode; meta згадує подібну проблему щодо C ++ прапорів -D (очевидний чіт) проти -std = c ++ 11 (вибір конкретної варіації мови, так що, ймовірно, добре). Прапорці IMO, які використовуються, призначені для включення досить поширеного GHC-розширення Haskell98, отже, аналогічно -std = c ++ 11. Посилання: meta.codegolf.stackexchange.com/questions/1859/…
Метт Нунан

ви можете замінити своє друге визначення u на u n=(:)<$>[t,f]<*>u(n-1)(хоча це потребує імпорту Control.Applicative, тому, по-друге, це гірше)
гордий haskeller

1
ви можете замінити визначення c наc l=(all(==l!!0)l,and l)
гордий haskeller

6

Пітона, 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

Для кожного a -> bз вхідних даних ми додаємо дане застереження та його заперечення not b -> not a до набору пропозицій, а потім обчислюємо набір пропозицій, ->доступних для будь-якого пропозиції, використовуючи цикл фіксованої точки. Кожного разу, коли ми стикаємося з протиріччям, ми кидаємо (а пізніше виловлюємо) а ZeroDivisionErrorта друкуємо Yes.

Нарешті, ми перевіряємо, чи доступний "здатний літати" (та / або його заперечення) із пропозиції "є свиня" ''та друкуємо відповідну відповідь.

EDIT : Це помилка, виправлення. Виправлено.


1
ви повинні бути в змозі зберегти 2 байти, поставивши tryблок на ту саму лінію, що іtry:
undergroundmonorail

@undergroundmonorail: дякую, що помітили це! змінив його.
user2361830

5

Рубін 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'}

Використання

Вище код визначає функцію f, яка приймає один параметр , який представляє текстовий введення і повертається Yes, Noабо Maybe.

Наприклад:

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

Тест в Інтернеті: http://ideone.com/fxLemg

Ungolfed код ( в тому числі модульних тестів) доступний тут .


* доступні (під заголовком "онлайн-тест"). Множина, мій добрий друже.
Стен Струм

@StanStrum Дякую! Я змінив текст - я маю в виду код є доступним і він також включає в себе модульні тести.
Крістіан Лупаску
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.