Alex terkadang benar


50

Tantangan ini adalah untuk mengangkat semangat mod kami Alex A. , yang biasanya salah .


Misalkan Anda memiliki teman bernama Alex yang membutuhkan bantuan dengan logika dan matematika dasar, khususnya kesetaraan matematika .

Dia memberi Anda daftar persamaan bentuk di [variable] = [variable]mana a[variable] selalu huruf besar tunggal A sampai Z (bukan huruf kecil, bukan angka, atau apa pun). Ada satu persamaan per baris dalam daftar kecuali untuk satu baris yang hanya mengatakan therefore.

Semua persamaan di atas thereforeadalah premis , fakta yang dianggap benar. Semua persamaan di bawah ini thereforeadalah proposisi yang tidak diverifikasi, fakta yang berusaha disimpulkan Alex dari premis-premisnya, dan itu mungkin benar atau tidak benar.

Misalnya, dalam daftar persamaan ini proposisi kesimpulan tunggal A = Cternyata benar:

A = B
B = C
therefore
A = C

Adalah tugas Anda untuk memberi tahu Alex apakah semua proposisinya secara logis mengikuti dari tempat yang diberikan. Artinya, Anda perlu memberi tahu Alex apakah dia salah atau benar dalam kesimpulannya.

Tulis program / fungsi yang mengambil string dari daftar persamaan seperti yang dijelaskan dan dicetak / dikembalikan

Alex is right

jika semua kesimpulan mengikuti secara logis dari tempat, dan jika tidak, output

Alex is wrong

jika ada kesimpulan tidak secara logis mengikuti dari tempat.

Kode terpendek dalam byte menang.

Pastikan untuk mewaspadai kasus-kasus ini:

  • Variabel selalu sama dengan diri mereka sendiri. misalnya

    B = A
    therefore
    A = A
    X = X
    

    hasil dalam Alex is right.

  • Variabel dengan hubungan yang tidak diketahui tidak dapat dianggap sama. misalnya

    P = Q
    therefore
    E = R
    

    hasil dalam Alex is wrong.

  • Ketika tidak ada persamaan setelah itu thereforemaka kesimpulannya benar . misalnya

    D = C
    therefore

    dan

    therefore

    keduanya menghasilkan Alex is right.

  • Ketika tidak ada persamaan sebelum thereforemaka hanya kesetaraan diri dapat disimpulkan. misalnya

    therefore
    R = R
    

    menghasilkan Alex is right, tetapi

    therefore
    R = W
    

    hasil dalam Alex is wrong.

Lebih banyak contoh

Kasus Alex salah: (dipisahkan oleh garis kosong)

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 adalah kasus yang benar:

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 byte Alex is wrongMemverifikasi semua kasus uji.
Dennis

19
Hei, terkadang lebih baik daripada tidak sama sekali. ¯ \ _ (ツ) _ / ¯
Alex A.


7
therefore\nTABS < SPACES->Alex is right
Gagang Pintu

7
Senang melihat solusi dalam prolog.
Azz

Jawaban:


18

CJam, 49

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

Terinspirasi dari solusi Ruby histocrat. Cobalah secara online
3 byte terhapus berkat jimmy23013 :)

Penjelasan:

Untuk setiap premis, program mengganti variabel pertama dengan variabel ke-2 di seluruh teks. Kemudian memeriksa apakah ada kesimpulan dengan variabel yang berbeda.

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

Versi lama, 85

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

Ini menggunakan algoritma union-find. Cobalah online


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

1
Saya baru saja membaca baris terakhir sebagai 'Ini menggunakan algoritma unicorn -find' ... waitwot? xD
Jan

Alex is * wrong * right * ?
Charlie

32

Ruby, 80 76 + 2 = 78

Dengan bendera baris perintah p0, jalankan

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

Penjelasan:

Ini menggunakan manipulasi string murni. p0membaca input penuh sebagai string tunggal ke dalam variabel $_. Kemudian, kami berulang kali mencocokkan string itu dengan ekspresi reguler /(.) = (?!\1)(.)/, yang menemukan semua string dari bentuk "X = Y" di mana X dan Y bukan huruf yang sama, dan menetapkan X ke $ 1 dan Y ke $ 2. Ketika kecocokan seperti itu ditemukan, gsub$1,$2ganti semua instance X dengan Y dalam string. Kami juga memeriksa apakah kecocokan ini terjadi sebelum atau setelah "oleh karena itu" dengan

$`[/e/]

Jika itu terjadi setelah itu, itu adalah klaim yang tidak dapat dibenarkan dan Alex salah. Kami melacak apakah kejadian seperti itu terjadi saat menggunakan p=. Penggunaan psebagai variabel pelacakan mencegah hal-hal dari kerusakan jika loop tidak pernah menyentuh sekali pun, sejak itup akan mengembalikan nol jika tidak pernah ditugaskan.

Pada posting ini, solusi CJam lebih panjang. Sebuah momen singkat yang membanggakan, jika tidak diragukan.

Sunting: Yup, cepat dicopot. Juga, untuk menyelesaikan penjelasan, dengan pflag nilai akhir dari $_output di akhir eksekusi, jadi baris terakhir adalah output.


15
Momen termanis adalah saat sebelum solusinya dibantai oleh seorang esolang.
Alex A.

Penyalahgunaan String#formatuntuk mendapatkan panggilan gsub dan penugasan menjadi satu ekspresi adalah ide yang cukup rapi, +1!
Ventero

12

CJam, 83 75 68 67 64 byte

Terima kasih kepada Dennis untuk menghemat 1 byte.

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

Suite uji. Kasing uji terlalu panjang untuk permalink, jadi cukup salin dari pertanyaan. Perhatikan bahwa ini cukup lambat - dibutuhkan satu atau dua menit dalam juru bahasa online. Anda dapat membuatnya lebih cepat dengan mengubah 5*ke2* dalam hal ini akan menyelesaikan hampir seketika dan memecahkan semua kecuali satu kasus uji.

Penjelasan

(Sedikit ketinggalan jaman.)

Idenya adalah untuk melakukan semacam "mengisi banjir" dari persamaan yang mungkin dan kemudian menghapus semua persamaan yang kami dapatkan dari daftar kesimpulan. Dapat ditunjukkan bahwa kita membutuhkan tidak lebih dari 5 langkah dari pengisian banjir, karena itu akan mencakup jarak (dalam grafik awal ketidaksetaraan) tetapi jarak maksimum adalah 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.

Membangun penutupan transitif, eh? Saya tidak terbiasa dengan CJam, tetapi sepertinya generasi ke-5 persamaan hanya dapat dihasilkan dalam satu arah. Jika ya, Anda perlu satu iterasi lagi untuk membalikkan persamaan tersebut.
user2357112

@ user2357112 Saya percaya mereka harus dihasilkan di kedua arah, karena langkah pertama menambahkan semua membalikkan input (atau dalam versi yang golf lebih lanjut, saya mengurutkan semua premis dan kesimpulan persamaan untuk memulai).
Martin Ender

Ketika Anda mengambil perbedaan simetris, apakah Anda mendapatkan tepi di kedua arah? (Atau, dalam versi lebih lanjut golf, apakah perbedaan simetris menghasilkan tepi dalam arah yang diperlukan?)
user2357112

@ user2357112 Karena saya sedang memproses seluruh produk Cartesian, saya akan mendapatkan setiap pasangan persamaan di kedua pemesanan, yang akan menghasilkan kedua urutan kesimpulan yang ditarik (Satu-satunya alasan saya perlu membalikkan secara eksplisit, atau mengurutkan input awal, adalah bahwa tempat asli tidak perlu dihasilkan dalam proses ini, sehingga tidak terbalik dengan mengambil perbedaan yang ditetapkan dari produk Cartesian).
Martin Ender

6

R, 183 192 byte

Saya telah memodifikasi jawaban saya untuk mengatasi batasan yang ditunjukkan oleh user2357112. Masih ada kemungkinan yang sangat kecil untuk memanggil Alex ketika dia ternyata benar (yang sepertinya tidak terlalu sering terjadi jika saya memahami konteks tantangannya :-). Saya harap dia tidak keberatan.

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

Saya perlu sedikit menghilangkan golf:

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

Misalnya, jika inputnya adalah

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

pertama-tama akan mengevaluasi setup:

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

lalu premises

A = B
B = C

akan dijalankan masing-masing 1.000 kali dalam urutan acak. Ini untuk memastikan ("hampir pasti") bahwa semua persamaan disebarkan. Akhirnya, itu akan mengevaluasi propositions:

TRUE & A == B & B == C

3
Jika premisnya ada A = B, B = C, C = A, nilainya hanya berputar-putar selamanya. 26 putaran evaluasi tidak cukup.
user2357112

Logika saya yang gagal ... Terima kasih untuk contohnya, saya harus mengerjakan sesuatu yang lain.
flodel

Saya pikir memperbaikinya, atau hampir ...!
flodel

5

Haskell, 208 byte

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"

Saya menurunkan pekerjaan ke Data.Equivalence.Persistentmodul, yang menyediakan fungsi untuk memanipulasi kelas kesetaraan. Yang tersisa untuk dilakukan adalah mem-parsing fungsi input dan panggilan yang terkadang memiliki nama terlalu panjang untuk bermain golf yang tepat.

Contoh penggunaan:

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

Bekerja pada input string, sesuai tantangan.

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

Anda bisa kehilangan 8 byte dengan mendeklarasikan fsebagai fungsi murni, mengganti Simplify[#2,#1]dengan #2~Simplify~#, dan mengganti StringSplit[s,"\n"]dengan #~StringSplit~"<actual newline>".
LegionMammal978

Poin bagus! Juga q=StringSplit;dan kemudian s / StringSplit / q / selama 6 byte atau lebih disimpan. Tetapi pada akhirnya, ini bukan tantangan yang bagus untuk Mathematica, saya takut, meskipun karakter logika tampak pas.

Juga, a___dan b___mungkin bisa diubah menjadi a__dan b__, dan s=Symbol;.
LegionMammal978

a__dan b__tidak akan berfungsi jika bangunan, proposisi atau keduanya kosong

3

Retina, 90 byte

Untuk menjalankan, letakkan 12 baris kode berikut dalam 12 file terpisah (+11 byte dihitung untuk setiap file di luar yang pertama). <empty>menunjuk file kosong; \nmenunjuk baris baru literal. Sebagai alternatif, pertahankan \ns apa adanya, letakkan semua baris dalam satu file, dan gunakan -sopsi. Pastikan bahwa semua file menggunakan baris baru literal, bukan Windows \r\n, dan perhatikan ruang di akhir baris terakhir.

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

Bagaimana itu bekerja

Penggantian pertama cocok dengan premis pertama di input, setiap kali premis terjadi kemudian dalam file. Ini menggantikan kejadian kemudian dengan rhs dari premis. The +Memastikan pengubah bahwa penggantian ini diulang sampai tidak cocok lagi. Dengan demikian, jika premis pertama adalah A = B, semua As berikutnya dalam file dapat ditransmisikan menjadiB s.

Penggantian kedua menghapus premis pertama dari input, karena kita sudah selesai dengan itu sekarang. Lalu) pengubah loop kembali ke penggantian pertama, dan ulangi sampai tidak ada perubahan secara keseluruhan melewati loop. Ini terjadi ketika semua tempat telah diganti dan dihapus, dan input dimulai dengan therefore.

Penggantian ketiga cocok dengan baris input pertama (yaitu therefore) atau apa pun dari formulir A = A, dan menghapusnya. Jika semua proposisi didukung oleh premis, semuanya akan cocok dengan formulir ini, jadi yang tersisa hanya terdiri dari baris baru. Penggantian keempat mengubah ini menjadi right. Jika tidak, penggantian kelima mengubah semua yang tersisa (yang tidak mengandung rsejak thereforedihapus) menjadi wrong. Akhirnya, penggantian terakhir ditambahkan Alex is di awal.


3

Python 2, 264 byte

Sudah ada jawaban Python 3 yang luar biasa dari mbomb007 . Jawaban ini mencuri secara mencolok dari yang itu (khususnya trik "Alex is wrriognhgt").

Dan jawaban ini juga jauh lebih lama dari yang ...

Yah, bagaimanapun, ide dalam jawaban ini adalah untuk memelihara kamus pasangan nilai kunci, di mana kuncinya adalah 26 karakter huruf kapital, dan nilai masing-masing tombol yang terkait adalah himpunan huruf yang setara dengan kunci. (Jika semua 26 huruf itu setara, maka setiap tombol akan memiliki satu set 26 huruf untuk nilainya yang sesuai.)

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]

(Untuk menyimpan byte, jawaban ini menggabungkan spasi dan tab , yang sah menurut Python 2.)

Kode ini benar-benar sangat efisien, karena kamus terbatas pada ukuran maksimum yang dimungkinkan (26 x 26 seperti dijelaskan di atas) yang tidak bergantung pada jumlah baris input.

Sekarang, ketika saya bermain golf solusi ini, saya menyadari bahwa saya bisa menyimpan empat byte dengan menggunakan string daripada set untuk nilai-nilai kamus, dengan mengganti

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

dengan

d={C:C for C in map(

Tentu saja maka Anda juga harus mengganti (CATATAN: JANGAN LAKUKAN INI) tiga contoh operasi serikat yang ditetapkan |dengan rangkaian string+ , tetapi itu tidak mengubah panjang kode. Hasilnya adalah bahwa semuanya harus tetap berfungsi sama, kecuali itu tidak akan menghilangkan duplikat seperti yang Anda lakukan dengan set (itu hanya akan terus menambahkan ke ujung string). Kedengarannya OK - sedikit kurang efisien, pasti, tetapi 260 byte, bukan 264.

Nah, ternyata versi 260-byte sangat tidak efisien yang menyebabkan MemoryErrorketika saya mengujinya

A = B
A = B
therefore
B = A

Ini mengejutkan saya. Mari kita selidiki versi "string concatenation" 260-byte!

Tentu saja akan dimulai dengan pasangan kunci-nilai A:Adan B:B(ditambah 24 lainnya yang tidak penting). Kami akan menulis d[A]berarti nilai kamus sesuai dengan kunci A, jadi pada awalnya kami akan memiliki d[A] = A. Sekarang, mengingat premis A = B, itu akan dimulai dengan menggabungkan nilai-nilai d[A]=Adan d[B]=Buntuk mendapatkan y = AB. Maka akan mengulangi string ini dua kali: for v in AB: for w in AB:...

Jadi, pertama kali melalui loop, kita punya v=Adan w=A. Menerapkan d[v] += d[w]dan d[w] += d[v]menghasilkan urutan kamus berikut:

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

Selanjutnya, dengan v=Adan w=B:

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

Berikutnya, 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])

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

Urutan langkah-langkah di atas akan menerapkan premis tunggal A = B, dengan kesimpulan yang Asama dengan setiap huruf dalam string AAAABBAAAABAAAAB, sedangkan Bsama dengan setiap huruf dalam BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Sekarang, anggaplah bahwa premis berikutnya adalah A = B lagi . Anda pertama kali menghitung y = d[A] + d[B] = AAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB.

Selanjutnya, Anda mengulangi string ini dua kali: for v in y: for w in y:...

Ya. Mungkin itu bukan implementasi yang sangat efisien.


Jawaban saya tidak "bagus" karena tidak valid, tetapi itu merupakan upaya yang patut dicatat. Sayang sekali saya tidak bisa membuatnya bekerja.
mbomb007

1
@ mbomb007 Huh, maaf mendengarnya. (Saya pikir Anda memiliki pendekatan yang keren!) Karena Anda keberatan dengan kata "hebat", saya telah mengganti "luar biasa". :)
mathmandan

2

ES6, 128 byte

Secara longgar didasarkan pada versi Ruby.

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

Mencari non-self-equality before the "Oleh karena itu" dan secara rekursif mengganti variabel sepanjang string setiap kali (ini menghemat byte selama loop sementara).


1

C, 240 byte

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

Ini bekerja dengan menggabungkan nilai-nilai ke dalam set tree, sehingga setiap nilai yang setara mengarah ke set root yang sama. Tidak disatukan, dengan tipe implisit dibuat eksplisit.

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

Versi yang lebih pendek ini berfungsi untuk semua kasus dari OP, tetapi untuk beberapa input lainnya secara tidak benar mengklaim Alex salah. Ini menggunakan pendekatan yang sama, tetapi untuk setiap premis hanya mengatur entri kedua dengan nilai saat ini dari entri pertama. Saat membandingkan, itu terlihat hanya pada nilai yang tepat daripada mencari pohon.

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

Contoh input yang gagal dilakukan:

A = B
C = B
karena itu
A = C


1

05AB1E , 32 byte

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

Terinspirasi oleh @aditsu 's CJam jawabannya .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

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

Lihat tip tambang 05AB1E ini (bagian Cara menggunakan kamus? ) Untuk memahami mengapa …±º€ˆini "alex is "dan „–у©itu "wrong right".


0

bash + awk + SWI-Prolog , 167 byte

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)

Cobalah online!

Awalnya, ini hanya akan menjadi jawaban Prolog, tetapi alat yang bisa saya temukan untuk benar-benar mengubah format input menjadi sesuatu yang dapat digunakan cukup terbatas sehingga saya memutuskan untuk melakukan bagian itu dalam bash, meskipun saya hampir tidak memiliki pengalaman melakukan sesuatu dengan bash, dan bahkan tidak pernah menyentuh awk. Saya akhirnya menghabiskan berjam-jam di atasnya untuk ingin mempostingnya bahkan setelah itu tumbuh menjadi 167-byte ini, nyaris tidak golf sama sekali monster.

Pada dasarnya, apa yang dilakukan program awk adalah mengambil input dari stdin, menghapus baris therefore, ganti setiap A = Bsetelahnya dengan ?=(A,B), dan menambahkan write(\"Alex is right\");write(\"Alex is wrong\"). halt.. Kemudian, paste -sd ,ganti setiap baris baru tetapi yang terakhir dengan koma, mengubahnya menjadi dua kueri yang valid ke shell SWI-Prolog, yang kemudian dijalankan dengan hasil cetak yang terpotong menjadi satu baris head -n1, yang membutuhkan <(...)alih-alih pipa karena alasan di luar pemahaman saya. Semua ini, hanya menggunakan builtin !

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.