Bir doğruluk tablosu verildiğinde, onu tatmin eden bir Stackylogic programı çıktılayın


17

Stackylogic, daha önceki bir zorlukta oluşturduğum bir programlama dilidir: Run Stackylogic . Tüm ayrıntılar ve örnekler için bu yayını okuyun, ancak nasıl yorumlandığı aşağıda açıklanmıştır:

Stackylogic alır 0sitesindeki ve 1giriş için sitesindeki ve tek bir çıkış olarak 0 veya 1üzerine tamamlama.

Bir program yalnızca karakterleri içeren satırlardan ve satırlardan 01?birinin <sonunda tam olarak bir satırdan oluşur. Çizgiler boş olmayabilir ve hattı <en az birine sahip olması gerekir 0, 1ya da ?ondan önce.

İşte hesaplayan bir örnek program NAND iki bit:

1
?<
11
?
0

Bir programdaki her satır , alt kısmı solda ve üst kısmı sağda olacak şekilde bir yığın olarak kabul edilir . Örtük olarak, bir programdaki ilk satırdan önce ve son satırdan sonra boş bir yığın (yani boş satır) vardır.

<Bir program çalıştırıldığında, imleç adı verilen işaretler yığın günü başlayacak. Yürütme aşağıdaki gibi devam eder:

  1. Üst karakteri imlecin şu anda işaret ettiği yığından çıkar.

    • Karakter ise ?, kullanıcıdan bir 0veya a 1isteyin ve karaktermiş gibi davranın.
    • Karakter ise 0, imleci bir yığın yukarı taşı (geçerli satırın üzerindeki satıra).
    • Karakter ise 1, imleci bir yığın aşağı taşı (geçerli satırın altındaki satıra).
  2. İmlecin hareket ettiği yığın boşsa, bir yığına atılan son değeri (her zaman a 0veya 1) çıkarın ve programı sonlandırın.

  3. Aksi takdirde, imlecin hareket ettiği yığın boş değilse, 1. adıma dönün ve işlemi tekrarlayın.

Bu zorluk için gerçekleştirilecek en önemli şey, tüm Stackylogic programlarının bir doğruluk tablosuna eşit olmasıdır . Bazı önceden belirlenmiş sayıda boolean değeri girilir ve tam olarak bir boolean deterministik olarak çıkar.

Bu nedenle göreviniz, verilen herhangi bir doğruluk tablosuyla aynı çıktıya sahip olan veya benzeyen bir Stackylogic programı oluşturmaktır. Ancak Stackylogic'in herhangi bir doğruluk tablosunu simüle edebileceği açık değildir , bu yüzden indüksiyonla bir kanıt :

Temel Durum

İki 0-girişli doğruluk tablosu her zaman 0veya çıktı veren tablolardır 1. Bu tabloların Stackylogic eşdeğerleri sırasıyla 0<ve 1<.

Endüktif Adım

Stackylogic'in herhangi bir N-giriş doğruluk tablosunu simüle edebileceğini varsayın. M = N + 1 olsun.

Bir M-giriş masası, T, iki N-tablo giriş, T olarak ifade edilebilir 0 ve T 1 , artı B 0 ek giriş biti B., T sonucu 0 kullanılır. B 1 olduğunda, T sonucu 1 kullanılır.

Örneğin, sözde koda karşılık gelen 3 girişli doğruluk tablosu

if B:
    result = x OR y
else:
    result = x NAND y

dır-dir

B x y | result
0 0 0 | 1
0 0 1 | 1
0 1 0 | 1
0 1 1 | 0
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1

Bu gerçekten NAND ve OR için iki girişli iki doğruluk tablosu.

S 0 ve S 1 sırasıyla T 0 ve T 1'i karşılayan Stackylogic programları olsun (bunların ilk varsayım temelinde var olduğunu biliyoruz). T'yi karşılayan S programı daha sonra şu şekilde yapılandırılabilir:

[lines of S0 excluding the cursor, with 0 appended to all lines below the cursor]
?<
[lines of S1 excluding the cursor, with 1 appended to all lines above the cursor]

S arasındaki Bu düzenleme etkili bir muxes 0 ve S 1 (hattından birinci giriş bit göre ?<). Eğer öyleyse, 0imleç ekli 0olanları S 0'ın orijinal imleç konumuna kadar sürecek, daha sonra boş yığınlarla üst ve alt kenarlarla sınırlanacak ve böylece orijinal S 0 ile tamamen aynı olacaktır . Aynı şekilde, 1girdidir, imleç binecek 1'S aşağı s 1 s imleç pozisyonu' ve yalnız sanki bunu çalıştırmak için devam edin.

Örneğin, OR ve NAND için Stackylogic programları

?
?<

ve

1
?<
11
?
0

Simüle etmek için birleştirilebilirler

if B:
    result = x OR y
else:
    result = x NAND y

şöyle:

1
?
110
?0
00
0
?<
?1
?

Böylece, herhangi bir doğruluk tablosu bir Stackylogic programı ile simüle edilebilir.

Meydan okuma

N giriş doğruluk tablosunu (N> 0) alan , tablo çıkışlarını artan ikili sırada temsil eden 2 N boole değeri listesi şeklinde alan bir program veya işlev yazın .

Herhangi bir makul giriş formatı uygundur. örneğin bir OR doğruluk tablosu için

x y | OR
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1

bu giriş stillerinden herhangi biri iyi olur:

0111

0, 1, 1, 1

0
1
1
1

[False, True, True, True]

Doğruluk tablosunu karşılayan, yani aynı girdi verildiğinde aynı çıktıya sahip bir Stackylogic programı yazdırın veya döndürün. Tabloyu sağlayan herhangi bir sonlu program geçerli çıktıdır. Endüktif kanıtın yapım yöntemini izlemenize gerek yoktur. Stackylogic programlarının en iyi şekilde kısa olması gerekmez.

Örneğin, girdi olsaydı, 11100111geçerli bir çıktı

1
?
110
?0
00
0
?<
?1
?

ama daha birçokları var.

Bayt cinsinden en kısa kod kazanır.

Bir tercümana ihtiyacınız varsa orijinal Stackylogic yarışmasına bakın .


N'yi ikinci bir girdi olarak alabilir miyiz?
Leaky Nun

@LeakyNun Evet (veya gerekirse 2 ^ N).
Calvin'in Hobileri

Yanıtlar:


8

Pyth, 53 bayt

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<

Çevrimiçi deneyin

Bu, Stackylogic'te keyfi doğruluk tablolarının nasıl uygulanacağı konusundaki zorlukta açıklanan sistemin tam bir uygulamasıdır. Doğruluk tablosunu ikiye böldük, yinelemeli olarak uyguladık ve sonra uygun şekilde 0 ve 1 ekledik.

Bu, dönüş değeri olan [1, ['0', '?', '1']], ilk sayı işaretçinin konumu, geri kalanı ise yığınsal bir program olan özyinelemeli bir işlevi tanımlar .

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<
                                                         Q = eval(input())
L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hb
L                                                 def y(b): return
 ?tb                                              if b[1:] (base case on false)
                                      ,0]`hb      else: [0, str([0])]
                                                  then:
           c2b                                    Cut the input in half
         yM                                       Map y over the halves
        J                                         Store that in J
    ,leh                                          The cursor position is the length 
                                                  of the body of the first function
                 .e                 J             enum-map, where k is the index
                                                  and b is the value, over J
                   .e             eb              enum-map, Y is the index and
                                                  Z is the value, over body of b
                     +W         Zk                Add to Z (line) k (the overall 
                                                  index, 0 or 1) conditional on
                          -Yhb                    Y (line index) - cursor
                       _Wk                        Negated if k
                      >       0                   > 0
               X0                    \?           Add '?' to the first element
              s                                   Concatenate, giving the body

jXF+yQ\<
    yQ      Call the above on the input
   +  \<    Append a '<'
 XF         Splat the 3 element list into the 'append-at' function,
            adding the curson in the right place
j           Join on newlines and print.

Şey ... Çözümümü düzeltmek için eve döndüm ...
Leaky Nun

3

Python 3, 352 208 205 bayt

Bu hala çok dinsiz ve daha sonra bir açıklama eklemeye çalışacağım. Bazı değişikliklerden sonra 144 147 bayt kaldırmayı başardım .

f=lambda x,l=len,r=range:'\n'.join(*x)if l(x)<2 else f([[x[i][j]+['0',''][j<=l(x[i])//2]for j in r(l(x[i]))]+[['?','?<'][l(x)<3]]+[x[i+1][j]+['1',''][j>=l(x[i])//2]for j in r(l(x[i]))]for i in r(0,l(x),2)])

Bir fonksiyon fformunun boolean bir listesi olarak doğruluk tablosu değerlerinin girdi alır ['1','1','1','0','0','1'...], '1'truthy ve '0'Falsey, ve bir Stackylogic programı döndürür.

Ideone üzerinde deneyin

Üretilen bir programı test etmek isterseniz, burada GamrCorps'un Convex yorumlayıcısını kullanabilirsiniz .

Nasıl çalışır

Bu özyinelemeli bir işlevdir ve soruda açıklanan endüktif yöntemi kullanır.

Sıfır indeksli özyineleme düzeyinde a, fonksiyon n/2 a+1listedeki -input programlarından -input Stackylogic programları oluşturur n a. Bu, listedeki iki programın tüm bitişik çiftlerini aşağıdakilerle birleştirerek yapılır ?; imleç her zaman her bir kurucu programın orta elemanında olduğundan, gerekli ekleme 0veya 1programların her satırı üzerinden yineleme yapılarak ve geçerli satırın indeksi eşit veya daha büyükse ekleme yapılabilir orta endekse eşit veya eşittir. Liste yalnızca iki program içeriyorsa, bir sonraki özyinelemeli arama son programı verir; Bu bir imleç gerektirdiğinden, bunun yerine katılma gerçekleşir ?<.

Liste uzunluğu olduğunda, liste 1tam programı içeren tek bir öğe içermelidir. Bu nedenle, programdaki tüm satırlar yeni bir satırda birleştirilir ve sonra döndürülür.

Bir örnek bunu açıklamaya yardımcı olur:

Take the input ['1', '1', '1', '0', '0', '1', '1', '1'].

Level  Return value

0  [['1', '?', '1'], ['1', '?', '0'], ['0', '?', '1'], ['1', '?', '1']]
1  [['1', '?', '10', '?', '11', '?', '0'], ['0', '?', '10', '?', '11', '?', '1']]
2  [['1', '?', '10', '?', '110', '?0', '00', '?<', '01', '?1', '101', '?', '11', '?', '1']]
3  '1\n?\n10\n?\n110\n?0\n00\n?<\n01\n?1\n101\n?\n11\n?\n1'

which when printed gives:

1
?
10
?
110
?0
00
?<
01
?1
101
?
11
?
1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.