돼지는 날 수 있습니까?


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. 주어진 진술은 유효하지만 일관성이 없습니다 (즉, 주어진 진술에 모순이 있음). 이후 전 falso 혼성 곡 , 우리는 출력을 결정하는 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 코드로 변환하는 답변을 작성하는 것을 고려하고 있습니다.
Tal

1
빨간색이 없다고 결론 내릴 수 있습니다. 달콤하고 빨간색이 아닌 것이 좋습니다.
user2357112

1
더 많은 예제를 기대하고 있었기 때문에 직접 할 수 있습니다.
cjfaure

1
@ xem : ex falso quodlibet, wikipedia에서 폭발의 원리로 찾아보십시오. 모순이 존재하면 무엇이든 입증 할 수 있습니다. 따라서 '신이 존재한다'는 것이 사실이고 '신이 존재하지 않는다'는 것이 사실이라면, 무엇이든지 사실로 보일 수 있으며, 따라서 돼지가 날 수 있다는 사실이 입증 될 수 있습니다.
fightermagethief

답변:


10

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
어떻게 작동하는지 / 의견을 적어 주시면 좋을 것입니다!
flawr

그리고 더 많은 의견에 대한 또 다른 공감대 ... 특히 더 자세한 설명이 필요하십니까?
Thaylon

더 많은 의견을 추가 ...
Thaylon

@AlanBerndt는 postfix를 제안했습니다. 그는 말을 할 수 없어서 승인 할 수 없습니다. 고마워요! 이리.
Thaylon

10

하스켈, 586 566547 바이트

나는 모든 속성 P에 대해 P (x) 가 참이고 P (y) 가 거짓 이되도록 어떤 xy 가 존재해야 한다는 가정하에 이것을 썼다 . 이 가정이 없으면 네 번째 예제 입력에는 모순이 없으며 "아니오"라고 대답합니다.

#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 #-}

그것은 특성 세트를 수집 한 다음 입력의 의미를 사용하여 특성 세트-> 진실 평가를 필터링하여 작동합니다. 그런 다음 모든 특성을 True와 False에 모두 올바르게 할당 할 수 있는지 확인하기 위해 결과를 테스트합니다 (여기서는 실패한 quodlibet 사례 임). 마지막으로 돼지의 사실과 일치하는 평가를 찾아 각 평가에서 "날 수있는"값을 확인합니다.

지금까지 본 특성 세트, pig-fact-selector 기능 및 그 영향에 의해 결정되는 필터링 기능 : 아마도 똑같은 생각은 불결한 언어에서 훨씬 짧을 것입니다.

편집 : 자랑스러운 haskeller의 제안에 의해 몇 바이트를 절약 한 다음 z와 "u % drop 2 z"의 바인딩을 "_ : _ : z"및 "u % z"에 대한 바인딩으로 바꾸어 몇 개를 추가하여 3을 절약했습니다.

편집 2 : 좀 더 저장되었습니다. (#) = (,) 트릭을 사용하여 2 바이트를 절약하고 패턴 동의어 ( https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms ) 에 대해 배웠지 만 표기법이 너무 길어서 이 프로그램에서 나머지 쌍을 제거합니다. 파서가 검색하는 패턴을 변경하여 더 많은 비용을 절감했습니다. 예를 들어, 문장이 Pigs로 시작하지 않고 구문 분석기 상태에 남아있는 것이 있으면 "Everything that is .."문장을 구문 분석합니다. 이것은 X와 %의 패턴에 많은 문자를 저장했습니다.


귀하의 가정이 맞습니다. 처음에 언급하지 않았지만 이제는 세부 사항 섹션에 추가했습니다!
vauge

2
당신은 당신의 바이트 수의 플래그합니다 (참조 포함해야한다 태그 위키 에 대한 코드 골프 ). 따라서 607 바이트입니다.
nyuszika7 시간

정말 맞습니까? 링크는 유니 코드 인코딩과 관련된 플래그 만 언급합니다. 메타는 C ++ 플래그 -D (명백한 속임수) 대 -std = c ++ 11 (특정 언어 변형 선택, 아마도 괜찮음)에 관한 비슷한 문제를 언급합니다. 사용 된 IMO 플래그는 Haskell98의 다소 일반적인 GHC 확장을 가능하게하기위한 것이므로 -std = c ++ 11과 유사합니다. 참조 : meta.codegolf.stackexchange.com/questions/1859/…
Matt Noonan

u에 대한 두 번째 정의를 다음으로 대체 할 수 있습니다 u n=(:)<$>[t,f]<*>u(n-1)(Control.Applicative를 가져와야하지만 두 번째 생각에서는 더 나쁩니다)
자랑스러운 haskeller

1
c의 정의를 다음과 같이 대체 할 수 있습니다.c l=(all(==l!!0)l,and l)
proud 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.

마지막으로, 우리는 '돼지'제안에서 '비행 가능'(및 / 또는 부정)에 도달 할 수 있는지 확인 ''하고 적절한 응답을 인쇄합니다.

편집 : 이것은 버그, 수정입니다. 결정된.


1
다음 try과 같은 줄에 블록을 배치하여 2 바이트를 절약 할 수 있어야합니다.try:
undergroundmonorail

@undergroundmonorail : 그것을 발견해 주셔서 감사합니다! 그것을 바꿨다.
user2361830

5

루비 1.9.3 ( 365 364362 )

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 코드 (단위 테스트 포함)는 여기에서 확인할 수 있습니다 .


* 사용 가능합니다 ( "온라인 테스트"헤더 아래). 복수, 내 좋은 친구.
Stan Strum

@StanStrum 감사합니다! 텍스트를 수정했습니다. 코드 사용할 수 있으며 단위 테스트도 포함되어 있습니다.
Cristian Lupascu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.