ブール式の圧縮


16

構文

~ない
/\
\/もしくは
t
f
PQFISH、など:変数

(演算子は優先順位の順に与えられます)

前書き

一部のブール式は、短くするために異なる形式に変更できます。たとえば、式

~(~P /\ ~Q)

短い形式に変更できます

P\/Q

数式

P \/ ~P

短い形式に変更できます

t

チャレンジ

この課題では、のみ使用して、任意のブール式が与えられると、そのプログラムの書き込みに必要とされる/\\/~tf複数の最短形態が存在し得るので、括弧、ブール(大文字で)変数、および空白を、(最短形式を出力します)変数のすべての割り当てに相当する式の文字。最短のコード(すべての言語)が勝ちます。I / Oは、合理的な方法で実行できます。

また、答えを確認するのは難しいので、コードがどのように機能するかの簡単な説明を含めると役立ちます(ただし、必須ではありません)。


「チャレンジ」セクションでは、空白については言及していませんが、例には空白が含まれています。それらを処理する必要がありますか?
ビクターStafusa 14年

4
フロレントのポイントは、ゴルフだけでなく、一般的に解決するのが難しい問題だと思います。とりわけ、パーサーは、2つの任意の式が同じ真理条件を持っているかどうかを判断できる必要があります。pがアトミックであればp ^〜pを減らすのは簡単ですが、((A ^ B)v(A ^ C))^〜(A ^(BvC))はどうですか?私はそれがクールな問題だと思うし、私はいくつかの応答を見たいと思っています。ただし、短い解決策が必要な場合は、A。プレフィックス表記を使用して、B。必要な削減のリストを提供することにより、ゴルフをより助長することができます。
dfernig 14年

1
5000文字以上の有効な(ゴルフの)ソリューションがあります。これはばかげています...トークナイザー、ASTパーサー、ASTリライター、および式ジェネレーターで構成されています。
フローレント14年

1
Mathematicaは1回の関数呼び出しでそれを行うことができます(BooleanMinimize
Florent

1
記録のために、sha256sumがである498文字のソリューションがありb9c98d088b78c30bb2108008a064a7b95722a4694d90ddad94a025c2eb4ed30aます。創造性を抑えたくないため、実際のコードは後日掲載します。
リリーチョン

回答:


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

入力/出力:

> ~(~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.