Алекс иногда прав

50

Эта задача - поднять настроение нашему моду Алексу А. , который обычно ошибается .


Предположим, у вас есть друг по имени Алекс, которому нужна помощь по базовой логике и математике, в частности, по математической эквивалентности .

Он дает вам список уравнений вида, [variable] = [variable]где a [variable]- это всегда одна заглавная буква от A до Z (ни строчная буква, ни число, ни что-либо еще). В списке есть одно уравнение на строку, за исключением одной строки, которая говорит только therefore.

Все уравнения выше thereforeявляются предпосылками , фактами, которые считаются правдой. Все уравнения ниже thereforeявляются непроверенными утверждениями, фактами, которые Алекс пытается вывести из помещения, и они могут быть или не быть правдой.

Например, в этом списке уравнений единственное заключительное утверждение A = Cоказывается верным:

A = B
B = C
therefore
A = C

Это ваша работа, чтобы сказать Алексу, если все его предложения логически вытекают из данной посылки. То есть вам нужно сказать Алексу, ошибся он или нет в своих выводах.

Напишите программу / функцию, которая принимает строку списка уравнений, как описано, и печатает / возвращает

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.

Больше примеров

Алекс не в том случае: (разделены пустыми строками)

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 байт. Alex is wrongПроверяет все тесты.
Денис
19
Эй, иногда лучше, чем никогда. ¯ \ _ (ツ) _ / ¯
Алекс А.
5
alex-is-неправильный
Оптимизатор
7
therefore\nTABS < SPACES->Alex is right
Дверная ручка
7
Люблю видеть решение в прологе.
Azz

Ответы:

18

CJam, 49

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

Вдохновлен гистократским решением Ruby. Попробуйте онлайн
3 байта уничтожены благодаря jimmy23013 :)

Объяснение:

Для каждой предпосылки программа заменяет первую переменную второй переменной в остальной части текста. Затем он проверяет, есть ли какой-либо вывод с разными переменными.

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

Это использует алгоритм поиска объединения. Попробуйте онлайн

aditsu
источник
1
"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?,
jimmy23013
1
Я просто прочитал эту последнюю строку как «Это использует алгоритм единорога- поиска»… waitwot? xD
января
Alex is * wrong * right * ?
Чарли
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 в строке. Мы также проверяем, произошло ли это совпадение до или после «следовательно» с

$`[/e/]

Если это произошло после, это необоснованное требование, и Алекс не прав. Мы отслеживаем, имели ли место такие случаи с использованием p=. Использование pв качестве переменной отслеживания предотвращает прерывание работы, если цикл никогда не срабатывает ни разу, поскольку pвернет nil, если он никогда не был назначен.

На данный момент решение CJam длиннее. Гордый, если без сомнения, мимолетный момент.

Редактировать: Да, быстро свергнут. Кроме того, чтобы завершить объяснение, с pфлагом $_выводится окончательное значение в конце выполнения, поэтому последняя строка является выходной.

histocrat
источник
15
Самые сладкие моменты - это те моменты, когда чье-то решение забито эзолангом.
Алекс А.
Злоупотребление String#formatполучением вызова и присваивания gsub в одном выражении - довольно интересная идея, +1!
Вентеро
12

CJam, 83 75 68 67 64 байта

Спасибо Деннису за сохранение 1 байта.

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

Тестирование. Тестовые случаи слишком длинные для постоянной ссылки, поэтому просто скопируйте их из вопроса. Обратите внимание, что это довольно медленно - это займет минуту или две в онлайн-переводчике. Вы можете сделать это гораздо быстрее за счет изменения 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 Я полагаю, что они должны быть сгенерированы в обоих направлениях, потому что на первом шаге добавляются все реверсы ввода (или в дальнейшей версии игры я сортирую все начальные и конечные равенства для начала).
Мартин Эндер
Когда вы берете симметричные различия, вы получаете края в обоих направлениях? (Или, в версии для дальнейшего игры в гольф, симметричные различия дают края в нужном направлении?)
user2357112
@ user2357112 Так как я обрабатываю весь декартово произведение, я получу каждую пару равенств в обоих порядках, что приведет к обоим порядкам полученного заключения (Единственная причина, по которой мне нужно явно поменять местами или отсортировать исходные данные, это что исходные предпосылки не обязательно генерируются в этом процессе, поэтому они не меняются местами, принимая набор разностей декартовых произведений).
Мартин Эндер
6

R 183 192 байта

Я изменил свой ответ, чтобы устранить ограничение, указанное пользователем user2357112. По-прежнему крайне мала вероятность вызова Алекса, когда он на самом деле прав (что само по себе, похоже, случается не очень часто, если я понимаю контекст задачи :-). Надеюсь, он не будет возражать.

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

будет запущен 1000 раз каждый в случайном порядке. Это делается для того, чтобы убедиться («почти наверняка»), что все равенства распространяются. Наконец, он оценит propositions:

TRUE & A == B & B == C
flodel
источник
3
Если это так A = B, B = C, C = A, то значения просто вращаются вечно. 26 раундов оценки недостаточно.
user2357112
Моя неудачная логика ... Спасибо за пример, тогда мне придется работать над чем-то другим.
flodel
Я думаю исправили это или почти ...!
Flodel
5

Haskell, 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;и затем s / StringSplit / q / для еще 6 байтов или около того сохранены. Но, в конце концов, это не очень хорошая задача для 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 

Как это устроено

Первая замена соответствует первой предпосылке во входных данных всякий раз, когда lhs предпосылки появляется позже в файле. Это заменяет это более позднее вхождение на rhs предпосылки. В +Модификатор гарантирует , что замена повторяется до тех пор, пока не соответствует больше. Таким образом, если первая предпосылка есть A = B, все последующие As в файле преобразуются в Bs.

Вторая замена удаляет первую предпосылку из ввода, так как мы закончили с этим сейчас. Затем )модификатор возвращается к первой замене и повторяется до тех пор, пока не произойдет никаких изменений за весь проход цикла. Это происходит, когда все помещения были заменены и удалены, а ввод начинается с therefore.

Третья замена соответствует первой строке ввода (которая есть therefore) или чему-либо в форме A = Aи удаляет ее. Если все предложения поддерживаются посылками, все они будут соответствовать этой форме, поэтому то, что остается, должно состоять исключительно из новых строк. Четвертая замена меняет это на right. В противном случае пятая замена заменяет все оставшееся (которое не содержит, rпоскольку thereforeбыло удалено) в wrong. Наконец, последняя замена добавляет Alex is в начале.

DLosc
источник
3

Python 2, 264 байта

Там уже замечательный ответ Python 3 от mbomb007 . Этот ответ вопиюще ворует из этого (в частности, уловка «Алекс неправда»).

И этот ответ также значительно длиннее, чем этот ...

Ну, в любом случае, идея в этом ответе состоит в том, чтобы поддерживать словарь пар ключ-значение, где ключи - это 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 на 26, как описано выше), который не зависит от количества строк ввода.

Теперь, когда я занимался этим решением, я понял, что могу сохранить четыре байта , используя строки вместо наборов для значений словаря, заменив

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

с участием

d={C:C for C in map(

Конечно, тогда вы также должны заменить (ПРИМЕЧАНИЕ: НЕ ДЕЛАЙТЕ ЭТОГО) три экземпляра операции set union |на конкатенацию строк +, но это не меняет длину кода. В результате все должно работать точно так же, за исключением того, что оно не будет устранять дубликаты, как вы делаете с наборами (оно будет просто добавлять в конец строки). Звучит хорошо - немного менее эффективно, конечно, но 260 байтов вместо 264.

Что ж, получается, что 260-байтовая версия настолько неэффективна, что это вызвало, MemoryErrorкогда я тестировал ее с

A = B
A = B
therefore
B = A

Это было удивительно для меня. Давайте исследуем 260-байтовую версию «конкатенации строк»!

Конечно, это началось бы с пар ключ-значение A:Aи B: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=Aи 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:...

Да уж. Возможно, это не будет очень эффективной реализацией.

mathmandan
источник
Мой ответ не «велик», поскольку он недействителен, но это была заслуживающая внимания попытка. Жаль, что я не смог заставить его работать.
mbomb007
1
@ mbomb007 Да, мне жаль это слышать. (Я действительно думал, что у вас был классный подход!) Поскольку вы возражали против слова «великий», я заменил «замечательный». :)
mathmandan
2

ES6, 128 байт

Свободно основанный на версии Ruby.

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

Ищет любое несобственное равенство перед «следовательно» и рекурсивно заменяет переменную по всей строке каждый раз (это сохраняет байты в цикле 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, но для некоторых других входных данных неправильно утверждает, что Алекс неправ. Он использует аналогичный подход, но для каждой предпосылки просто устанавливает вторую запись в текущее значение первой записи. При сравнении он смотрит только на точные значения вместо поиска по дереву.

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

ughoavgfhw
источник
1

05AB1E , 32 байта

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

Вдохновленный ответом Cadam @aditsu .

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

…±º€ˆ      # 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-программа, это взять ввод из stdin, стереть строку therefore, заменить каждый A = Bпосле нее на ?=(A,B)и добавить write(\"Alex is right\");write(\"Alex is wrong\"). halt.. Затем paste -sd ,заменяет каждую новую строку, кроме последней, запятой, превращая ее в действительные два запроса к оболочке SWI-Prolog, которые затем выполняются с усеченным выводимым результатом до одной строки head -n1, которая требует <(...)вместо конвейера по причинам, выходящим за рамки Мое понимание. Все это, просто чтобы использовать встроенный !

Несвязанная строка
источник