Alex às vezes está certo


50

Esse desafio é elevar o ânimo do nosso mod Alex A. , que geralmente está errado .


Suponha que você tenha um amigo chamado Alex que precise de ajuda com lógica e matemática básicas, especificamente equivalência matemática .

Ele fornece uma lista de equações da forma em [variable] = [variable]que a [variable]é sempre uma única letra maiúscula de A a Z (nem uma letra minúscula, nem um número, nem qualquer outra coisa). Há uma equação por linha na lista, exceto por uma única linha que diz apenas therefore.

Todas as equações acima thereforesão premissas , fatos que são assumidos como verdadeiros. Todas as equações abaixo thereforesão proposições não verificadas, fatos que Alex está tentando inferir a partir das premissas, e podem ou não ser verdadeiras.

Por exemplo, nesta lista de equações, a única proposição conclusiva A = Cé verdadeira:

A = B
B = C
therefore
A = C

É seu trabalho dizer a Alex se todas as suas proposições seguem logicamente a partir das premissas fornecidas. Ou seja, você precisa dizer a Alex se ele está certo ou errado em suas conclusões.

Escreva um programa / função que inclua uma sequência de uma lista de equações conforme descrito e imprima / retorne

Alex is right

se todas as conclusões derivam logicamente das premissas e, de outra forma, produzem

Alex is wrong

se alguma conclusão não resultar logicamente das premissas.

O código mais curto em bytes vence.

Cuidado com esses casos:

  • Variável sempre se iguala. por exemplo

    B = A
    therefore
    A = A
    X = X
    

    resulta em Alex is right.

  • Variáveis ​​com relacionamentos desconhecidos não podem ser consideradas iguais. por exemplo

    P = Q
    therefore
    E = R
    

    resulta em Alex is wrong.

  • Quando não há equações após o therefore, as conclusões são vacuamente verdadeiras . por exemplo

    D = C
    therefore

    e

    therefore

    ambos resultam em Alex is right.

  • Quando não existem equações antes therefore, apenas a auto-igualdade pode ser inferida. por exemplo

    therefore
    R = R
    

    resulta em Alex is right, mas

    therefore
    R = W
    

    resulta em Alex is wrong.

Mais exemplos

Alex está com casos errados: (separados por linhas vazias)

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

Alex está certo:

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 wrongVerifica todos os casos de teste.
Dennis

19
Ei, às vezes é melhor do que nunca. ¯ \ _ (ツ) _ / ¯
Alex A.


7
therefore\nTABS < SPACES->Alex is right
Maçaneta

7
Adoro ver uma solução em prólogo.
azz

Respostas:


18

CJam, 49

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

Inspirado na solução Ruby do histocrat. Experimente online
3 bytes eliminados graças a jimmy23013 :)

Explicação:

Para cada premissa, o programa substitui a primeira variável pela 2ª variável no restante do texto. Em seguida, verifica se há alguma conclusão com variáveis ​​diferentes.

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

Versão antiga, 85

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

Isso usa um algoritmo de localização de união. Experimente online


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

1
Acabei de ler a última linha como 'Isso usa um algoritmo de busca de unicórnios ' ... waitwot? xD
Jan

Alex is * wrong * right * ?
28415 Charlie

32

Ruby, 80 76 + 2 = 78

Com sinalizadores de linha de comando p0, execute

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

Explicação:

Isso usa manipulação pura de strings. p0lê a entrada completa como uma única sequência na variável $_. Em seguida, correspondemos repetidamente essa string à expressão regular /(.) = (?!\1)(.)/, que encontra todas as strings do formato "X = Y" onde X e Y não são a mesma letra e atribui X a $ 1 e Y a $ 2. Quando essa correspondência é encontrada, gsub$1,$2substitui todas as instâncias de X por Y na sequência. Também verificamos se essa correspondência ocorreu antes ou depois do "portanto" com

$`[/e/]

Se ocorreu depois, é uma reivindicação injustificada e Alex está errado. Nós rastreamos se alguma dessas ocorrências aconteceu usando p=. O uso de pcomo variável de rastreamento impede que as coisas quebrem se o loop nunca atingir uma única vez, pois pretornará nulo se nunca tiver sido atribuído.

Até o momento, a solução CJam é mais longa. Um momento orgulhoso, embora sem dúvida fugaz.

Edit: Sim, rapidamente destronado. Além disso, para finalizar a explicação, com o psinalizador o valor final de $_é emitido no final da execução, portanto a última linha é a saída.


15
Os momentos mais doces são aqueles antes que a solução seja abatida por um esolang.
Alex A.

O abuso de String#formatobter a chamada e a atribuição gsub em uma expressão é uma ideia muito interessante, +1!
Ventero

12

CJam, 83 75 68 67 64 bytes

Agradecemos a Dennis por economizar 1 byte.

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

Suíte de teste. Os casos de teste são muito longos para um link permanente, portanto, basta copiá-los da pergunta. Observe que isso é bastante lento - leva um ou dois minutos no intérprete online. Você pode torná-lo muito mais rápido, alterando 5*para o 2*caso em que ele será concluído quase instantaneamente e resolverá todos, exceto um caso de teste.

Explicação

(Um pouco desatualizado.)

A idéia é fazer uma espécie de "preenchimento" de possíveis igualdades e remover todas as igualidades que obtivemos da lista de conclusões. Pode-se mostrar que não precisamos de mais de 5 etapas do preenchimento da inundação, porque elas cobririam uma distância (no gráfico inicial de desigualdades), mas a distância máxima é 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.

Construindo o fechamento transitivo, não é? Não estou familiarizado com o CJam, mas parece que a 5ª geração de igualdades só pode ser gerada em uma direção. Se estiverem, você precisará de mais uma iteração para reverter essas igualidades.
user2357112

@ user2357112 Acredito que eles devam ser gerados em ambas as direções, porque o primeiro passo adiciona todos os reversos da entrada (ou na versão mais avançada, separo todas as igualdades de premissa e conclusão).
Martin Ender

Quando você considera as diferenças simétricas, obtém arestas nas duas direções? (Ou, na versão mais-golfed, que as diferenças simétricas produzir as bordas na direção necessária?)
user2357112

@ user2357112 Como estou processando todo o produto cartesiano, receberei cada par de igualdades em ambos os pedidos, o que resultará em ambos os pedidos da conclusão tirada (a única razão pela qual preciso reverter explicitamente ou classificar a entrada inicial é: que as premissas originais não são necessariamente geradas nesse processo; portanto, não são revertidas considerando as diferenças definidas do produto cartesiano).
Martin Ender

6

R, 183 192 bytes

Modifiquei minha resposta para resolver uma limitação apontada pelo usuário2357112. Ainda há uma probabilidade extremamente pequena de chamar Alex quando ele está certo (o que por si só não parece acontecer com muita frequência se eu entender o contexto do desafio :-). Espero que ele não se importe.

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

Eu preciso de-golf isso um pouco:

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

Por exemplo, se a entrada for

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

primeiro avaliará setup:

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

então o premises

A = B
B = C

será executado 1.000 vezes cada uma em uma ordem aleatória. Isso é para garantir ("quase com certeza") que todas as igualidades sejam propagadas. Por fim, avaliará propositions:

TRUE & A == B & B == C

3
Se as premissas são A = B, B = C, C = A, os valores circulam para sempre. 26 rodadas de avaliação não são suficientes.
user2357112

Minha lógica falhou ... Obrigado pelo exemplo, vou ter que trabalhar outra coisa então.
flodel

Eu acho que consertei, ou quase ...!
flodel

5

Haskell, 208 bytes

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"

Estou transferindo o trabalho para o Data.Equivalence.Persistentmódulo, que fornece funções para manipular classes de equivalência. Tudo o que resta fazer é analisar as funções de entrada e chamada, que às vezes têm nomes muito longos para o golfe adequado.

Exemplo de uso:

*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

Mathematica, 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"]

Funciona na entrada de string, conforme o desafio.

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

Você pode perder 8 bytes declarando fcomo uma função pura, substituindo Simplify[#2,#1]por #2~Simplify~#e substituindo StringSplit[s,"\n"]por #~StringSplit~"<actual newline>".
precisa

Bons pontos! Além disso q=StringSplit;, s / StringSplit / q / por mais 6 bytes salvos. Mas no final, esse não é um bom desafio para o Mathematica, embora o personagem lógico pareça perfeito.

Além disso, a___e b___provavelmente pode ser alterado para a__e b__, e s=Symbol;.
usar o seguinte

a__e b__não vai funcionar se instalações, proposições ou ambos estão vazios embora

3

Retina, 90 bytes

Para executar, coloque as 12 linhas de código a seguir em 12 arquivos separados (+11 bytes contados para cada arquivo além do primeiro). <empty>designa um arquivo vazio; \ndesigna uma nova linha literal. Como alternativa, mantenha os \ncomo estão, coloque todas as linhas em um único arquivo e use a -sopção Verifique se todos os arquivos usam novas linhas literais, não o Windows \r\n, e anote o espaço no final da última linha.

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

Como funciona

A primeira substituição corresponde à primeira premissa na entrada, sempre que o lhs da premissa ocorrer posteriormente no arquivo. Ele substitui essa ocorrência posterior pelos rhs da premissa. O +modificador garante que a substituição seja repetida até que não corresponda mais. Assim, se a primeira premissa for A = B, todos os As subsequentes no arquivo serão transmutados em Bs.

A segunda substituição remove a primeira premissa da entrada, já que a terminamos agora. Em seguida, o )modificador volta para a primeira substituição e se repete até que não houve alterações em uma passagem completa do loop. Isso acontece quando todas as instalações foram substituídas e removidas e a entrada começa com therefore.

A terceira substituição corresponde à primeira linha de entrada (que é therefore) ou qualquer coisa do formulário A = Ae a exclui. Se todas as proposições forem suportadas pelas premissas, todas elas corresponderão a esse formulário; portanto, o que resta deve consistir apenas em novas linhas. A quarta substituição muda isso para right. Caso contrário, a quinta substituição altera tudo o que resta (que não contém rdesde que thereforefoi excluído) wrong. Finalmente, a última substituição é adicionada Alex is no início.


3

Python 2, 264 bytes

Já existe uma resposta notável do Python 3 por mbomb007 . Essa resposta rouba flagrantemente aquela (em particular o truque "Alex is wrriognhgt").

E essa resposta também é significativamente mais longa do que aquela ...

Bem, de qualquer forma, a idéia nesta resposta é manter um dicionário de pares de valores-chave, onde as chaves são os 26 caracteres maiúsculos e o valor correspondente de cada chave é o conjunto de letras que são equivalentes à chave. (Se todas as 26 letras fossem equivalentes, cada chave teria um conjunto de 26 letras para o seu valor correspondente.)

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]

(Para salvar bytes, esta resposta combina espaços e tabulações , o que é legal no Python 2.)

Esse código é realmente bastante eficiente, porque o dicionário é limitado ao tamanho máximo possível (26 por 26, conforme descrito acima), que não depende do número de linhas de entrada.

Agora, enquanto jogava essa solução, percebi que podia salvar quatro bytes usando cadeias de caracteres em vez de conjuntos para os valores do dicionário, substituindo

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

com

d={C:C for C in map(

Obviamente, você também precisará substituir (OBSERVAÇÃO: NÃO FAÇA ISSO) as três instâncias da operação de união de conjuntos |com concatenação de cadeias +, mas isso não altera o tamanho do código. O resultado é que tudo ainda deve funcionar da mesma forma, exceto que não eliminará duplicatas como você faz com os conjuntos (continuará adicionando no final da string). Parece OK - um pouco menos eficiente, com certeza, mas 260 bytes em vez de 264.

Bem, acontece que a versão de 260 bytes é tão ineficiente que causou um MemoryErrorquando eu a testei com

A = B
A = B
therefore
B = A

Isso foi surpreendente para mim. Vamos investigar a versão de "concatenação de string" de 260 bytes!

É claro que começaria com os pares de valores-chave A:Ae B:B(mais 24 outros que não importam). Escreveremos d[A]para significar o valor do dicionário correspondente à chave A, portanto, no começo, teríamos d[A] = A. Agora, dada a premissa A = B, começaria concatenando os valores d[A]=Ae d[B]=Bobtendo y = AB. Em seguida, passaria duas vezes por essa sequência: for v in AB: for w in AB:...

Então, pela primeira vez no loop, temos v=Ae w=A. Aplicação d[v] += d[w]e d[w] += d[v]resultados na seguinte sequência de dicionários:

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

Em seguida, com v=Ae w=B:

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

Em seguida 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])

E 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 sequência de etapas acima implementaria a única premissa A = B, com a conclusão de que Aé igual a todas as letras da string AAAABBAAAABAAAAB, enquanto Bé igual a todas as letras de BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Agora, suponha que a próxima premissa seja A = B novamente . Você calcula primeiro y = d[A] + d[B] = AAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Em seguida, você faz um loop sobre essa sequência duas vezes: for v in y: for w in y:...

Sim. Talvez isso não seja uma implementação muito eficiente.


Minha resposta não é "ótima", pois é inválida, mas foi uma tentativa digna de nota. Pena que eu não consegui fazê-lo funcionar.
mbomb007

1
@ mbomb007 Huh, desculpe-me por ouvir isso. (Eu pensei que você tinha uma abordagem interessante!) Como você se opôs à palavra "ótimo", substituí "notável". :)
mathmandan 27/10/2015

2

ES6, 128 bytes

Vagamente baseado na versão Ruby.

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

Procura qualquer não-auto-igualdade antes do "portanto" e recurtavelmente substitui a variável por toda a cadeia de caracteres a cada vez (isso salva bytes em um loop while).


1

C, 240 bytes

#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]);}

Isso funciona combinando valores em árvores definidas, para que quaisquer valores equivalentes levem à mesma raiz definida. Ungolfed, com tipos implícitos explicitados.

// 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 bytes

Esta versão mais curta funciona para todos os casos do OP, mas para algumas outras entradas afirma incorretamente que Alex está errado. Ele usa uma abordagem semelhante, mas para cada premissa simplesmente define a segunda entrada para o valor atual da primeira entrada. Ao comparar, ele analisa apenas os valores exatos em vez de pesquisar uma árvore.

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]);}

Um exemplo de entrada para o qual isso falha:

A = B
C = B,
portanto,
A = C


1

05AB1E , 32 bytes

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

Inspirado por @aditsu resposta CJam 's .

Experimente online ou verifique todos os casos de teste .

Explicação:

…±º€ˆ      # 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)

Veja esta dica 05AB1E (seção Como usar o dicionário? ) Para entender por que …±º€ˆé "alex is "e „–у©é "wrong right".


0

bash + awk + SWI-Prolog , 167 bytes

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)

Experimente online!

Originalmente, essa seria apenas uma resposta do Prolog, mas as ferramentas que eu pude encontrar para transformar o formato de entrada em algo utilizável eram limitadas o suficiente para que eu decidisse fazer essa parte dele no bash, mesmo que eu tivesse quase nenhuma experiência fazendo qualquer coisa no bash, e nunca tinha tocado awk. Acabei gastando horas suficientes nele para querer publicá-lo, mesmo depois que ele se transformou em um monstro de 167 bytes, que mal jogava golfe.

Essencialmente, o que o programa awk faz é pegar a entrada do stdin, apagar a linha com therefore, substituir todas as A = Bdepois por ?=(A,B)e anexar write(\"Alex is right\");write(\"Alex is wrong\"). halt.. Em seguida, paste -sd ,substitui cada nova linha, exceto a última, por vírgula, transformando-a em duas consultas válidas para o shell SWI-Prolog, que são executadas com o resultado impresso sendo truncado em uma linha por head -n1, o que requer, em <(...)vez de um canal, por outras razões. meu entendimento. Tudo isso, apenas para usar um builtin !

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.