Tulis Kolmogorov Complexity Solver

16

The kompleksitas Kolmogorov dari string S adalah panjang dari program terpendek P , ditulis dalam beberapa bahasa pemrograman L , yang output persis S .
(Ya, definisi sebenarnya lebih formal tetapi ini sudah cukup untuk tantangan.)

Tugas Anda dalam tantangan ini adalah untuk menulis sesingkat mungkin "Kolmogorov kompleksitas solver", yaitu sebuah program yang ditulis dalam L sendiri yang mengambil dalam string S dan kembali terpendek P ditulis dalam L yang output S .

Pendekatan naif untuk ini adalah untuk mengulangi semua program 1 panjang, lalu semua program 2 panjang, lalu semua program 3 panjang, dan seterusnya, menjalankan masing-masing dan mengukur output sampai sebuah program yang menghasilkan S ditemukan. Masalah dengan pendekatan ini adalah bahwa beberapa dari program ini mungkin tidak pernah berhenti berjalan, yang berarti bahwa pemecah itu sendiri mungkin tidak pernah berhenti. Dan karena masalah penghentian tidak ada cara pasti untuk menghindari program yang tidak berhenti.

Solusi sederhana, meskipun tidak sempurna adalah dengan menetapkan batas waktu pada waktu eksekusi masing-masing P potensial . Program yang tidak berhenti pada waktunya dapat dilewati, tetapi pemecah pasti akan berhenti (dengan asumsi bahwa suatu program dalam L memang dapat menghasilkan S dalam batas waktu).

Tantangan

Tuliskan solver Anda sebagai program atau fungsi yang mencakup tiga hal:

  • String S .
  • T bilangan bulat positif yang merupakan batas waktu dalam detik atau rentang waktu yang lebih kecil (misalnya milidetik).
  • Sebuah string A dari abjad karakter untuk digunakan untuk potensi P 's.

Dan output terpendek P yang hanya berisi karakter dalam A , berjalan dalam waktu kurang dari T unit waktu, dan output S .

Ini adalah pseudocode umum:

Function KolmogorovComplexitySolver(S, T, A):
    Assign N to 0
    Loop until function returns:
        In any order, iterate over all strings of length N that only contain characters from *A*. Call the current string P:
            Execute P, saving the output to O, stopping the execution if it takes longer than time T
            If (P did not throw any errors) and (P did not timeout) and (O and S are identical):
                Return P
        Add 1 to N

Detail

  • Anda mungkin berasumsi bahwa akan selalu ada sebuah P terbuat dari karakter dalam A yang berjalan dalam waktu T yang output S .
  • Anda dapat mengasumsikan bahwa eksekusi P potensial tidak akan memiliki efek samping yang mencegah solver berjalan atau bekerja dengan benar (seperti mengacaukan memori yang dialokasikan solver).
  • Anda tidak boleh berasumsi bahwa potensi P bebas dari kesalahan. Pastikan untuk menyertakan try/ catchmemblokir atau apa pun yang berlaku di sekitar panggilan eksekusi.
  • Jika ada beberapa P terpendek , maka semua sudah cukup. "Shortness" diukur dalam karakter bukan byte.
  • Output dari P potensial adalah apa yang dicetak ke stdout (atau area output biasa bahasa Anda). String kosong adalah P potensial .
  • Idealnya, solver Anda akan memungkinkan A mengandung karakter apa pun. Sebuah keharusan setidaknya untuk bisa mengandung ASCII printable karakter ditambah tab dan baris baru.
  • Input dapat berasal dari argumen file / stdin / command line / function. Output menuju stdout atau serupa, atau dapat dikembalikan sebagai string jika Anda menulis suatu fungsi.

Mencetak gol

Kiriman dengan byte paling sedikit menang. Tiebreaker pergi ke kiriman diposting paling awal.

Hobi Calvin
sumber
7
Otakku sakit.
Alex A.
1
Bisakah Anda mengendurkan persyaratan bahwa bahasa target dan bahasa yang digunakan oleh pemecah meta harus sama?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Dan bukankah mungkin untuk hanya menulis sebuah program yang mengubah output menjadi representasi literal dari bahasa?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Tidak, intinya adalah melakukannya dalam bahasa yang sama. Ya, tapi itu tidak selalu menjadi program terpendek.
Calvin Hobi
@ Calvin'sHobbies: Jadi pada akhirnya, itu hanya tantangan kode golf untuk mengetahui bahasa mana yang dapat dengan mudah menulis kode untuk memanggil fasilitas (atau mengimplementasikan kompiler jika tidak ada) untuk mengkompilasi bahasa itu sendiri?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Jawaban:

11

Python 3, 240 236 byte

import subprocess as s,itertools as i
def f(S,T,A,N=0):
 while 1:
  for P in i.product(A,repeat=N):
   try:
    P="".join(P);open("a","w").write(P)
    if s.check_output(["py","-3","a"],timeout=T).decode()==S:return P
   except:1
  N+=1

Jangan jalankan ini. Di komputer saya, setidaknya, saya menemukan program sangat sulit untuk berhenti setelah mulai berjalan karena jendela pop-up yang dibuat per proses.

timeouts hanya ditambahkan ke subprocess.check_outputdalam Python 3, itulah sebabnya kami menggunakan ini daripada Python 2.

Berikut ini adalah versi alternatif dengan time.sleepyang juga mencetak semua program yang valid yang ditemukan di sepanjang jalan, serta output yang sesuai:

import subprocess as s,itertools as i
import time
def f(S,T,A,N=0):
 while 1:
  for P in i.product(A,repeat=N):
   time.sleep(0.2)
   try:
    P="".join(P);open("a","w").write(P);C=s.check_output(["py","-3","a"],timeout=T).decode()
    print(P,repr(C))
    if C==S:return P
   except:1
  N+=1

Program menggunakan nama file auntuk setiap program yang Pakan diuji, jadi jika Anda menjalankan ini pastikan Anda belum memiliki file dengan nama itu. Ganti ["py","-3","a"]dengan perintah yang sesuai untuk pengaturan Anda (misalnya ["python","a"]atau ["python3","a"]).

Jangan ragu untuk mengubah sleepdurasi dengan risiko Anda sendiri :). Sebut seperti f("1\r\n",1,"1()print"), di mana Tbatas waktu dalam detik.

Beberapa baris pertama output dari tester dengan panggilan di atas:

 ''
1 ''
11 ''
() ''
111 ''
(1) ''
int ''
1111 ''

(Jika Anda ingin sedikit membantu program ini, Anda dapat mengubahnya P="".join(P)ke P="print"+"".join(P))

Karena semua program di atas tidak memiliki output, inilah hasilnya untuk f("1\r\n",1,["print","(",")","1"])(token bukan bagian dari tantangan, tapi saya ingin menunjukkan apa yang terjadi):

 ''
print ''
1 ''
() ''
11 ''
print() '\r\n'
(print) ''
(1) ''
111 ''
print(print) '<built-in function print>\r\n'
print(1) '1\r\n'

Nilai kembali adalah string 'print(1)'.

Akhirnya, hanya untuk bersenang-senang, inilah yang terjadi jika alfabetnya string.printable, yaitu

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c

Tautan pastebin dari semua program 0-2 char Python 3 yang valid

Sp3000
sumber