บางครั้งอเล็กซ์พูดถูก


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
เฮ้บางครั้งดีกว่าไม่เคย ¯ \ _ (ツ) _ / ¯
Alex A.


7
therefore\nTABS < SPACES->Alex is right
Doorknob

7
ชอบที่จะเห็นทางออกในการเปิดฉาก
azz

คำตอบ:


18

CJam, 49

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

แรงบันดาลใจจากสารละลายทับทิมของฮิสโตแคต ลองออนไลน์
3 ไบต์หายไปขอบคุณ jimmy23013 :)

คำอธิบาย:

สำหรับแต่ละหลักฐานโปรแกรมจะแทนที่ตัวแปรแรกด้วยตัวแปรที่ 2 ในส่วนที่เหลือของข้อความ จากนั้นตรวจสอบว่ามีข้อสรุปใด ๆ กับตัวแปรที่แตกต่างกันหรือไม่

"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
ฉันเพิ่งอ่านบรรทัดสุดท้ายว่า 'นี่ใช้อัลกอริธึมยูนิคอร์น - ค้นหา' …เดี๋ยวก่อน? xD
ม.ค.

Alex is * wrong * right * ?
Charlie

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 อีกต่อไป ความภาคภูมิใจถ้าไม่ต้องสงสัยเลยสักครู่หายวับไป

แก้ไข: Yup ปลดสมบัติอย่างรวดเร็ว นอกจากนี้เพื่อให้คำอธิบายเสร็จสิ้นด้วยpแฟล็กค่าสุดท้ายของ$_คือเอาต์พุตเมื่อสิ้นสุดการประมวลผลดังนั้นบรรทัดสุดท้ายคือเอาต์พุต


15
ช่วงเวลาที่หอมหวานที่สุดคือช่วงเวลาก่อนการแก้ปัญหาของคนหนึ่งที่ถูกฆ่าโดย esolang
Alex A.

การใช้String#formatทั้งการเรียก gsub และการมอบหมายให้เป็นหนึ่งในการแสดงออกที่ไม่เหมาะสมเป็นความคิดที่ประณีต +1!
Ventero

12

CJam, 83 75 68 67 64 ไบต์

ขอบคุณ Dennis ที่ช่วยประหยัด 1 ไบต์

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

ชุดทดสอบ กรณีทดสอบยาวเกินไปสำหรับลิงก์ถาวรดังนั้นเพียงคัดลอกมาจากคำถาม โปรดทราบว่านี่ค่อนข้างช้า - ใช้เวลาหนึ่งหรือสองนาทีในล่ามออนไลน์ คุณสามารถทำให้เร็วขึ้นมากโดยเปลี่ยน5*เป็น2*กรณีที่จะเสร็จเกือบทันทีและแก้ปัญหาทั้งหมดยกเว้นกรณีทดสอบหนึ่ง

คำอธิบาย

(ล้าสมัยเล็กน้อย)

แนวคิดคือการจัดเรียงของ "การเติมน้ำท่วม" ของความเท่าเทียมที่เป็นไปได้และจากนั้นลบความเท่าเทียมทั้งหมดที่เราได้รับจากรายการสรุป แสดงให้เห็นว่าเราไม่จำเป็นต้องเติมน้ำท่วมเกินกว่า 5 ขั้นตอนเพราะสิ่งเหล่านั้นจะครอบคลุมระยะทาง (ในกราฟเริ่มต้นของความไม่เท่าเทียมกัน) แต่ระยะทางสูงสุดคือ 2525 = 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 ฉันเชื่อว่าพวกเขาควรจะสร้างขึ้นในทั้งสองทิศทางเนื่องจากขั้นตอนแรกจะเพิ่มการย้อนกลับของอินพุตทั้งหมด (หรือในเวอร์ชันที่ตีกอล์ฟต่อไป
Martin Ender

เมื่อคุณใช้ความแตกต่างแบบสมมาตรคุณจะได้ขอบทั้งสองด้านหรือไม่? (หรือในเวอร์ชันที่ตีกอล์ฟต่อไปความแตกต่างของสมมาตรจะสร้างขอบในทิศทางที่ต้องการหรือไม่)
user2357112

@ user2357112 เนื่องจากฉันกำลังประมวลผลผลิตภัณฑ์คาร์ทีเซียนทั้งหมดฉันจะได้รับความเท่าเทียมกันในการสั่งซื้อทั้งคู่ซึ่งจะส่งผลในการเรียงลำดับของข้อสรุปที่วาด (เหตุผลเดียวที่ฉันต้องย้อนกลับอย่างชัดเจนหรือเรียงลำดับอินพุตเริ่มแรกคือ ว่าสถานที่ดั้งเดิมไม่จำเป็นต้องสร้างในกระบวนการนี้ดังนั้นพวกเขาจะไม่กลับรายการโดยใช้ความแตกต่างที่ตั้งไว้ของผลิตภัณฑ์คาร์ทีเซียน)
Martin Ender

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

ฉันต้องการ de-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")

ตัวอย่างเช่นถ้าอินพุตเป็น

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

มันจะประเมินsetup:

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

จากนั้น premises

A = B
B = C

จะถูกเรียกใช้ 1,000 ครั้งในลำดับแบบสุ่ม นี่คือเพื่อให้แน่ใจว่า ("เกือบจะแน่ใจ") ว่ามีการเผยแพร่ความเท่าเทียมกันทั้งหมด ในที่สุดมันจะประเมินpropositions:

TRUE & A == B & B == C

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

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

ทำงานกับอินพุตสตริงตามความท้าทาย

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 ของสถานที่ โมดิ+ฟายเออร์ช่วยให้มั่นใจได้ว่าการเปลี่ยนจะทำซ้ำจนกว่าจะไม่ตรงกันอีกต่อไป ดังนั้นถ้าหลักฐานแรกคือs A = Bทั้งหมดที่ตามมาAในไฟล์จะถูกแปลงเป็นBs

การแทนที่ครั้งที่สองจะลบหลักฐานแรกออกจากอินพุตเนื่องจากเราทำเสร็จแล้วในตอนนี้ จากนั้น)ตัวดัดแปลงจะวนกลับไปที่การแทนที่ครั้งแรกและทำซ้ำจนกว่าจะไม่มีการเปลี่ยนแปลงในการส่งผ่านทั้งวง thereforeนี้เกิดขึ้นเมื่อสถานที่ทั้งหมดได้รับการทดแทนและลบออกและการป้อนข้อมูลเริ่มต้นด้วย

การแทนที่ที่สามตรงกับบรรทัดแรกของอินพุต (ซึ่งคือtherefore) หรือสิ่งใด ๆ ของแบบฟอร์มA = Aและลบออก หากข้อเสนอทั้งหมดได้รับการสนับสนุนจากสถานที่ทั้งหมดของพวกเขาจะตรงกับแบบฟอร์มนี้ดังนั้นสิ่งที่เหลือควรประกอบด้วยเพียงการขึ้นบรรทัดใหม่ rightเปลี่ยนที่สี่การเปลี่ยนแปลงนี้ลงใน มิฉะนั้นการเปลี่ยนห้าทุกอย่างเปลี่ยนแปลงที่เหลือ (ซึ่งไม่ได้มีrตั้งแต่thereforeถูกลบ) wrongลง ในที่สุดการเปลี่ยนครั้งล่าสุดจะเพิ่มAlex is ที่จุดเริ่มต้น


3

Python 2, 264 ไบต์

แล้วมีที่น่าทึ่งหลาม 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 x 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

ฉันประหลาดใจมาก มาตรวจสอบเวอร์ชั่น "string concatenation" ขนาด 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ขณะที่มีค่าเท่ากับตัวอักษรในทุกBBAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB

ทีนี้สมมติว่าหลักฐานต่อไปคือ 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')

ค้นหาความไม่เท่าเทียมกันของตัวเองก่อน "ดังนั้น" และ recurisvely แทนที่ตัวแปรตลอดทั้งสตริงในแต่ละครั้ง


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 แต่สำหรับอินพุตอื่นบางอย่างไม่ถูกต้องอ้างว่า Alex ผิด มันใช้วิธีการที่คล้ายกัน แต่สำหรับแต่ละสถานที่ตั้งเพียงรายการที่สองให้เป็นมูลค่าปัจจุบันของรายการแรก เมื่อเปรียบเทียบจะมองเฉพาะค่าที่แน่นอนแทนที่จะค้นหาต้นไม้

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

แรงบันดาลใจจาก@aditsuคำตอบ CJam 's

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

…±º€ˆ      # 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 แต่เครื่องมือที่ฉันสามารถค้นหาเพื่อเปลี่ยนรูปแบบการป้อนข้อมูลให้เป็นสิ่งที่ใช้งานได้มีข้อ จำกัด เพียงพอที่ฉันตัดสินใจที่จะทำส่วนนั้นด้วยการทุบตีแม้ว่าฉันจะไม่มีประสบการณ์ ทำอะไรในทุบตีและไม่เคยแตะต้องเลยแม้แต่น้อย ท้ายที่สุดฉันใช้เวลามากพอที่จะโพสต์มันแม้หลังจากที่มันเติบโตเป็น 167- ไบต์นี้แทบจะไม่เล่นกอล์ฟกับสัตว์ประหลาดทุกตัว

โดยพื้นฐานแล้วสิ่งที่โปรแกรม awk ไม่คือการใช้การป้อนข้อมูลจาก stdin ลบบรรทัดที่มีthereforeเปลี่ยนทุกA = Bหลังด้วยและผนวก?=(A,B) write(\"Alex is right\");write(\"Alex is wrong\"). halt.จากนั้นpaste -sd ,แทนที่ทุกบรรทัดใหม่ แต่สุดท้ายด้วยเครื่องหมายจุลภาคเปลี่ยนมันเป็นสองแบบสอบถามที่ถูกต้องเพื่อเปลือก SWI-Prolog ซึ่งจะทำงานด้วยผลการพิมพ์ที่ถูกตัดทอนเป็นหนึ่งบรรทัดโดยhead -n1ที่ต้องใช้<(...)แทนท่อไปด้วยเหตุผลเกิน ความเข้าใจของฉัน ทั้งหมดนี้เพียงใช้builtin !

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.