Nén công thức boolean


16

Cú pháp

~không
/\
\/hay
tđúng
fsai
P, Q, FISH, vv: biến

(Toán tử được đưa ra theo thứ tự ưu tiên)

Giới thiệu

Một số công thức boolean có thể được thay đổi thành các hình thức khác nhau để làm cho chúng ngắn hơn. Ví dụ: công thức

~(~P /\ ~Q)

có thể thay đổi thành dạng ngắn hơn

P\/Q

trong khi công thức

P \/ ~P

có thể thay đổi thành dạng ngắn hơn

t

Thử thách

Trong thử thách này, bạn được yêu cầu viết một chương trình đó, đưa ra bất kỳ công thức boolean chỉ sử dụng /\, \/, ~, t, f, dấu ngoặc đơn, biến boolean (viết hoa), và khoảng trắng, kết quả đầu ra một hình thức ngắn nhất (vì có thể có nhiều hơn một hình thức ngắn nhất ) trong các ký tự của biểu thức đó tương đương với tất cả các phép gán của các biến. Mã ngắn nhất (trong bất kỳ ngôn ngữ) chiến thắng. I / O có thể được thực hiện theo bất kỳ cách hợp lý.

Ngoài ra, vì các câu trả lời rất khó để xác minh, sẽ rất hữu ích (nhưng không bắt buộc) để bao gồm một lời giải thích ngắn gọn về cách hoạt động của mã.


Trong phần "Thử thách", bạn không đề cập đến bất kỳ khoảng trắng nào, nhưng ví dụ của bạn có chúng. Tôi có nên xử lý chúng?
Victor Stafusa

4
Tôi nghĩ rằng quan điểm của Florent là nó là một vấn đề khó giải quyết nói chung, hãy để một mình chơi golf. Trong số những thứ khác, trình phân tích cú pháp sẽ cần có khả năng xác định xem hai công thức tùy ý có cùng điều kiện sự thật hay không. Giảm p ^ ~ p là đủ dễ nếu p là nguyên tử, nhưng còn ((A ^ B) v (A ^ C)) ^ ~ (A ^ (BvC)) thì sao? Tôi nghĩ đó là một vấn đề tuyệt vời và tôi tò mò muốn xem một số phản hồi. Nhưng nếu bạn muốn các giải pháp ngắn, vấn đề có thể trở nên thuận lợi hơn cho việc chơi golf bằng cách A. sử dụng ký hiệu tiền tố và B. cung cấp danh sách các mức giảm cần thiết.
dfernig

1
Tôi có một giải pháp hợp lệ (được đánh gôn) với hơn 5000 ký tự. Điều này thật lố bịch ... Nó bao gồm một mã thông báo, trình phân tích cú pháp AST, trình ghi lại AST và trình tạo biểu thức.
Florent

1
Mathematica có thể thực hiện điều đó trong một hàm gọi ( BooleanMinimize)
Florent

1
Để ghi lại, bây giờ tôi có một giải pháp 498 ký tự, có sha256sum b9c98d088b78c30bb2108008a064a7b95722a4694d90ddad94a025c2eb4ed30a. Tôi sẽ đăng mã thực tế vào một ngày sau đó, vì tôi không muốn kìm hãm sự sáng tạo.
Lily Chung

Câu trả lời:


2

Oh đúng, tôi quên không bao giờ thực sự gửi câu trả lời của tôi. Về cơ bản, nó sử dụng chính xác cách tiếp cận mà câu trả lời của KSab sử dụng, nhưng chỉ in biểu thức hợp lệ ngắn nhất.

Python3, 493

e=lambda x:eval(x.replace('\\/','+').replace('/\\','%'),None,w)
class V(int):
 def __add__(s,o):return V(s|o)
 def __mod__(s,o):return V(s*o)
 def __invert__(s):return V(-s+1)
import re;from itertools import product as P;t=V(1);f=V(0);i=input();v=re.findall('[A-Z]+',i)
for k in range(1,len(i)):
 for m in P(''.join(v)+'~/\\tf',repeat=k):
  m=''.join(m)
  try:
   for d in P((V(0),V(1)),repeat=len(v)):
    w=dict(zip(v,d))
    if e(m)!=e(i):raise
  except:continue
  print(m);exit()
print(i)

Lưu ý rằng các hash tôi tính trước đó bao gồm các ký tự dòng mới và là trước khi tôi golfed def e(x): returnđểe=lambda x:


1

Con trăn 616

Không đặc biệt hiệu quả, nhưng hoạt động trong thời gian hợp lý cho các đầu vào có kết quả khoảng 5 hoặc 6 ký tự. Để kiểm tra một chuỗi để xem nó có khớp hay không, nó lặp qua mọi kết hợp có thể có của các giá trị thật / sai cho tất cả các biến và đảm bảo mỗi biến đều đồng ý. Sử dụng cái này, nó kiểm tra mọi chuỗi có thể bao gồm các ký tự có liên quan (thậm chí không nhất thiết phải là một chuỗi đúng về mặt cú pháp).

Nó thực sự sẽ in mọi biểu thức tương đương (ở mọi kích thước) và không thực sự chấm dứt.

Mã số:

c=['t','f'];o=['1 ','0 ']
def e(s,v):
 for k in v:s=s.replace(k,v[k])
 return eval(s)
def z(t,p='~/\\() '):
 w=[]
 if p=='':return[t]*(t not in['']+c)
 for s in t.split(p[0]):w.extend(z(s,p[1:]))
 w.sort(key=lambda v:-len(v));return w
def m(v):
 l=list('~\\/()')+v
 for s in l:yield s
 for r in m(v):
    for s in l:yield s+r
def n(x):
 if x<1:yield []
 else:
    for l in n(x-1):
     for b in o:yield[b]+l
t=raw_input();v=z(t)+c;l=len(v)
for s in m(v):
 g=1
 for y in n(l):
    y[-2:]=o;d=dict(zip(v+['/\\','\\/','~'],y+['and ','or ','not ']))
    try:
     if e(s,d)!=e(t,d):g=0
    except:g=0
 if g:print s

Đầu vào / Ouput:

> ~(~P /\ ~Q)
Q\/P
P\/Q
...

> P /\ ~P
f
~t
...

> (P \/ Q) /\ P
P
(P)
...
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.