Hay chưng minh tôi sai!


22

Giới thiệu

Nhiệm vụ của bạn trong cuộc sống rất đơn giản: Chứng minh người sai trên internet!
Để làm điều này, bạn thường cẩn thận phân tích các tuyên bố của họ và chỉ ra mâu thuẫn trong đó.
Đã đến lúc tự động hóa việc này, nhưng vì chúng ta lười biếng, chúng tôi muốn chứng minh rằng mọi người đã sai với nỗ lực ít nhất (đọc: mã ngắn nhất) có thể.

Đặc điểm kỹ thuật

Đầu vào

Đầu vào của bạn sẽ là một công thức ở dạng kết hợp bình thường . Đối với định dạng, bạn có thể sử dụng định dạng bên dưới hoặc xác định định dạng của riêng bạn, theo nhu cầu của ngôn ngữ của bạn (mặc dù bạn không thể mã hóa nhiều hơn ở định dạng so với CNF thuần túy). Tuy nhiên, các trường hợp thử nghiệm (ở đây) được cung cấp ở định dạng bên dưới (mặc dù nó sẽ không quá khó để tạo riêng cho bạn).

Đầu vào của bạn sẽ là một danh sách danh sách các danh sách các biến (bạn cũng có thể đọc nó dưới dạng chuỗi / chuỗi yêu cầu). Đầu vào là một công thức ở dạng kết hợp thông thường (CNF) được viết dưới dạng một tập các mệnh đề, mỗi mệnh đề là một danh sách gồm hai danh sách. Danh sách đầu tiên trong mệnh đề mã hóa các ký tự dương (biến), danh sách thứ hai mã hóa các ký tự phủ định (phủ định) (biến). Mọi biến trong mệnh đề được OR'ed với nhau và tất cả các mệnh đề được AND'ed với nhau.

Để làm cho nó rõ ràng hơn: [[[A,B],[C]],[[C,A],[B]],[[B],[A]]]có thể được đọc là:
(A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))

Đầu ra

Đầu ra là boolean, ví dụ hoặc một số giá trị trung thực hoặc một số giá trị giả.

Phải làm sao

Thật đơn giản: Kiểm tra xem công thức đưa ra có phù hợp hay không, ví dụ: liệu có tồn tại một số phép gán đúng và sai cho tất cả các biến sao cho công thức tổng thể mang lại "đúng" hay không. Đầu ra của bạn sẽ là "true" nếu công thức là satiesfible và "false" nếu nó không phải.
Fun-Fact: Đây là một vấn đề NP-đầy đủ trong trường hợp chung.
Lưu ý: Tạo bảng chân lý và kiểm tra xem bất kỳ mục kết quả nào là đúng, đều được phép.

Góc trường hợp

Nếu bạn nhận được một danh sách cấp 3 trống, thì không có biến (dương / âm) nào trong mệnh đề đó - một đầu vào hợp lệ.
Bạn có thể để các trường hợp góc khác không xác định nếu bạn muốn.
Bạn cũng có thể trả về true theo công thức trống (danh sách cấp 1) và sai theo mệnh đề trống (danh sách cấp 2).

Ai thắng?

Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng!
Quy tắc tiêu chuẩn áp dụng tất nhiên.

Các trường hợp thử nghiệm

[[[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
Chúng ta có thể lấy đầu vào là (A OR B OR (NOT C)) AND (C OR A OR (NOT B)) AND (B OR (NOT A))?
Adám

1
@ Adám, như được chỉ định trong thử thách, định dạng hoàn toàn tùy thuộc vào bạn, miễn là nó không mã hóa nhiều thông tin hơn so với định dạng dựa trên danh sách. (Ví dụ: công thức như bạn đã cho phép hoàn toàn được phép)
SEJPM

@SEJPM Nếu tôi hiểu ký hiệu chính xác, tôi nghĩ trường hợp kiểm tra thứ 3 và thứ 4 sẽ trả về đúng. Tôi đã thử thay thế (P, Q) = (1,1) và (P, Q, R, S, T) = (0,0,0,0,0) và thấy cả hai đều đúng, vì vậy ít nhất phải có một trường hợp biểu thức là đúng.
busukxuan

@busukxuan, tôi chắc chắn 100% là thứ ba và thứ tư là sai. Đối với 3): đây là {{P,Q},{P,!Q},{!P,Q},{!P,!Q}}(không theo thứ tự này) có thể dễ dàng hiển thị là một mâu thuẫn. Đối với 4): Đây là một mâu thuẫn tầm thường bởi vì nó P AND ... AND (NOT P)rõ ràng không bao giờ đúng với bất kỳ giá trị nào của P.
SEJPM

2
Thật buồn cười là mã ngắn hơn thực sự đòi hỏi nhiều nỗ lực hơn để được viết.
dùng6245072

Câu trả lời:


41

Toán học, 12 byte

SatisfiableQ

Chà, có tích hợp ...

Định dạng đầu vào là And[Or[a, b, Not[c], Not[d]], Or[...], ...]. Đây không hoạt động chính xác cho trống tiểu biểu thức, vì Or[]FalseAnd[]True.

Đối với bản ghi, một giải pháp nhận định dạng dựa trên danh sách từ thử thách và bản thân chuyển đổi là 44 byte, nhưng OP đã làm rõ trong một nhận xét rằng mọi định dạng đều ổn miễn là nó không mã hóa bất kỳ thông tin bổ sung nào:

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

18
Bởi vì Mathicala ...
Leaky Nun

11
Mathematica thực sự có số lượng dựng sẵn điên rồ ._.
Thiền vào

3
@ TùxCräftîñg Thật vậy .
jpmc26

15
Trong tích tắc, tôi nghĩ câu trả lời này được viết bằng một esolang tối nghĩa, xếp chồng lên nhau, trong đó, chỉ bằng cơ hội, chuỗi lệnh S a t i s f i a b l e Qsẽ giải quyết vấn đề. Chỉ sau đó, việc đọc hiểu đã gõ cửa ...
ojdo

3

Haskell, 203 200 byte

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)

Thử thách này xứng đáng với câu trả lời không có nội dung, vì vậy bạn hãy vào đây. Hãy thử nó trên ideone . Thuật toán chỉ cần thử tất cả các bài tập biến và kiểm tra xem một trong số chúng có thỏa mãn công thức không.

Đầu vào ở dạng [([],["P","Q"]),(["Q","P"],[]),(["P"],["Q"]),(["Q"],["P"])], mặc dù thay vì các chuỗi, mọi loại có đẳng thức sẽ hoạt động.

Mã bị đánh cắ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)

Sử dụng:

f('a|b')(['a','b'])
true
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.