การบีบอัดสูตรบูลีน


17

วากยสัมพันธ์

~ไม่
/\และ
\/หรือ
tจริง
fเท็จ
P, Q, FISHฯลฯ : ตัวแปร

(ผู้ประกอบการจะได้รับตามลำดับความสำคัญ)

บทนำ

บางสูตรบูลีนสามารถเปลี่ยนเป็นรูปแบบที่แตกต่างกันเพื่อให้สั้นลง ตัวอย่างเช่นสูตร

~(~P /\ ~Q)

สามารถเปลี่ยนเป็นแบบสั้น

P\/Q

ในขณะที่สูตร

P \/ ~P

สามารถเปลี่ยนเป็นแบบสั้น

t

ท้าทาย

ในความท้าทายนี้คุณจะต้องเขียนโปรแกรมที่ได้รับสูตรบูลใด ๆ โดยใช้เพียง/\, \/, ~, t, fวงเล็บตัวแปรบูลีน (ตัวพิมพ์ใหญ่) และช่องว่างเอาท์พุทเป็นรูปแบบที่สั้นที่สุด (เนื่องจากอาจมีมากกว่าหนึ่งรูปแบบที่สั้นที่สุด ) ในลักษณะของนิพจน์นั้นซึ่งเทียบเท่ากับการกำหนดตัวแปรทั้งหมด รหัสที่สั้นที่สุด (ในภาษาใด ๆ ) ชนะ I / O สามารถทำได้ในลักษณะที่สมเหตุสมผล

นอกจากนี้เนื่องจากคำตอบนั้นยากต่อการตรวจสอบจึงเป็นประโยชน์ (แต่ไม่จำเป็น) เพื่อรวมคำอธิบายสั้น ๆ เกี่ยวกับการทำงานของรหัส


ในส่วน "ความท้าทาย" ของคุณคุณไม่ได้กล่าวถึงช่องว่างใด ๆ แต่ตัวอย่างของคุณมี ฉันควรจัดการกับพวกเขาหรือไม่
Victor Stafusa

4
ฉันคิดว่าประเด็นของ Florent ก็คือมันเป็นปัญหายากที่จะแก้ไขโดยทั่วไป เหนือสิ่งอื่นใด parser จะต้องสามารถตรวจสอบว่าสูตรโดยพลการทั้งสองมีเงื่อนไขความจริงเดียวกัน การลด p ^ ~ p นั้นง่ายพอถ้า p เป็นอะตอม แต่ถ้า ((A ^ B) v (A ^ C)) ^ ~ (A ^ (BvC))? ฉันคิดว่ามันเป็นปัญหาที่เยี่ยมยอดและฉันอยากรู้อยากเห็นคำตอบบางอย่าง แต่ถ้าคุณต้องการแนวทางแก้ไขปัญหาระยะสั้นปัญหาอาจเอื้อต่อการเล่นกอล์ฟโดย A. โดยใช้เครื่องหมายคำนำหน้าและ B แสดงรายการของการลดที่จำเป็น
dfernig

1
ฉันมีทางออกที่ถูกต้อง (เล่นกอล์ฟ) มากกว่า 5,000 ตัวอักษร นี่มันไร้สาระ ... มันประกอบไปด้วย tokenizer, AST-parser, AST-rewriter และ expression generator
Florent

1
Mathematica สามารถทำได้ในการเรียกใช้ฟังก์ชันเดียว ( BooleanMinimize)
Florent

1
สำหรับบันทึกที่ฉันมีวิธีการแก้ปัญหา 498 ตัวอักษรตอนนี้ sha256sum b9c98d088b78c30bb2108008a064a7b95722a4694d90ddad94a025c2eb4ed30aซึ่งเป็น ฉันจะโพสต์รหัสจริงในภายหลังเนื่องจากฉันไม่ต้องการยับยั้งความคิดสร้างสรรค์
Lily Chung

คำตอบ:


2

โอ้ใช่ฉันลืมที่จะโพสต์คำตอบของฉัน มันใช้วิธีเดียวกันกับที่คำตอบของ KSabใช้ แต่พิมพ์เฉพาะนิพจน์ที่สั้นที่สุดเท่านั้น

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)

โปรดทราบว่าแฮชที่ฉันคำนวณไว้ก่อนหน้านั้นรวมถึงการขึ้นบรรทัดใหม่และก่อนที่ฉันdef e(x): returnจะตีกอล์ฟe=lambda x:


1

Python 616

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

มันจริงจะพิมพ์ทุกการแสดงออกเทียบเท่า (ทุกขนาด) และไม่เคยยุติ

รหัส:

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

Input / ouput:

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

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

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