Alex a parfois raison

50

Ce défi consiste à élever les esprits de notre mod Alex A. , qui a généralement tort .


Supposons que vous avez un ami nommé Alex qui a besoin d'aide pour la logique de base et les mathématiques, en particulier l'équivalent mathématique .

Il vous donne une liste d'équations de la forme [variable] = [variable]où a [variable]est toujours une simple lettre majuscule de A à Z (pas une lettre minuscule, ni un chiffre, ni rien d'autre). Il y a une équation par ligne dans la liste, à l'exception d'une seule ligne qui dit seulement therefore.

Toutes les équations ci-dessus thereforesont des prémisses , des faits supposés vrais. Toutes les équations ci-dessous thereforesont des propositions non vérifiées, des faits qu'Alex tente de déduire des prémisses, et elles peuvent être vraies ou non.

Par exemple, dans cette liste d’équations, la proposition de conclusion unique A = Cest vraie:

A = B
B = C
therefore
A = C

C'est à vous de dire à Alex si toutes ses propositions découlent logiquement des prémisses données. Autrement dit, vous devez dire à Alex s’il a tort ou tort dans ses conclusions.

Écrivez un programme / une fonction qui prend une chaîne d'une liste d'équations telle que décrite et qui est imprimée / retournée

Alex is right

si toutes les conclusions découlent logiquement des locaux, et sinon sorties

Alex is wrong

si aucune conclusion ne découle logiquement des locaux.

Le code le plus court en octets gagne.

Assurez-vous de faire attention à ces cas:

  • La variable est toujours égale à elle-même. par exemple

    B = A
    therefore
    A = A
    X = X
    

    résultats en Alex is right.

  • Les variables avec des relations inconnues ne peuvent pas être supposées égales. par exemple

    P = Q
    therefore
    E = R
    

    résultats en Alex is wrong.

  • Quand il n'y a pas d'équations après le, thereforealors les conclusions sont vaines . par exemple

    D = C
    therefore

    et

    therefore

    les deux résultent en Alex is right.

  • Quand il n'y a pas d'équations avant le thereforeseul alors égalité de soi peut être déduite. par exemple

    therefore
    R = R
    

    résultats en Alex is right, mais

    therefore
    R = W
    

    résultats en Alex is wrong.

Plus d'exemples

Alex a tort: (séparés par des lignes vides)

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 a raison:

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
Les passe-temps de Calvin
la source
42
PHP, 13 octets Alex is wrongVérifie tous les cas de test.
Dennis
19
Hey, parfois, c'est mieux que jamais. ¯ \ _ (ツ) _ / ¯
Alex A.
5
alex-is-faux
Optimiseur
7
therefore\nTABS < SPACES->Alex is right
Poignée de porte
7
J'adore voir une solution dans Prolog.
azz

Réponses:

18

CJam, 49 ans

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

Inspiré de la solution Ruby d'Histocrat. Essayez-le en ligne
3 octets oblitérés grâce à jimmy23013 :)

Explication:

Pour chaque prémisse, le programme remplace la première variable par la deuxième variable dans le reste du texte. Il vérifie ensuite s'il existe une conclusion avec différentes variables.

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

Ancienne version, 85

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

Ceci utilise un algorithme de recherche d'union. Essayez-le en ligne

Aditsu
la source
1
"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?.
Jimmy23013
1
Je viens de lire cette dernière ligne comme suit: «Ceci utilise un algorithme de recherche d' une licorne »… waitwot? xD
Jan
Alex is * wrong * right * ?
Charlie
32

Rubis, 80 76 + 2 = 78

Avec les indicateurs de ligne de commande p0, exécutez

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

Explication:

Ceci utilise une manipulation de chaîne pure. p0lit l'entrée complète sous la forme d'une chaîne unique dans la variable $_. Ensuite, nous associons à plusieurs reprises cette chaîne à l'expression régulière /(.) = (?!\1)(.)/, qui trouve toutes les chaînes de la forme "X = Y" où X et Y ne sont pas la même lettre et affecte X à $ 1 et Y à $ 2. Lorsqu'une telle correspondance est trouvée, gsub$1,$2remplace toutes les instances de X par Y dans la chaîne. Nous vérifions également si cette correspondance a eu lieu avant ou après le "donc" avec

$`[/e/]

Si cela s'est produit après, c'est une demande injustifiée et Alex a tort. Nous vérifions si de tels événements se sont produits avec p=. L'utilisation de pcomme variable de suivi évite que les choses ne se brisent si la boucle ne frappe jamais une seule fois, car elle pne retournera rien si elle n'a jamais été affectée.

A partir de cet article, la solution CJam est plus longue. Un moment de fierté, si ce n’est sans doute.

Edit: Ouais, rapidement détrôné. De plus, pour terminer l'explication, avec l' pindicateur, la valeur finale de $_est sortie à la fin de l'exécution, la dernière ligne est donc la sortie.

histocrate
la source
15
Les moments les plus doux sont ceux avant que la solution ne soit abattue par un esolang.
Alex A.
L’abus de String#formatfaire en sorte que l’appel gsub et l’affectation en une seule expression soit une bonne idée, +1!
Ventero
12

CJam, 83 75 68 67 64 octets

Merci à Dennis d'avoir sauvegardé 1 octet.

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

Suite de tests. Les cas de test sont trop longs pour un lien permanent, copiez-les simplement de la question. Notez que c'est assez lent - cela prend une minute ou deux dans l'interprète en ligne. Vous pouvez le faire beaucoup plus rapidement en changeant 5*de 2*dans ce cas , il finira presque instantanément et de résoudre tous sauf un cas de test.

Explication

(Légèrement dépassé.)

L'idée est de faire une sorte de "remplissage" des égalités possibles, puis de supprimer toutes les égalités que nous avons obtenues de la liste des conclusions. On peut montrer que nous n'avons pas besoin de plus de 5 étapes de remplissage, car celles-ci couvriraient une distance (dans le graphe initial des inégalités) de mais la distance maximale est de 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.
Martin Ender
la source
Construire la fermeture transitive, hein? Je ne connais pas bien CJam, mais il semble que la 5e génération d'égalités ne pourrait être générée que dans un sens. S'ils le sont, vous aurez besoin d'une itération supplémentaire pour inverser ces égalités.
user2357112
@ user2357112 Je pense qu'elles devraient être générées dans les deux sens, car la première étape ajoute tous les renversements de l'entrée (ou dans la version développée plus loin, je trie tout d'abord les égalités de prémisse et de conclusion).
Martin Ender
Lorsque vous prenez les différences symétriques, obtenez-vous des bords dans les deux sens? (Ou, dans la version ultérieure, les différences symétriques produisent-elles les arêtes dans la direction requise?)
user2357112
@ user2357112 Puisque je traite le produit cartésien en entier, je vais obtenir chaque paire d'égalités dans les deux ordres, ce qui donnera les deux ordres de la conclusion tirée (la seule raison pour laquelle je dois inverser explicitement ou trier l'entrée initiale est que les prémisses d'origine ne sont pas nécessairement générées dans ce processus, elles ne sont donc pas inversées en prenant les différences définies du produit cartésien).
Martin Ender
6

R, 183 192 octets

J'ai modifié ma réponse pour répondre à une limitation signalée par l'utilisateur2357112. Il y a encore une très faible probabilité d'appeler Alex alors qu'il a raison (ce qui en soi ne semble pas se produire très souvent si je comprends le contexte du défi :-). J'espère que ça ne le dérangera pas.

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

J'ai besoin de dé-golfer un peu:

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

Par exemple, si l'entrée est

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

il va d'abord évaluer le setup:

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

puis le premises

A = B
B = C

sera exécuté 1000 fois chacun dans un ordre aléatoire. Ceci est pour vous assurer ("presque sûr") que toutes les égalités sont propagées. Enfin, il évaluera propositions:

TRUE & A == B & B == C
flodel
la source
3
Si les prémisses sont A = B, B = C, C = A, les valeurs simplement cycle pour toujours 26 tours d'évaluation ne suffisent pas.
user2357112
Ma logique ratée ... Merci pour l'exemple, je vais devoir travailler autre chose alors.
Flodel
Je pense le réparer, ou presque ...!
Flodel
5

Haskell, 208 octets

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"

Je délègue le travail au Data.Equivalence.Persistent module, qui fournit des fonctions pour manipuler des classes d'équivalence. Tout ce qui reste à faire est d’analyser les fonctions d’entrée et d’appel qui ont parfois des noms trop longs pour un golf correct.

Exemple d'utilisation:

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

*Main> f "A = B\nB = D\ntherefore\nA = C"
"Alex is wrong"
nimi
la source
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"]

Fonctionne sur l'entrée de chaîne, selon le défi.

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

la source
Vous pouvez perdre 8 octets en déclarant fune fonction pure, en remplaçant Simplify[#2,#1]par #2~Simplify~#et en remplaçant StringSplit[s,"\n"]par #~StringSplit~"<actual newline>".
LegionMammal978
Bons points! Aussi q=StringSplit;, puis s / StringSplit / q / pour 6 autres octets ou plus. Mais à la fin, ce n’est pas un bon défi pour Mathematica, même si le personnage logique semblait un ajustement parfait.
Aussi, a___et b___peut probablement être changé en a__et b__, et s=Symbol;.
LegionMammal978
a__et b__ne fonctionnera pas si les locaux, les propositions ou les deux sont vides
3

Retina, 90 octets

Pour l'exécuter, placez les 12 lignes de code suivantes dans 12 fichiers distincts (+11 octets comptés pour chaque fichier au-delà du premier). <empty>désigne un fichier vide; \ndésigne une nouvelle ligne littérale. Autrement, conservez le \ns tel quel, mettez toutes les lignes dans un seul fichier et utilisez l' -soption. Assurez-vous que tous les fichiers utilisent des nouvelles lignes, pas Windows \r\n, et notez l'espace à la fin de la dernière ligne.

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

Comment ça fonctionne

Le premier remplacement correspond à la première prémisse de l'entrée, chaque fois que les lhs de la prémisse se produisent plus tard dans le fichier. Il remplace cette occurrence ultérieure par le rhs de la prémisse. Le +modificateur garantit que le remplacement est répété jusqu'à ce qu'il ne corresponde plus. Ainsi, si le premier principe est A = B, tous les As suivants du fichier sont transmutés enB s.

Le deuxième remplacement supprime le premier principe de l'entrée, puisque nous en avons terminé avec cela maintenant. Ensuite, le )modificateur revient en boucle au premier remplacement et se répète jusqu'à ce qu'il n'y ait plus de changement dans un passage complet de la boucle. Cela se produit lorsque tous les locaux ont été remplacés et supprimés et que l'entrée commence par therefore.

Le troisième remplacement correspond à la première ligne d'entrée (qui est therefore) ou à tout autre élément du formulaire A = Aet le supprime. Si toutes les propositions sont prises en charge par les prémisses, elles correspondront toutes à ce formulaire. Il ne reste donc que les nouvelles lignes. Le quatrième remplacement change cela en right. Sinon, le cinquième remplacement remplace tout ce qui reste (ce qui ne contient pas rdepuis thereforesa suppression) wrong. Enfin, le dernier remplacement ajoute Alex is au début.

DLosc
la source
3

Python 2, 264 octets

Il existe déjà une réponse remarquable à Python 3 de mbomb007 . Cette réponse vole de manière flagrante à celle-là (en particulier le truc "Alex est écrit").

Et cette réponse est aussi beaucoup plus longue que celle-là ...

Quoi qu’il en soit, l’idée dans cette réponse est de maintenir un dictionnaire de paires clé-valeur, où les clés sont les 26 caractères majuscules, et la valeur correspondante de chaque clé est l’ensemble des lettres qui sont équivalentes à la clé. (Si les 26 lettres étaient équivalentes, chaque touche aurait alors un ensemble de 26 lettres pour la valeur correspondante.)

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]

(Pour économiser des octets, cette réponse mélange des espaces et des tabulations , ce qui est légal dans Python 2.)

Ce code est vraiment très efficace, car le dictionnaire est limité à une taille maximale possible (26 par 26 comme décrit ci-dessus), qui ne dépend pas du nombre de lignes d'entrée.

Alors que je jouais cette solution, je me suis rendu compte que je pouvais économiser quatre octets en utilisant des chaînes plutôt que des ensembles pour les valeurs du dictionnaire, en remplaçant

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

avec

d={C:C for C in map(

Bien entendu, vous devez également remplacer (NOTE: NE LE FAITES PAS) les trois instances de l'opération d'union définie |avec la concaténation de chaînes +, mais cela ne modifie pas la longueur du code. Le résultat est que tout devrait toujours fonctionner de la même manière, sauf que cela n'éliminera pas les doublons comme vous le faites avec des ensembles (cela ne fera que continuer d'ajouter des éléments à la fin de la chaîne). Cela semble correct - un peu moins efficace, bien sûr, mais 260 octets au lieu de 264.

Eh bien, il s’avère que la version à 260 octets est tellement inefficace qu’elle a causé un problème MemoryErrorlorsque je l’ai testée avec

A = B
A = B
therefore
B = A

C'était surprenant pour moi. Examinons la version "concaténation de chaînes" de 260 octets!

Bien sûr, cela commencerait par les paires clé-valeur A:Aet B:B(plus 24 autres qui importent peu). Nous écrirons d[A]pour signifier la valeur du dictionnaire correspondant à la clé A, donc nous aurions au début d[A] = A. Maintenant, étant donné la prémisse A = B, il faudrait commencer par concaténer les valeurs d[A]=Aet d[B]=Bobtenir y = AB. Ensuite, il bouclerait deux fois cette chaîne: for v in AB: for w in AB:...

Donc, la première fois dans la boucle, nous avons v=Aet w=A. Application d[v] += d[w]et d[w] += d[v]résultats dans la séquence de dictionnaires suivante:

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

Ensuite, avec v=Aet w=B:

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

Ensuite 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])

Et 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])

La séquence d'étapes ci-dessus implémenterait le principe unique A = B, avec la conclusion Aégale à chaque lettre de la chaîne AAAABBAAAABAAAAB, et Bégale à chaque lettre BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Maintenant, supposons que la prochaine prémisse soit à A = B nouveau . Vous calculez d'abord y = d[A] + d[B] = AAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Ensuite, vous passez deux fois sur cette chaîne: for v in y: for w in y:...

Ouais. Ce ne serait peut-être pas une implémentation très efficace.

Mathmandan
la source
Ma réponse n'est pas "bonne" puisqu'elle est invalide, mais c'était une tentative remarquable. Dommage que je ne pouvais pas le faire fonctionner.
mbomb007
1
@ mbomb007 Euh, je suis désolé d'entendre ça. (Je pensais que vous aviez une approche géniale!) Depuis que vous vous êtes opposé au mot "génial", j'ai remplacé "remarquable". :)
mathmandan
2

ES6, 128 octets

Librement inspiré de la version Ruby.

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

Recherche toute non-égalité devant le "par conséquent" et remplace la variable de manière récurrente tout au long de la chaîne à chaque fois (cela enregistre des octets sur une boucle while).

Neil
la source
1

C, 240 octets

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

Cela fonctionne en combinant des valeurs dans des arbres définis, donc toutes les valeurs équivalentes mènent à la même racine définie. Ungolfed, avec des types implicites rendus explicites.

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

Cette version plus courte fonctionne pour tous les cas de l'OP, mais pour certaines autres entrées, Alex affirme à tort qu'il a tort. Il utilise une approche similaire, mais pour chaque prémisse, définit simplement la deuxième entrée sur la valeur actuelle de la première entrée. Lors de la comparaison, il ne regarde que les valeurs exactes au lieu de chercher dans un arbre.

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

Un exemple d'entrée pour lequel cela échoue:

A = B
C = B
donc
A = C

ughoavgfhw
la source
1

05AB1E , 32 octets

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

Inspiré par la réponse de CJad de @aditsu .

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

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

Voir ce conseil 05AB1E (section Comment utiliser le dictionnaire? ) Pour comprendre pourquoi …±º€ˆest "alex is "et „–у©est "wrong right".

Kevin Cruijssen
la source
0

bash + awk + SWI-Prolog , 167 octets

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)

Essayez-le en ligne!

À l’origine, c’était une réponse de Prolog, mais les outils que j’ai pu trouver pour transformer le format d’entrée en quelque chose d’utilisable étaient suffisamment limités pour que j’ai décidé de le faire par bash, même si je n’avais pratiquement aucune expérience. faire n'importe quoi dans bash, et n'avait même jamais touché awk. J'ai fini par passer suffisamment d'heures dessus pour vouloir l'afficher même après qu'il soit devenu ce monstre de 167 octets, à peine golfé.

Essentiellement, le programme awk prend les entrées de stdin, efface la ligne avec therefore, remplace chaque A = Baprès avec ?=(A,B), et ajoute write(\"Alex is right\");write(\"Alex is wrong\"). halt.. Ensuite, paste -sd ,remplace chaque virgule par une virgule, la transformant en deux requêtes valides au shell SWI-Prolog, qui sont ensuite exécutées avec le résultat imprimé tronqué à une ligne par head -n1, ce qui nécessite <(...)un canal pour des raisons autres que ma compréhension. Tout cela, juste pour utiliser un Builtin !

Chaîne non liée
la source