Golunar / Unary adalah cara untuk menyandikan semua program Brainfuck yang valid , tetapi ini bukan enumerasi, karena sebagian besar bilangan alami tidak sesuai dengan program yang valid.
Untuk tujuan tantangan ini, asumsikan rekaman ganda tak terbatas dan tidak ada komentar, yaitu, program Brainfuck valid jika dan hanya jika itu hanya terdiri dari karakter <>+-.,[]
dan semua tanda kurung kiri dan kanan cocok.
Misalnya, program kosong ,[+][-].
,, [>+<[--].]
dan +[+[+][+[+]+]+]+.
merupakan program Brainfuck yang valid, sementara ][
, dan a[]
tidak.
Tugas
Tulis program atau fungsi yang menerima program Brainfuck yang valid sebagai input dan kembalikan nomor alami ( 1 , 2 , 3 , ...), dengan batasan-batasan berikut:
Output yang dihasilkan harus berbeda untuk semua program Brainfuck yang valid.
Untuk setiap bilangan alami n , harus ada program Brainfuck yang valid yang, ketika diberikan sebagai input, menghasilkan output n .
Aturan tambahan
Diberi program Brainfuck 100 atau kurang byte, program atau fungsi Anda harus selesai dalam satu menit.
Ini berarti bahwa Anda tidak dapat mengulangi semua program Brainfuck yang valid hingga Anda mencocokkan input.
Aturan standar kode-golf berlaku.
sumber
Jawaban:
Python 3,
443158155154134131128124117116115 byteBeberapa byte berkat Sp3000 dan Mitch Schwartz: D
Bagaimana ini bekerja:
Ini memetakan semua program BF yang valid ke dalam semua program BF yang mungkin, valid, atau tidak valid, yang tidak dimulai dengan
[
rasio satu banding satu. Setelah itu, program baru diubah menjadi oktal.Berikut adalah rumus pemetaannya:
[
karakter. Bagian ketiga adalah postfix terbesar yang hanya terdiri dari]
karakter. Bagian kedua adalah tengah.]
tanda kurung di bagian ketiga yang cocok dengan[
tanda kurung di bagian kedua. Ini juga dapat dihitung ulang nanti.Jika Anda tidak mengerti penjelasan ini, Anda dapat menemukan penjelasan tambahan dalam obrolan yang dimulai di sini .
Untuk referensi, berikut adalah 20 program pertama:
Berikut adalah 1000 program pertama: http://pastebin.com/qykBWhmD
Ini adalah program yang saya gunakan untuk menghasilkannya: http://ideone.com/e8oTVl
Ini adalah
Hello, World!
:sumber
Python 2, 157 byte
Masih terlihat cukup golf, tapi saya memposting ini untuk saat ini. Ini menggunakan rekursi dengan sedikit caching. Yang menjengkelkan,
D.get
tidak ada hubungan pendek untuk caching, jadi saya tidak bisa menyimpan 9 byte seperti itu ...Pemetaan memprioritaskan panjang pertama, kemudian urutan leksikografis atas pemesanan
"][><.-,+"
(lihat contoh output di bawah). Gagasan utamanya adalah membandingkan awalan.Variabel
o
melacak jumlah[
kurung masih terbuka untuk awalan saat ini, sementara variabeld
mengambil salah satu dari tiga nilai yang menunjukkan:d = 1
: Awalan saat ini secara leksikografis lebih awal daris
. Tambahkan semua program dengan awalan dan panjang ini<= s
,d = -1
: Awalan saat ini secara leksikografis lebih lambat daris
. Tambahkan semua program dengan awalan dan panjang ini< s
.d = 0
: Awalan saat ini adalah awalan daris
, jadi kami mungkin berubahd
ke 1 atau -1 nanti.Sebagai contoh, jika kita memiliki
s = "[-]"
dan awalan kita saat inip = "+"
, karenap
lebih lambat dari padas
leksikografis kita hanya tahu untuk menambahkan program yang dimulai denganp
yang lebih singkat dari itus
.Untuk memberikan contoh yang lebih rinci, anggaplah kita memiliki program input
s = "-[]"
. Ekspansi rekursif pertama melakukan ini:Perhatikan bagaimana kita sebenarnya tidak menggunakan awalan dalam rekursi - semua yang kita pedulikan adalah ditangkap melalui variabel
d
,o
dan program input menyusuts
. Anda akan melihat banyak pengulangan di atas - di sinilah caching masuk, memungkinkan kami untuk memproses program 100-ar dengan baik dalam batas waktu.Ketika
s
kosong, kita melihat(d>=0 and o==0)
, yang memutuskan apakah akan mengembalikan 1 (hitung program ini karena secara leksikografis awal / sama dan program itu valid), atau 0 (jangan hitung program ini).Setiap situasi dengan
o < 0
segera kembali0
, karena setiap program dengan awalan ini memiliki lebih]
dari[
, dan karenanya tidak valid.20 output pertama adalah:
Menggunakan contoh Hello World yang sama dengan jawaban @ TheNumberOne:
sumber
Python 2, 505 (tidak golf)
Saya menikmati mengembangkan pendekatan ini, tetapi saya mungkin tidak repot-repot bermain golf karena tidak kompetitif dibandingkan dengan pendekatan lain. Saya mempostingnya demi keberagaman dan kemungkinan minat estetika. Ini melibatkan rekursi dan sedikit matematika.
Fungsi
f(n)
menghitung jumlah program brainfuck yang valid dengan panjangn
.h(x)
program peta panjangn
untuk[0..f(n)-1]
, dang(x)
adalah fungsi peringkat bijective yang bersangkutan.Gagasan utamanya adalah bahwa program yang tidak kosong dapat memulai dengan
[
atau dengan salah satu dari 6[]
karakter yang bukan . Dalam kasus sebelumnya, kita dapat beralih pada kemungkinan lokasi pencocokan]
dan pengulangan pada bagian tertutup dan pada ekor (di mana ekor berarti substring mengikuti]
). Dalam kasus yang terakhir, kita dapat berulang pada ekor (di mana ekor berarti menjatuhkan karakter pertama). Alasan ini dapat digunakan baik untuk menghitung dan untuk peringkat komputasi.Program yang lebih pendek akan selalu memiliki peringkat lebih rendah daripada program yang lebih lama, dan pola braket adalah faktor penentu sekunder. Non-
[]
karakter diurutkan berdasarkan "+ - <> ,." (yang sewenang-wenang).Misalnya dengan
n=4
kami memiliki kasus ini:di mana
z
singkatan untuk non-[]
karakter danx
singkatan untuk karakter apa pun, di bawah batasan yang]
harus sesuai dengan inisial[
. Program diberi peringkat berdasarkan urutan itu, dan secara rekursif padax
sub - bagian, dengan bagian kiri diprioritaskan di atas bagian kanan dalam kasus-kasus terakhir. Perhitungan peringkat mirip dengan sistem angka radix campuran, danf
penting untuk menghitung "radix" saat ini.sumber
Jawaban ini adalah bukti formal untuk jawaban oleh TheNumberOne , Enumerate Brainf ** k program yang valid , di mana mungkin agak sulit untuk memahami poin-poin penting mengapa enumerasi itu benar. Tidaklah penting untuk memahami mengapa tidak ada beberapa program yang tidak valid yang memetakan ke nomor yang tidak tercakup oleh program yang valid.
Sepanjang jawaban ini, huruf kapital digunakan untuk menunjukkan program, dan variabel huruf kecil digunakan untuk fungsi dan bilangan bulat. ~ adalah operator gabungan.
Proposisi 1:
Biarkan fungsi f menjadi program yang dijelaskan dalam jawaban itu. Kemudian untuk setiap program U terdapat program V yang valid sehingga f (U) = f (V)
Definisi 1:
Misalkan g (X) adalah jumlah
[
yang muncul dalam program X, dan misalkan h (X) adalah jumlah]
yang muncul.Definisi 2:
Tentukan P (x) sebagai fungsi ini:
Definisi 3:
Diberikan program X, menyatakan X1 sebagai awalan
[
karakter terbesar, X2 pusatnya, dan X3 sufiks]
karakter terbesar.Bukti proposisi 1:
Jika g (U) = h (U) maka U adalah program yang valid, dan kita dapat mengambil V = U. (kasus sepele).
Jika g (U) <h (U) maka kita dapat membuat V dengan menambahkan
[
simbol n = h (U) - g (U) . Jelas f (V) = f (U) karena semua[
simbol di awalan dihapus.Sekarang pertimbangkan g (U)> h (U). Tentukan T = U2 ~ U3. jika g (T) <= h (T), maka kita dapat membuat V dengan menghapus
[
simbol n = g (U) - h (U) .Jadi kita dapat mengasumsikan bahwa h (T) <g (T). Bangun V = T ~ P (g (T) - h (T)).
Kami membutuhkan tiga fakta kecil untuk melanjutkan:
Klaim 1: g (U2) = g (T)
U3 tidak mengandung
[
simbol apa pun menurut definisinya. Sebagai T = U2 ~ U3,[
simbol - simbolnya semuanya ada di bagian pertama.Klaim 2: h (U3) <g (T)
Ini mengikuti dari mencatat bahwa h (T) <g (T) dan h (U3) <h (U3 ~ U2) = h (T).
Klaim 3: h (V3) = g (U2) - h (U2)
Sekarang kita tunjukkan bahwa f (V) = f (U).
Ini melengkapi buktinya. QED
Ayo lakukan keunikan juga.
Proposisi 2:
Biarkan U, V menjadi dua program yang berbeda dan valid. Kemudian f (U)! = F (V)
Ini cukup mudah dibandingkan dengan proposisi sebelumnya.
Mari kita asumsikan bahwa U2 = V2. Tetapi kemudian satu-satunya cara U dan V dapat berbeda adalah dengan menambahkan atau menghapus n
[
dan]
simbol masing-masing ke U1 dan U3. Namun ini mengubah output dari f, karena f akan menghitung jumlah]
simbol yang tidak cocok dalam sufiks.Jadi U2! = V2.
Jelas, ini mengarah pada kontradiksi. Karena U2 dan V2 secara harfiah terkandung dalam output dari f (U) dan f (V) masing-masing, mereka tidak dapat berbeda, kecuali di 'tepi', tempat di mana U2 digabungkan dengan U3. Tetapi simbol pertama dan terakhir dari U2 dan V2 tidak dapat
[
atau]
menurut definisi, sementara itu adalah satu-satunya simbol yang diperbolehkan masing-masing dalam U1, U3, V1, V3 dan masing-masing lagi. Jadi kita mendapatkan U2 = V2. QEDsumber