พิสูจน์ฉันผิด!


22

บทนำ

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

สเปค

อินพุต

การป้อนข้อมูลของคุณจะเป็นสูตรในรูปแบบปกติซึ่งเชื่อมต่อกัน สำหรับรูปแบบคุณสามารถใช้รูปแบบด้านล่างหรือกำหนดรูปแบบของคุณเองตามความต้องการในภาษาของคุณ (คุณไม่สามารถเข้ารหัสในรูปแบบได้มากกว่า CNF ล้วนๆ) อย่างไรก็ตามกรณีทดสอบ (ที่นี่) มีให้ในรูปแบบด้านล่าง (แม้ว่าจะไม่สร้างตัวคุณเองยากเกินไป)

ข้อมูลที่คุณป้อนจะเป็นรายการของรายการตัวแปร (คุณอาจอ่านเป็นสตริง / ต้องการสตริง) อินพุตเป็นสูตรในรูปแบบปกติที่เชื่อมต่อกัน (CNF) ที่เขียนเป็นชุดคำสั่งแต่ละรายการเป็นรายการสองรายการ รายการแรกในข้อเข้ารหัสตัวอักษรบวก (ตัวแปร) รายการที่สองเข้ารหัสตัวอักษร (ลบ) ตัวแปร (ตัวแปร) ตัวแปรทั้งหมดในส่วนคำสั่งคือ OR'ed เข้าด้วยกันและส่วนคำสั่งทั้งหมดเป็น AND'ed เข้าด้วยกัน

หากต้องการทำให้ชัดเจนยิ่งขึ้น[[[A,B],[C]],[[C,A],[B]],[[B],[A]]]สามารถอ่านได้ที่:
(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))

เอาท์พุต

ผลลัพธ์คือบูลีนเช่นค่าความจริงบางอย่างหรือค่าเท็จบางอย่าง

จะทำอย่างไร?

ง่ายมาก: ตรวจสอบว่าสูตรที่ให้ไว้ในมือเป็นที่น่าพอใจหรือไม่เช่นมีการมอบหมายค่าจริงและเท็จบางส่วนให้กับตัวแปรทั้งหมดหรือไม่ซึ่งสูตรโดยรวมให้ผลเป็น "จริง" ผลลัพธ์ของคุณจะเป็น "จริง" หากสูตรนั้นเป็นที่พอใจและ "เป็นเท็จ" หากไม่ใช่
Fun-Fact: นี่เป็นปัญหา NP-complete ในกรณีทั่วไป
หมายเหตุ: การสร้างตารางความจริงและตรวจสอบว่ารายการใด ๆ ที่เกิดขึ้นเป็นจริงได้รับอนุญาต

คดีมุม

หากคุณได้รับรายการระดับ 3 ที่ว่างเปล่าแสดงว่าไม่มีตัวแปร (บวก / ลบ) ในประโยคนั้น - อินพุตที่ถูกต้อง
คุณสามารถออกจากกรณีมุมอื่น ๆ ที่ไม่ได้กำหนดถ้าคุณต้องการ
นอกจากนี้คุณยังสามารถกลับมาจริงเมื่อสูตรว่าง (รายการระดับที่ 1) และเท็จตามข้อที่ว่างเปล่า (รายการระดับที่ 2)

ใครชนะ?

นี่คือ code-golf ดังนั้นคำตอบสั้น ๆ ในหน่วยไบต์ชนะ!
ใช้กฎมาตรฐานแน่นอน

การทดสอบกรณี

[[[P],[Q,R]],[[Q,R],[P]],[[Q],[P,R]]] -> true
[[[],[P]],[[S],[]],[[R],[P]],[[U],[Q]],[[X],[R]],[[Q],[S]],[[],[P,U]],[[W],[Q,U]]] -> true
[[[],[P,Q]],[[Q,P],[]],[[P],[Q]],[[Q],[P]]] -> false
[[[P],[]],[[],[P,S]],[[P,T],[]],[[Q],[R]],[[],[R,S]],[[],[P,Q,R]],[[],[P]]] -> false
optional behavior (not mandatory, may be left undefined):
[] -> true (empty formula)
[[]] -> false (empty clause)
[[[],[]]] -> false (empty clause)

1
เราจะรับอินพุตเป็น(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))อะไรได้บ้าง
59

1
@ Adámตามที่ระบุไว้ในความท้าทายรูปแบบขึ้นอยู่กับคุณทั้งหมดตราบใดที่มันไม่ได้เข้ารหัสข้อมูลมากกว่ารายการตามรายการ (เช่นสูตรที่คุณให้ไว้จะได้รับอนุญาตอย่างเต็มที่)
SEJPM

@SEJPM หากฉันเข้าใจเอกสารอย่างถูกต้องฉันคิดว่ากรณีทดสอบที่ 3 และ 4 ควรกลับมาจริง ฉันลองใช้การแทนที่ (P, Q) = (1,1) และ (P, Q, R, S, T) = (0,0,0,0,0) และพบทั้งสองจริงดังนั้นอย่างน้อยควรมีหนึ่ง กรณีที่นิพจน์เป็นจริง
busukxuan

@ busukxuan ฉันมั่นใจ 100% คนที่สามและสี่เป็นเท็จ สำหรับ 3): นี่คือ{{P,Q},{P,!Q},{!P,Q},{!P,!Q}}(ไม่อยู่ในคำสั่งนี้) ซึ่งสามารถแสดงได้ง่ายคือความขัดแย้ง สำหรับ 4): นี่เป็นความขัดแย้งเล็กน้อยเพราะเป็นP AND ... AND (NOT P)สิ่งที่เห็นได้ชัดว่าไม่เป็นความจริงสำหรับคุณค่าใด ๆ ของ P.
SEJPM

2
ตลกรหัสที่สั้นกว่าจริง ๆ ต้องใช้ความพยายามมากขึ้น
user6245072

คำตอบ:


41

Mathematica ขนาด 12 ไบต์

SatisfiableQ

มันมีในตัว ...

And[Or[a, b, Not[c], Not[d]], Or[...], ...]รูปแบบอินพุตเป็น นี้ไม่ทำงานอย่างถูกต้องสำหรับว่างย่อยแสดงออกเพราะOr[]เป็นFalseและเป็นAnd[]True

สำหรับเร็กคอร์ดโซลูชันที่ได้รับรูปแบบรายการจากการท้าทายและทำการแปลงเองคือ 44 ไบต์ แต่ OP ได้ชี้แจงในความคิดเห็นว่ารูปแบบใดดีตราบใดที่ไม่เข้ารหัสข้อมูลเพิ่มเติม:

SatisfiableQ[Or@@Join[#,Not/@#2]&@@@And@@#]&

18
เพราะ Mathematica ...
Leun Nun

11
Mathematica มีจำนวนบิวด์อินอย่างแท้จริง
TuxCrafting

3
@ TùxCräftîñg แท้จริง
jpmc26

15
สำหรับเสี้ยววินาทีฉันคิดว่าคำตอบนี้เขียนใน esolang ที่คลุมเครือและซ้อนกันโดยที่มีโอกาสเพียงแค่ลำดับคำสั่งS a t i s f i a b l e Qจะแก้ปัญหาได้ เท่านั้นแล้วการอ่านจับใจความเคาะประตู ...
ojdo

3

Haskell, 203 200 ไบต์

t=1<3
e%((t,f):r)=or((e<$>t)++map(not.e)f)&&e%r
e%_=t
u v b e s|s==v=b|t=e s
s e[]c=1<0
s e(v:w)c=e%c||s(u v t e)w c||s(u v(1<0)e)w c
g v[]=v
g v((t,f):r)=g(v++[x|x<-t++f,notElem x v])r
g[]>>=s(\x->t)

ความท้าทายนี้สมควรได้รับคำตอบที่ไม่ต้องทำดังนั้นคุณจึงไปได้ ลองบน ideone อัลกอริทึมนั้นจะพยายามกำหนดค่าตัวแปรทั้งหมดและตรวจสอบว่าหนึ่งในนั้นสอดคล้องกับสูตรหรือไม่

อินพุตอยู่ในรูปแบบของ[([],["P","Q"]),(["Q","P"],[]),(["P"],["Q"]),(["Q"],["P"])]แม้ว่าจะแทนสตริงทุกประเภทที่มีความเท่าเทียมกันจะใช้ได้

รหัสไม่ได้รับการตอบกลับ:

type Variable   = String
type CNF        = [([Variable], [Variable])]
type Evaluation = (Variable -> Bool)

satisfies :: Evaluation -> CNF -> Bool
satisfies eval [] = True
satisfies eval ((t,f):r) = or(map eval t ++ map (not.eval) f) && satisfies eval r

update :: Evaluation -> Variable -> Bool -> Evaluation
update eval s b var = if var == s then b else eval var

search :: Evaluation -> [Variable] -> CNF -> Bool
search eval [] cnf = False
search eval (v:vars) cnf = satisfies eval cnf || search (update eval v True) vars cnf || search (update eval v False) vars cnf 

getVars :: CNF -> [Variable] -> [Variable]
getVars [] vars = vars
getVars ((t,f):cnf) vars = getVars cnf (vars ++ [v |v<-(t++f), notElem v vars])

isSat :: CNF -> Bool
isSat cnf = search (\x->True) (getVars cnf []) cnf

1

JavaScript 6, 69B

x=>f=(v,e)=>(e=v.pop())?[0,1].some(t=>f([...v],eval(e+'=t'))):eval(x)

การใช้งาน:

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