Алекс іноді має рацію


50

Це завдання полягає в піднятті духу нашого мода Алекса А. , який, як правило, помиляється .


Припустимо, у вас є друг на ім’я Алекс, якому потрібна допомога з базової логіки та математики, зокрема математичної еквівалентності .

Він дає вам список рівнянь форми, [variable] = [variable]де а [variable]- це завжди одна велика літера А - 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
Гей, іноді краще, ніж ніколи. ¯ \ _ (ツ) _ / ¯
Олексій А.


7
therefore\nTABS < SPACES->Alex is right
Дверна ручка

7
Люблю бачити рішення в пролозі.
azz

Відповіді:


18

CJam, 49

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

Натхненний рішенням Рубі з гістократом. Спробуйте в Інтернеті
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"?

Для цього використовується алгоритм пошуку об'єднання. Спробуйте в Інтернеті


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 поверне нуль, якщо він ніколи не був призначений.

Станом на цю посаду рішення CJam довше. Гордий, якщо без сумніву, швидкоплинний момент.

Редагування: Так, швидко детронувались. Також, щоб закінчити пояснення, з pпрапором кінцеве значення $_виводиться в кінці виконання, тому останній рядок є вихідним.


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 байт

Я змінив свою відповідь, щоб вирішити обмеження, вказане користувачем2357112. Досі існує надзвичайно мала ймовірність визволити Алекса, коли він насправді має рацію (що, здається, не часто трапляється, якщо я розумію контекст виклику :-). Я сподіваюся, що він не буде проти.

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

3
Якщо приміщення є A = B, B = C, C = A, значення просто кружляють назавжди. 26 раундів оцінювання недостатньо.
user2357112

Моя невдала логіка ... Дякую за приклад, мені доведеться потім попрацювати ще щось.
флодел

Я думаю, виправили це, або майже ...!
флодель

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 у файлі перетворюються наB s.

Друга заміна видаляє першу передумову з вхідних даних, оскільки ми це зробили зараз. Потім )модифікатор циклічно повертається до першої заміни і повторюється, поки не було змін цілого проходу через цикл. Це відбувається, коли всі приміщення були замінені та видалені, і вхід починається з therefore.

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


3

Python 2, 264 байт

Вже є чудова відповідь Python 3 від mbomb007 . Ця відповідь відверто крадеться від тієї (зокрема, фокус "Алекс 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 на 26, як описано вище), який не залежить від кількості рядків введення.

Тепер, переглядаючи це рішення, я зрозумів, що можу зберегти чотири байти , використовуючи рядки замість наборів для значень словника, замінивши

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

з

d={C:C for C in map(

Зрозуміло, тоді вам також доведеться замінити (ПРИМІТКА: НЕ РОБИТИ ЦЕ) три екземпляри встановленої операції з'єднання |з контактецією рядків+ , але це не змінює довжину коду. Результат полягає в тому, що все ще має працювати точно так само, за винятком того, що це не усуне дублікатів, як ви робите з наборами (воно просто продовжуватиме додавати на кінець рядка). Звучить добре - трохи менш ефективно, впевнено, але 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:...

Так. Можливо, це було б не дуже ефективною реалізацією.


Моя відповідь не "чудова", оскільки вона недійсна, але це була примітна спроба. Шкода, що я не міг змусити його працювати.
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')

Шукає будь-яку несамостійність перед "отже" і рекурсивно замінює змінну у всьому рядку щоразу (це економить байти протягом певного циклу).


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

Це працює за допомогою комбінування значень у встановлені дерева, тому будь-які еквівалентні значення призводять до того ж встановленого кореня. Безголівковий, із неявними типами, зробленими явними.

// 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 байт

Ця коротша версія працює у всіх випадках із ОП, але для деяких інших даних неправильно стверджується, що Алекс помиляється. Він використовує аналогічний підхід, але для кожної передумови просто встановлюється другий запис поточним значенням першого запису. При порівнянні він дивиться лише на точні значення замість пошуку дерева.

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è«.ª

Натхненний відповіддю CJam @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)

Спробуйте в Інтернеті!

Спочатку це була просто відповідь Prolog, але інструменти, які я міг знайти, щоб насправді перетворити вхідний формат у щось корисне, були достатньо обмеженими, що я вирішив виконати цю частину в 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, що вимагає <(...)замість труби з інших причин моє розуміння. Все це, просто для використання вбудованого !

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.