알렉스가 때때로 옳다


50

이 문제는 우리 모드의 영혼 들어하는 것입니다 알렉스 A. 일반적으로, 잘못을 .


기본 논리와 수학, 특히 수학적 동등성에 대한 도움이 필요한 Alex라는 친구가 있다고 가정합니다 .

그는 [variable] = [variable]a [variable]가 항상 단일 대문자 A에서 Z (소문자가 아닌 숫자가 아닌 다른 형식) 인 형식의 방정식 목록을 제공합니다 . 이라고 만 표시된 단일 행을 제외하고 목록에 한 행에 하나의 방정식이 있습니다 therefore.

위의 모든 방정식 therefore전제 이며 사실입니다. 아래의 모든 방정식 therefore은 확인되지 않은 제안, Alex가 구내에서 추론하려고한다는 사실이며, 사실 일 수도 있고 아닐 수도 있습니다.

예를 들어,이 방정식 목록에서 단일 결론 제안 A = C은 사실입니다.

A = B
B = C
therefore
A = C

이 경우 알렉스에게 당신의 직업 의 모든 그의 명제는 논리적으로 주어진 전제에서 수행합니다. 즉, Alex가 자신의 결론에서 틀렸거나 옳은지 알 필요가 있습니다.

설명 된대로 일련의 방정식 목록을 취하는 프로그램 / 함수를 작성하고 인쇄 / 반환

Alex is right

모든 결론이 구내에서 논리적으로 따르고 그렇지 않으면 출력

Alex is wrong

구내에서 논리적으로 결론을 따르지 않는 경우.

바이트 단위의 가장 짧은 코드가 이깁니다.

다음과 같은 경우에주의하십시오.

  • 변수는 항상 자신과 같습니다. 예 :

    B = A
    therefore
    A = A
    X = X
    

    결과 Alex is right.

  • 관계가 알려지지 않은 변수는 동일하다고 가정 할 수 없습니다. 예 :

    P = Q
    therefore
    E = R
    

    결과 Alex is wrong.

  • therefore그 이후에 방정식이 없으면 결론은 명백하게 사실 입니다. 예 :

    D = C
    therefore

    therefore

    둘 다 결과 Alex is right.

  • 이전에 방정식이 없으면 therefore자기 평등 만 유추 할 수 있습니다. 예 :

    therefore
    R = R
    

    결과는 Alex is right되지만

    therefore
    R = W
    

    결과 Alex is wrong.

더 많은 예

Alex가 잘못된 경우 : (빈 줄로 구분)

A = B
C = D
therefore
A = C

A = L
E = X
A = I
S = W
R = O
N = G
therefore
G = N
L = I
R = O
S = A
X = X
X = E

D = K
D = Q
L = P
O = L
M = O
therefore
K = L

A = B
therefore
B = C

Z = A
S = S
therefore
A = Z
A = A
S = A
A = S
Z = A
Z = A

K = L
K = X
therefore
X = P
L = X
L = P

therefore
A = B
B = C
A = C

therefore
A = A
B = B
C = C
D = D
E = E
F = F
G = G
H = H
I = I
J = J
K = K
T = I
L = L
M = M
N = N
O = O
P = P
Q = Q
R = R
S = S
T = T
U = U
V = V
W = W
X = X
Y = Y
Z = Z

A = B
B = C
C = D
D = E
E = F
F = G
G = H
H = I
I = J
J = K
K = L
L = M
M = N
N = O
O = P
P = O
Q = R
R = S
S = T
T = U
U = V
V = W
W = X
X = Y
Y = Z
therefore
A = Z

therefore
C = D
T = Y
A = Z

P = Q
therefore
E = R

therefore
R = W

알렉스는 올바른 경우입니다.

H = J
therefore
J = H

K = L
K = X
therefore
L = X

C = B
B = A
therefore
A = B

K = L
K = X
K = P
therefore
L = X
L = P
X = P

A = Y
Y = Q
Q = O
therefore
O = Y
O = A

C = C
therefore
C = C

A = B
B = A
therefore
A = B
B = A

A = B
B = C
C = D
therefore
A = A
A = B
A = C
A = D
B = A
B = B
B = C
B = D
C = A
C = B
C = C
C = D
D = A
D = B
D = C
D = D

therefore
A = A
B = B
C = C
D = D
E = E
F = F
G = G
H = H
I = I
J = J
K = K
L = L
M = M
N = N
O = O
P = P
Q = Q
R = R
S = S
T = T
U = U
V = V
W = W
X = X
Y = Y
Z = Z

D = I
F = H
J = M
therefore
M = J
D = I
H = F

A = B
B = C
C = D
D = E
E = F
F = G
G = H
H = I
I = J
J = K
K = L
L = M
M = N
N = O
O = P
P = Q
Q = R
R = S
S = T
T = U
U = V
V = W
W = X
X = Y
Y = Z
therefore
Z = A
F = R
G = I
W = L

A = B
B = C
therefore
A = C

B = A
therefore
A = A
X = X

P = P
C = G
M = C
therefore

D = C
therefore

therefore

therefore
R = R

42
PHP, 13 bytes Alex is wrong모든 테스트 사례를 확인합니다.
Dennis

19
이따금 때로는 결코 낫지 않습니다. ¯ \ _ (ツ) _ / ¯
Alex A.


7
therefore\nTABS < SPACES->Alex is right
Doorknob

7
프롤로그에서 해결책을보고 싶어요.
azz

답변:


18

CJam, 49

"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?

histocrat의 Ruby 솔루션에서 영감을 얻었습니다. jimmy23013 덕분에 3 바이트가 없어지면 온라인으로 사용해보십시오.
:)

설명:

각 전제에 대해 프로그램은 나머지 텍스트에서 첫 번째 변수를 두 번째 변수로 바꿉니다. 그런 다음 변수가 다른 결론이 있는지 확인합니다.

"Alex is "    first push the part we know
qN%           read the input and split into lines
S             push a space (initial no-op replacement string, see below)
{…}h          do-while
  f{…}        for each line and the replacement string
    )         take out the last character
    er        replace the remaining character(s) with that character
  (           afterwards, take out the first line
  _el         duplicate and convert to lowercase
  -           remove all the resulting characters from the line
               this removes all lowercase letters and non-letters
               "X = Y" becomes "XY" (new replacement string)
               and "therefore" becomes "" (ending the loop)
              this is the loop condition and is left on the stack every time
;             after the loop, pop the empty string (from "therefore")
{…},          filter the remaining (conclusion) lines using the condition block
  )           take out the last character
  #           find its index in the remaining string
               this is 0 (false) iff the first character is the same as the last
              afterwards, we have an array of lines with non-equal variables
"wrong"       push "wrong"
"right"       push "right"
?             choose "wrong" if the array was not empty, else choose "right"

구버전, 85

"Alex is "26,:A;{:i{{_A=_@-}g}%$~}:F;0q"= "-'t/Nf%~\{A\Ft:A;}/1>{F=}%-"right""wrong"?

이것은 공용체 찾기 알고리즘을 사용합니다. 온라인으로 사용해보십시오


1
"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?.
jimmy23013

1
방금 마지막 줄을 ' 유니콘 찾기 알고리즘을 사용합니다 '라고 읽었습니다. xD
Jan

Alex is * wrong * right * ?
Charlie

32

루비, 80 76 + 2 = 78

명령 행 플래그 p0를 사용하여

gsub$1,$2%p=$`[/e/]while~/(.) = (?!\1)(.)/
$_="Alex is #{p ?:wrong: :right}"

설명:

순수한 문자열 조작을 사용합니다. p0전체 입력을 변수에 단일 문자열로 읽습니다 $_. 그런 다음 해당 문자열을 정규 표현식과 반복해서 일치시킵니다. /(.) = (?!\1)(.)/여기서 "X = Y"형식의 모든 문자열을 찾습니다. 여기서 X와 Y는 같은 문자가 아니며 X를 $ 1에, Y를 $ 2에 할당합니다. 이러한 일치가 발견되면 gsub$1,$2문자열에서 X의 모든 인스턴스를 Y로 바꿉니다. 또한이 일치 항목이 "thefore"이전 또는 이후에 발생했는지 확인합니다.

$`[/e/]

이후에 발생한 경우 정당하지 않은 주장이며 Alex가 잘못되었습니다. 를 사용하여 이러한 발생이 발생했는지 추적합니다 p=. p추적 변수로 사용 하면 루프가 한 번도 적중하지 않으면 일이 중단 p되지 않습니다. 할당되지 않은 경우 nil을 반환하기 때문입니다.

이 게시물을 기준으로 CJam 솔루션은 더 길다. 의심의 여지없이 잠깐의 순간.

편집 : 예, 빨리 결정됩니다. 또한, 설명을 끝내기 위해 p플래그 와 함께 최종 값 $_이 실행이 끝날 때 출력되므로 마지막 줄이 출력됩니다.


15
가장 달콤한 순간은 자신의 솔루션이 esolang에 의해 학살되기 전의 순간입니다.
Alex A.

String#formatgsub 호출과 할당을 하나의 표현으로 만드는 학대는 매우 깔끔한 아이디어입니다. +1!
Ventero

12

CJam, 83 75 68 67 64 바이트

1 바이트를 절약 해 준 Dennis에게 감사합니다.

"Alex is "q_elN--N/:$La/~{)-},\{__m*{:&},::^|}5*-"wrong""right"?

테스트 스위트. 테스트 케이스가 퍼머 링크에 비해 너무 길기 때문에 질문에서 간단히 복사하십시오. 온라인 인터프리터에서 1-2 분이 소요됩니다. 이 경우 거의 즉시 완료하고 하나의 테스트 사례를 제외한 모든 문제를 해결하는 것으로 변경 5*하여 훨씬 빠르게 만들 수 있습니다 2*.

설명

(약간 구식입니다.)

아이디어는 가능한 평등에 대해 일종의 "홍수 채우기"를 수행 한 다음 결론 목록에서 얻은 모든 평등을 제거하는 것입니다. 플러드 필의 5 단계 이상이 필요하지 않음을 알 수 있습니다. 이는 초기 불평등 그래프의 거리 를 포함 하지만 최대 거리는 25입니다.25 = 32

"Alex is " e# Push the string.
q          e# Read the input.
_elN-      e# Make a copy, convert to lower case, remove linefeeds. This gives us a string
           e# with all the characters we don't want from the input.
-          e# Remove them from the input. This leaves two upper-case letters on each line
           e# and an empty line between premises and conclusions.
N/         e# Split into lines.
La/        e# Split around the empty line.
~          e# Dump both halves on the stack.
{)-},      e# Remove any "A = A"-type equalities from the conclusions.
\          e# Swap with the premises.
{          e# Extend the premises 5 times...
  _Wf%     e#   Duplicate the premises and reverse each one, because = is symmetric.
  |        e#   Set union with the original premises.
  __m*     e#   Make two copies and get an array of every possible pair of premises.
  {:&},    e#   Select those which have at least one character in common.
  ::^      e#   For each such pair, take the mutual set difference, i.e. those characters
           e#   that are in only one of the strings.
  |        e#   Set union with the original premises.
}5*
-          e# Remove all the equalities we've obtained from the conclusions. If all
           e# conclusions were valid, the result will now be a empty array, which is falsy.
!          e# Logical not.
"wrong""right"?
           e# Select "wrong" or "right", respectively.

전이 폐쇄 구성하기? 저는 CJam에 익숙하지 않지만 5 세대 평등은 한 방향으로 만 생성되는 것처럼 보입니다. 그렇다면, 평등을 되돌리려면 반복이 하나 더 필요할 것입니다.
user2357112

@ user2357112 첫 번째 단계는 입력의 모든 반전을 추가하기 때문에 (또는 더 골프 버전에서는 모든 전제와 결론 평등을 처음부터 정렬하므로) 양방향으로 생성해야한다고 생각합니다.
Martin Ender

그러나 대칭적인 차이점을 고려할 때 양방향으로 가장자리를 얻습니까? (또는 추가 골프 버전에서는 대칭 차이가 필요한 방향으로 모서리를 생성합니까?)
user2357112

@ user2357112 전체 카티 전 곱을 처리하고 있기 때문에 두 순서로 각 동등 쌍을 얻을 수 있습니다. 결과적으로 두 가지 순서로 결과가 나옵니다 (명시 적으로 반대로하거나 초기 입력을 정렬해야하는 유일한 이유는 다음과 같습니다. 원래 구내가 반드시이 과정에서 생성되는 것은 아니기 때문에 직교 제품의 설정된 차이를 취하여 역전되지는 않습니다).
Martin Ender

6

R, 183192 바이트

user2357112가 지적한 제한 사항을 해결하기 위해 답변을 수정했습니다. Alex가 실제로 옳을 때 여전히 전화 할 가능성은 극히 적습니다 (이것은 도전의 맥락을 이해하면 자주 발생하지 않는 것 같습니다 :-). 나는 그가 신경 쓰지 않기를 바랍니다.

i=grep("t",z<-scan(,"",,,"\n"))
cat("Alex is",if(eval(parse(t=c(paste(LETTERS,"=",1:26),sample(rep(head(z,i-1),1e3)),paste(c(TRUE,sub("=","==",tail(z,-i))),collapse="&")))))"right"else"wrong")

나는 이것을 조금 골퍼해야합니다 :

lines = scan(, what = "", sep = "\n")
therefore_idx = grep("therefore", lines)
setup = paste(LETTERS, "=", 1:26)
premises = sample(rep(head(lines, therefore_idx - 1), 1000))
propositions = paste(c(TRUE, sub("=", "==", tail(lines, -therefore_idx))), collapse = "&")
things_to_evaluate = c(setup, premises, propositions)
boolean_result = eval(parse(text = things_to_evaluate))
cat("Alex is", if (boolean_result) "right" else "wrong")

예를 들어 입력이

A = B
B = C
therefore
A = C
B = C

먼저 다음을 평가합니다 setup.

A = 1
B = 2
...
Z = 26

그런 다음 premises

A = B
B = C

무작위로 1,000 번씩 실행됩니다. 이것은 모든 평등이 전파되도록 (거의 확실하게)하는 것입니다. 마지막으로 다음을 평가합니다 propositions.

TRUE & A == B & B == C

3
구내가 A = B, B = C, C = A인 경우 값이 영원히 순환됩니다. 26 라운드의 평가로는 충분하지 않습니다.
user2357112

실패한 논리 ... 예를 들어 주셔서 감사합니다. 그때 다른 작업을해야합니다.
flodel

나는 그것을 고치거나 거의 ...!
flodel

5

하스켈, 208 바이트

import Data.Equivalence.Persistent
c l=equate(l!!0)$last l 
r=foldr(c)$emptyEquivalence('A','Z')
l#r=equiv r(l!!0)$last l
f x|(h,_:t)<-span((<'t').head)$lines x="Alex is "++if all(#r h)t then"right"else"wrong"

작업을 Data.Equivalence.Persistent모듈로 오프로드하고 동등성 클래스를 조작하는 기능을 제공합니다. 남은 일은 골프를 치기에는 너무 긴 이름을 가진 입력 및 호출 기능을 파싱하는 것입니다.

사용 예 :

*Main> f "A = B\nB = C\ntherefore\nA = C"
"Alex is right"

*Main> f "A = B\nB = D\ntherefore\nA = C"
"Alex is wrong"

3

매스 매 티카, 182

f[s_]:="Alex is "<>If[True===And@@Simplify[#2,#1]&@@(StringSplit[s,"\n"]/.{a___,"therefore",b___}:>StringSplit/@{{a},{b}}/.{x_,_,y_}:>Symbol[x<>"$"]==Symbol[y<>"$"]),"right","wrong"]

과제에 따라 문자열 입력에서 작동합니다.

In[]:= f["A = B
B = C
therefore
A = C"]
Out[]= Alex is right

In[]:= f["D = K
D = Q
L = P
O = L
M = O
therefore
K = L"]
Out[]= Alex is wrong

당신은 선언 8 바이트를 잃을 수 f, 순수 함수로 대체 Simplify[#2,#1]하여 #2~Simplify~#, 및 교체 StringSplit[s,"\n"]와 함께 #~StringSplit~"<actual newline>".
LegionMammal978

좋은 포인트! 또한 q=StringSplit;다른 6 바이트 정도의 s / StringSplit / q /가 저장되었습니다. 그러나 결국 논리 캐릭터가 완벽하게 맞는 것처럼 보이지만 Mathematica에게는 좋은 도전이 아닙니다.

또한, a___b___아마로 변경 될 수 a__b__,와 s=Symbol;.
LegionMammal978

a__b__소재지, 제안 또는 둘 모두가 비어있는 경우 비록 작동하지 않습니다

3

레티 나, 90 바이트

실행하려면 다음 12 줄의 코드를 12 개의 개별 파일에 배치하십시오 (첫 번째 파일 이후 각 파일에 대해 +11 바이트 수). <empty>빈 파일을 지정합니다. \n리터럴 개행을 지정합니다. 또는 \ns를 그대로 유지하고 모든 줄을 단일 파일에 넣고 -s옵션을 사용하십시오 . 모든 파일이 Windows가 아닌 리터럴 개행을 사용하는지 확인 \r\n하고 마지막 행 끝에 공백을 기록하십시오.

s+`^(.) = (.)(.*)\1
$1 = $2$3$2
)`^. .+\n
<empty>
^.+|(.) = \1
<empty>
^\n*$
right
^[^r]+
wrong
^
Alex is 

작동 원리

첫 번째 대체는 전제 시간이 파일에서 나중에 발생할 때마다 입력의 첫 번째 전제와 일치합니다. 그것은 나중에 발생하는 것을 전제의 rhs로 대체합니다. +수정은 더 이상 일치하지 않을 때까지 교체가 반복되는 것을 보장한다. 따라서 첫 번째 전제가 A = BA경우 파일의 모든 후속 s가 s로 변환됩니다 B.

두 번째 대체는 입력이 완료되었으므로 첫 번째 전제를 입력에서 제거합니다. 그런 다음 )수정자는 첫 번째 교체로 루프하고 루프를 통과하는 전체 패스에 변경 사항이 없을 때까지 반복됩니다. 이것은 모든 구내가 대체되고 제거되고 입력이로 시작될 때 발생 therefore합니다.

세 번째 대체는 첫 번째 입력 행 ( therefore또는) 과 일치하고 A = A이를 삭제합니다. 모든 제안이 구내에서 지원되는 경우 모든 제안 이이 양식과 일치하므로 남아있는 내용은 개행으로 만 구성되어야합니다. 네 번째 교체는 이것을로 변경합니다 right. 그렇지 않으면 다섯 번째 교체는 남아있는 모든 항목 ( 삭제 된 r이후 포함되지 않은 therefore)을로 변경 wrong합니다. 마지막으로 마지막 교체가 Alex is 처음에 추가 됩니다.


3

파이썬 2, 264 바이트

mbomb007놀라운 Python 3 답변이 이미 있습니다. 이 답변은 그 중 하나에서 특히 훔친다 (특히 "Alex is wrriognhgt"트릭).

그리고이 답변은 그보다 훨씬 길다 ...

어쨌든,이 답변의 아이디어는 키-값 쌍의 사전을 유지하는 것입니다. 여기서 키는 26 개의 대문자 문자이고 각 키의 해당 값은 키와 동등한 문자 세트입니다. (26 자 모두 동일하면 각 키는 해당 값에 대해 26 자 세트를 갖습니다.)

def a(s):
 d={C:set(C)for C in map(chr,range(65,91))};p,c=s.split('t');c,p=[x.split('\n')for x in[c[9:],p]]
 for u in p[:-1]:
    g,h=u[::4];y=d[g]|d[h]
    for v in y:
     for w in y:d[v]|=d[w];d[w]|=d[v]
 print'Alex is','wrriognhgt'[all(u[0]in d[u[4]]for u in c if u)::2]

(바이트를 절약하기 위해이 답변 은 공백과 탭을 혼합 하여 Python 2에서 유효합니다.)

이 코드는 사전이 입력 줄 수에 의존하지 않는 가능한 최대 크기 (위에서 설명한 26 x 26)로 제한되기 때문에 매우 효율적입니다.

이제이 솔루션을 골프화 하면서 사전 값 대신 문자열을 사용하여 4 바이트절약 할 수 있음을 깨달았습니다.

d={C:set(C)for C in map(

d={C:C for C in map(

물론 set union 연산의 세 가지 인스턴스 |를 string concatenation 으로 바꿔야하지만 (참고 :하지 마십시오) +코드 길이는 변경되지 않습니다. 결과적으로 세트와 마찬가지로 중복을 제거하지 않습니다 (문자열 끝에 계속 추가 할 것임)를 제외하고는 모든 것이 여전히 동일하게 작동해야합니다. 괜찮은 것처럼 들립니다. 효율성은 떨어지지 만 264 대신 260 바이트입니다.

글쎄, 260 바이트 버전은 너무 비효율적이므로MemoryError 테스트 할 때 발생 했습니다.

A = B
A = B
therefore
B = A

이것은 나에게 놀랐다. 260 바이트 "문자열 연결"버전을 조사해 봅시다!

물론 그것은 키-값 쌍 A:AB:B중요하지 않은 24 개의 다른 값으로 시작합니다 . 우리는 d[A]키에 해당하는 사전 값을 의미하도록 작성 A하므로 처음에는을 갖습니다 d[A] = A. 이제 전제 주어 A = B,이 값을 연결하여 시작할 것 d[A]=A하고 d[B]=B얻을 y = AB. 그런 다음이 문자열을 두 번 반복합니다. for v in AB: for w in AB:...

그래서, 처음 루프를 통해, 우리가 v=A하고 w=A. 다음과 같은 사전을 적용 d[v] += d[w]하고 d[w] += d[v]결과를 얻습니다.

{A:A, B:B}      (start)
{A:AA, B:B}     (d[A] += d[A])
{A:AAAA, B:B}     (d[A] += d[A])

다음으로 v=Aand w=B:

{A:AAAA, B:B}     (start)
{A:AAAAB, B:B}    (d[A] += d[B])
{A:AAAAB, B:BAAAAB}   (d[B] += d[A])

다음으로 v=B, w=A:

{A:AAAAB, B:BAAAAB}   (start)
{A:AAAAB, B:BAAAABAAAAB}     (d[B] += d[A])
{A:AAAABBAAAABAAAAB, B:BAAAABAAAAB}     (d[A] += d[B])

그리고 v=B, w=B:

{A:AAAABBAAAABAAAAB, B:BAAAABAAAAB}     (start)
{A:AAAABBAAAABAAAAB, B:BAAAABAAAABBAAAABAAAAB}     (d[B] += d[B])
{A:AAAABBAAAABAAAAB, B:BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB}     (d[B] += d[B])

상기 일련의 단계는 하나의 전제를 구현하는 것이 A = B결론으로, A문자열의 모든 문자와 동일 AAAABBAAAABAAAAB하지만, B모든 편지와 같다 BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

이제 다음 전제가 A = B 다시 있다고 가정하자 . 먼저 계산 y = d[A] + d[B] = AAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB합니다.

다음으로이 문자열을 두 번 반복합니다. for v in y: for w in y:...

네. 어쩌면 그것은 매우 효율적인 구현이 아닐 수도 있습니다.


내 대답은 유효하지 않기 때문에 "위대한"것은 아니지만 주목할만한 시도였습니다. 너무 나쁘게 작동하지 못했습니다.
mbomb007

1
@ mbomb007 허, 유감입니다. (나는 당신이 멋진 접근법을 가지고 있다고 생각했습니다!) 당신이 "위대한"이라는 단어에 반대하기 때문에, 나는 "놀라운"을 대신했습니다. :)
mathmandan

2

ES6, 128 바이트

루비 버전을 기반으로합니다.

r=s=>(m=/^[^e]*(.) = (?!\1)(.)/.exec(s))?r(s.replace(RegExp(m[1],'g'),m[2])):'Alex is '+(/(.) = (?!\1)/.test(s)?'wrong':'right')

"thefore"이전에 자기 평등이 아닌 것을 찾고 매번 문자열 전체에서 변수를 반복적으로 대체합니다 (이것은 while 루프를 통해 바이트를 절약합니다).


1

C, 240 바이트

#define V[v-65]
v[26];char*r[]={"wrong","right"};i=65;j;g(a){return a V^a?g(a V):a;}main(){char b[16];for(;i<91;++i)i V=i;while(gets(b)&&*b<99)b[0]V=b[4]V=b[0]V<b[4]V?b[0]V:b[4]V;while(gets(b))j|=g(*b)^g(b[4]);printf("Alex is %s\n",r[!j]);}

이것은 값을 세트 트리로 결합하여 작동하므로 동등한 값은 동일한 세트 루트로 이어집니다. 암시 적 유형을 명시 적으로 사용하여 ungolfed.

// Anything before `V` becomes an index into `v`, offset by -'A'.
#define V [v-65]
int v[26];
char* r[] = {"wrong", "right"};
int i=65;
int j;
// Finds a set identifier for a by recursing until some index points to itself.
int g(int a) {
    return a V ^ a
           ? g(a V)
           : a;
}
int main() {
    char b[16];
    // Initialize all entries to point to themselves.
    for(; i < 91; ++i)
        i V = i;
    // For each premise "A = B", set the entries for A and B to point to the
    // smaller of their current values. This exits after reading "therefore"
    // as 't' > 99.
    while (gets(b) && *b < 99)
        b[0]V = b[4]V = b[0]V < b[4]V
                        ? b[0]V
                        : b[4]V;
    // For each conclusion "A = B", OR j with non-zero if the set identifiers
    // for A and B are different.
    while (gets(b))
        j |= g(*b) ^ g(b[4]);
    printf("Alex is %s\n", r[!j]);
}

180 바이트

이 짧은 버전은 OP의 모든 경우에 작동하지만 다른 입력의 경우 Alex가 잘못되었다고 잘못 주장합니다. 비슷한 접근 방식을 사용하지만 각 전제에 대해 두 번째 항목을 첫 번째 항목의 현재 값으로 설정하기 만하면됩니다. 비교할 때 트리를 검색하는 대신 정확한 값만 찾습니다.

v[26];*V=v-65;char*r[]={"wrong","right"};i;j;main(){char b[16];for(;i<26;++i)v[i]=i;while(gets(b)&&*b<99)V[b[4]]=V[*b];while(gets(b))j|=V[*b]^V[b[4]];printf("Alex is %s\n",r[!j]);}

실패한 입력 예 :

A = B
C = B
그러므로
A = C


1

05AB1E , 32 바이트

…±º€ˆ „–у©#|€á[ćD.l#`:}\€ËPè«.ª

@aditsu 의 CJam 답변에서 영감을 얻었습니다 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

…±º€ˆ      # Push dictionary string "alex is "
„–у©      # Push dictionary string "wrong right"
     #     # Split by spaces: ["wrong","right"]
|          # Push all input-lines as list
 ۈ        # Only leave the letters of each line
   [       # Start an infinite loop:
    ć      #  Extract the head of the list; pop and push remainder-list and head separately
     D     #  Duplicate the head
      .l   #  If it's a lowercase string:
        #  #   Stop the infinite loop
    `      #  Push both letters in the string to the stack
     :     #  Replace all these letters in the remainder-list
 }\        # After the infinite loop: discard the duplicated "therefore"
          # For each letter-pair in the remainder list of condition-lines:
    Ë      #  Check if both letters are equal (1 if truhy; 0 if falsey)
   P       # Check if everything was truthy by taking the product
    è      # Use this to index into the earlier ["wrong","right"]-list
     «     # Append it to the "alex is " string
         # Sentence capitalize it
           # (after which the result is output implicitly)

내이 05AB1E 팁을 참조하십시오 (섹션 어떻게 사전을 사용하는 방법을? ) 이유를 이해하는 …±º€ˆ것입니다 "alex is "하고 „–у©있다 "wrong right".


0

bash + awk + SWI-Prolog , 167 바이트

head -n1 <(awk '/therefore/{s=1;next};{if(s)print"?=("$1","$3")";else print};END{print"write(\"Alex is right\");write(\"Alex is wrong\"). halt."}' -|paste -sd ,|swipl)

온라인으로 사용해보십시오!

원래 이것은 프롤로그 답변 일뿐이지만 실제로 입력 형식을 사용 가능한 것으로 변환 할 수있는 도구는 제한이 없었지만 경험이 거의 없었지만 bash에서 그 부분을하기로 결정했습니다. bash에서 아무것도하지 않고 awk를 만지지 않았습니다. 나는 167 바이트로 자란 후에도 모든 몬스터에게 거의 골프를 치지 않고 게시하기 위해 충분한 시간을 보냈습니다.

기본적으로, 어떤 AWK 프로그램이하는 일은, 표준 입력에서 입력을 가진 행을 삭제하다 therefore, 모든 교체 A = B로 후 ?=(A,B), 및 추가 write(\"Alex is right\");write(\"Alex is wrong\"). halt.. 그런 다음, paste -sd ,그때까지 한 줄에 잘리지 인쇄 된 결과로 실행되는 SWI - 프롤로그 쉘에 대한 유효한 두 개의 쿼리로 변환, 모든 줄 바꿈하지만 쉼표로 마지막을 대체 head -n1필요 <(...)없는 이유로 대신 파이프의 내 이해. 이 모든 것이 내장되어 있습니다 !

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.